[Merge]Merge lp:openobject-server

bzr revid: vja@tinyerp.com-20121218052112-13xced5nfv7qncyq
This commit is contained in:
Vishmita 2012-12-18 10:51:12 +05:30
commit b652d6bc66
98 changed files with 23627 additions and 2480 deletions

1
debian/control vendored
View File

@ -19,6 +19,7 @@ Depends:
python-docutils,
python-feedparser,
python-gdata,
python-jinja2,
python-ldap,
python-libxslt1,
python-lxml,

View File

@ -135,6 +135,9 @@ The view describes how the edition form or the data tree/list appear on screen.
A form can be called by an action opening in 'Tree' mode. The form view is generally opened from the list mode (like if the user pushes on 'switch view').
.. _domain:
.. _domains:
The domain
----------

View File

@ -141,10 +141,6 @@ for users who do not belong to the authorized groups:
.. note:: The tests related to this feature are in ``openerp/tests/test_acl.py``.
.. warning:: At the time of writing the implementation of this feature is partial
and does not yet restrict read/write RPC access to the field.
The corresponding test is written already but currently disabled.
Workflow transition rules
+++++++++++++++++++++++++

View File

@ -76,9 +76,9 @@ This phase also generates the ``rows`` indexes for any
Conversion
++++++++++
This second phase takes the record dicts, extracts the :ref:`dbid` and
:ref:`xid` if present and attempts to convert each field to a type
matching what OpenERP expects to write.
This second phase takes the record dicts, extracts the :term:`database
ID` and :term:`external ID` if present and attempts to convert each
field to a type matching what OpenERP expects to write.
* Empty fields (empty strings) are replaced with the ``False`` value
@ -141,14 +141,14 @@ If ``name_search`` finds no value, an error is generated. If
``name_search`` finds multiple value, a warning is generated to warn
the user of ``name_search`` collisions.
If the specified field is a :ref:`xid` (``m2o/id``), the
If the specified field is a :term:`external ID` (``m2o/id``), the
corresponding record it looked up in the database and used as the
field's value. If no record is found matching the provided external
ID, an error is generated.
If the specified field is a :ref:`dbid` (``m2o/.id``), the process is
the same as for external ids (on database identifiers instead of
external ones).
If the specified field is a :term:`database ID` (``m2o/.id``), the
process is the same as for external ids (on database identifiers
instead of external ones).
Many to Many field
~~~~~~~~~~~~~~~~~~
@ -161,11 +161,11 @@ One to Many field
~~~~~~~~~~~~~~~~~
For each o2m record extracted, if the record has a ``name``,
:ref:`xid` or :ref:`dbid` the :ref:`dbid` is looked up and checked
through the same process as for m2o fields.
:term:`external ID` or :term:`database ID` the :term:`database ID` is
looked up and checked through the same process as for m2o fields.
If a :ref:`dbid` was found, a LINK_TO command is emmitted, followed by
an UPDATE with the non-db values for the relational field.
If a :term:`database ID` was found, a LINK_TO command is emmitted,
followed by an UPDATE with the non-db values for the relational field.
Otherwise a CREATE command is emmitted.

View File

@ -27,5 +27,15 @@ OpenERP Server API
api_core.rst
api_models.rst
Concepts
''''''''
.. glossary::
Database ID
The primary key of a record in a PostgreSQL table (or a
virtual version thereof), usually varies from one database to
the next.
External ID

View File

@ -3,7 +3,7 @@
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
# Copyright (C) 2010 OpenERP s.a. (<http://openerp.com>).
# Copyright (C) 2010, 2012 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
@ -85,7 +85,6 @@ The kernel of OpenERP, needed for all installation.
'res/ir_property_view.xml',
'security/base_security.xml',
'security/ir.model.access.csv',
'security/ir.model.access-1.csv', # res.partner.address is deprecated; it is still there for backward compability only and will be removed in next version
],
'demo': [
'base_demo.xml',

View File

@ -149,7 +149,6 @@ CREATE TABLE res_users (
active boolean default True,
login varchar(64) NOT NULL UNIQUE,
password varchar(64) default null,
lang varchar(64) default '',
-- No FK references below, will be added later by ORM
-- (when the destination rows exist)
company_id int,
@ -316,13 +315,29 @@ CREATE TABLE ir_module_module_dependency (
primary key(id)
);
CREATE TABLE res_company (
CREATE TABLE res_partner (
id serial NOT NULL,
name character varying(64) not null,
parent_id integer references res_company on delete set null,
name character varying(128),
lang varchar(64),
company_id int,
primary key(id)
);
CREATE TABLE res_currency (
id serial PRIMARY KEY,
name VARCHAR(32) NOT NULL
);
CREATE TABLE res_company (
id serial PRIMARY KEY,
name character varying(128) not null,
parent_id integer references res_company on delete set null,
partner_id integer not null references res_partner,
currency_id integer not null references res_currency
);
CREATE TABLE res_lang (
id serial PRIMARY KEY,
name VARCHAR(64) NOT NULL UNIQUE,
@ -375,16 +390,24 @@ CREATE TABLE ir_model_relation (
module integer NOT NULL references ir_module_module on delete restrict,
model integer NOT NULL references ir_model on delete restrict,
name character varying(128) NOT NULL
);
);
---------------------------------
-- Users
---------------------------------
insert into res_users (id,login,password,active,company_id,partner_id) VALUES (1,'admin','admin',true,1,1);
insert into ir_model_data (name,module,model,noupdate,res_id) VALUES ('user_root','base','res.users',true,1);
insert into res_users (id,login,password,active,company_id,partner_id,lang) values (1,'admin','admin',True,1,1,'en_US');
insert into ir_model_data (name,module,model,noupdate,res_id) values ('user_root','base','res.users',True,1);
insert into res_partner (id, name, lang, company_id) VALUES (1, 'Your Company', 'en_US', 1);
insert into ir_model_data (name,module,model,noupdate,res_id) VALUES ('main_partner','base','res.partner',true,1);
-- Compatibility purpose, to remove V6.0
insert into ir_model_data (name,module,model,noupdate,res_id) values ('user_admin','base','res.users',True,1);
insert into res_currency (id, name) VALUES (1, 'EUR');
insert into ir_model_data (name,module,model,noupdate,res_id) VALUES ('EUR','base','res.currency',true,1);
insert into res_company (id, name, partner_id, currency_id) VALUES (1, 'Your Company', 1, 1);
insert into ir_model_data (name,module,model,noupdate,res_id) VALUES ('main_company','base','res.company',true,1);
select setval('res_company_id_seq', 2);
select setval('res_users_id_seq', 2);
select setval('res_partner_id_seq', 2);
select setval('res_currency_id_seq', 2);

View File

@ -32,6 +32,7 @@
<record id="main_partner" model="res.partner" context="{'default_is_company': True}">
<field name="name">Your Company</field>
<field name="company_id" eval="None"/>
<field name="image" eval="False"/>
<field name="customer" eval="False"/>
<field name="is_company" eval="True"/>
<field name="street"></field>

View File

@ -7,6 +7,74 @@
<field name="customer" eval="False"/>
<field name="email">demo@example.com</field>
</record>
<record id="main_partner" model="res.partner">
<field name="image">iVBORw0KGgoAAAANSUhEUgAAALQAAAAuCAYAAACBMDMXAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A
/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sDCAo7GWN31l0AAA1fSURBVHja
7Zx5dFXFHcc/eQk7KBiUTVGRRezA8ahYamgRFbWAcmyPe+uGSrW1FrFqF9u61bZWm1Kx1lgVpHVp
3ShVVBTcBYSyDHHBulEUhVRBRJJA0j/m95rJZOa++zYS2vs95xLevLkzc+d+72++v99v7oMECRIk
SJAgQYIECRIkSJAgQYIECQqB9skUFA4luZ6ooRzoA/QGPgWqlfn7/4aBwJHAEUA/oANwA3C/Vaen
/N3gnPs14ErgaGB9QscdSGgNewHj5TgC6Oyp9h6wylTnUQULdsI52U2Oj4GaiHoVwC3AcM93a4DB
QHfgAeAwoBFYAVwjZe2AamA/ma8jA6SeAowDtgH18neb9Rmg1DrK5Ggn1r+dlH8ObAE+A24D5su5
/YCZVtvu30an/XQf7eXYJNe7BlhMvHs+DPhNRJ8pGbd9Lem/24C10t/bMpebsrHEAzXco6FBQ6Mc
72qYoeEaDZdoqNKwSMMWq06jhuc1jNxJiHww8ILcwEaZuHnANz0P/qFAg1XXd9wKvB/4bgZwvnxf
AawTsu/uGddlwKtCxsYCHZOs9vsBS4APCtT2QuCYGIReBnxUgP4+Aa4DukRaaG2Wzl8D35KnA7Eo
l4v1bfCcs4c87fYF1QMXK/h9GybzaOBpsQw+PAucC6yWzw8CJ+TZZwPwE7kZ+wBzgVpZ/WoCq+kM
ecBcrBDS18pRJ39LgF5yfBHoKvUnAH/3tHMg8A9P+RZgmvRRAwwAFHAG0NFTf5vM6Ysx5uFY4DFP
+QYxCq8DG4Eh0uaEQDuzAnNjiKnhRcfaPqShWwyLXqLhaufcRg3faKNk3gV4N4Yl+Fz0bgdgeYz6
f5KlfVtEnanWOMqFMEuBHoGxTgq0c3FMKfWW1D84ot7HnvbXBOr2F0PgG9O/gE4xxtUhcP7iQP3j
ga2Bc071EXKASAqbjPN12Hr52ijV8KbTxgbtX1JbGzOyXOLWigXMVCf98A8RvfhhoF6ZNZZ9RH4s
Bnb1jHVCHoQGeFzq94uo81oWhEZkUkg6fCnmuD7JgtCI0+3r7+6UQ8TOwEPy5KWxHjjdJzFCULAd
+IVTXA5UtjEydw8uU2HUyTLow/sit74rcqKv1J0iJJoo0Y8tUr8vcJR1/jtC2qHyoLnINxKyVm78
RxF1su1jfcR9PTiLNrLBTYHy4a7VvcPjtV+vzI3KFjNFx9k4TRuHqq1gRIZIT4M4TDeKZu4D7CtO
zUjReD8SP2M8cJI4jA8A35eyPpaunA2cjPE1TgWeEX1o4xXgFOA44ETnu9o8r3eatFkfUSeXPpYH
yrvFPD/bPj/AHyIuL7Os8wSZbByHblYuM6egTpsw3iAPiRa1EULv7SHwCglpLRBn8BPPeZ2B74im
rXO+SwFnAXfJ3E0HrnCs4mfAvcB9gXHNEX29scDXu0yOQmNdlkQvBNYAB7j92frtp76JVfktc+94
CD00jmMp9d5ULQnj1h0EbFXROi+EOw+Exy6FASWwsRLeWGwcjkiUwujr4Y5x0Khafv2cRBNKgc+v
g6pnYfDj/mW+MaKbtibPouDTyltltSkWenrKlpZZ1vkQT4U78uz0XU/Z/hHkbC9L9cXibMwEzvTU
GwX8QEJR5VI2WZmoQhyntauE4c6Wp7wM4E7zUFyojIWMM747gXM89Z4GLpIQZ++JUHsjjFHwUisR
bprM0+lFav9wT9k1GbR6Pugmss3FC2kLfWZgGZmbZ8c+bTQ0QJZREuayv+/qIeL1wLc92ncSGQit
Tabph8D3MIH4hRJ9SHv9ewH3aRimTIgr0/jae/oYIpJhoBOaGkfrEfqrGXRzPhiGSd03I5ZEIoqF
SZ6yB4C5KW2s01hfBWUcmXzQ31NW5hAgpY1jtcBD9lVWvaHAStGuPhkyTJtlPkTmgZhA/8/EcgxR
8GXR0fc7+nhCzPEtcvoYLaQd6BnCm61E5nJgT2JIqRywPyabajt/DwqfivUA7Ss+iRu9OT9NrsPw
xzzfKEDn/QMeapoAe4jjNFb6G+wjtDb7HeYBm2WJv18mzrYMnYRIr3vIPAIjA7piQopHK5FDCrZr
uFsiFM30mTO+1R5/YKHVxxlAlTgr9Z4lcVkRSXuO3Mc6uT77OoZhsnm1Beqri0RuTpSVLn2dS0Rm
zM7gG2SLMZjsZAlmm8BVjn5+DRN6/Xea0KG9Fu8VIYrQjNDypJViUq4rMOnO3azvq7WRA08Joc9O
x8M1POFZ6uo9ZO4LPGzJl4dVS23fxflcHRhfDU1ZvLo0SbWJOU/FkPovMsF3We3VWW0WA8Pxb5LC
GUO+eASTqXOxUqJXjUW4tmnG7njl7M8x+Y46e/nvlYVDFxuSJu8eiHzYkZXNymQSu9A85VsvVnu2
jOU8J7nzsaftDZ6yKgyp0/idp44tudbT5BTa49vFGd8yBbXaWKpLxOovtOSNjZdV8ZZggEdlBdps
WeISWfEmilRqV4B+7gkQepgs+X8owrVdIM57bwljLpdjCZ4IXFnAW8yb0AG5AcayIsu9HRwf7Dh6
K4DTRDON9ITvXD1bp5xthLLl9VjbkiiTzLDrfEUmDEwGb7IyxHDH58Y8F2mjTacBxyhLfnjCWPOK
rJOfAH4b+G6WWNCOBejnXrknx3m+uwGzyei9Al/b83LEQgr//orNSjRJHjgksOw9GeFguJLnWmB8
YCwHxHC6zqL5HpQqh8xjxTtOiV4foUzq3wfl8eTvBipVcy2domU2tNiEjsIqTKa3QwEt5qZAKK2K
VkYqECssxFN2lqdsftr6xSD0OGCmatqymSn896RD1hLL8v63/3RoTcPNEpbsJuG4Q1W0zrUJvV10
dZknPKUcr/9Tojfa7AgspHBvxKzF7NH24Wg8cfkdTehXPeWleernAZgQlm9ZCmGI83kL8MtA+50x
O9O8UkYwWuSK7USM1Sb8ls7mnQj0VEZmbMlwWV+wVzDx8M/3bNpy5caCAoQ/88XX8Sc/csVtONLN
wk1E7+YrKsoChO5fAOtc4rHOT0Wc40qI6cq/jwJMksNuf6Nngke4MkrCTT8GXlLNw1uZHtAUcJBV
tKtES3xzV+F8for/PTQC54mf42rzXcU5nNBaFtq3zHbKde+y3Hw389iASVVHRURcQs+O6MaVEtOU
2fBjw400PK3gMgXPZ0NmwaE0DycSWj0w8eC2op996IlxlvPFakySyofxmBBmqxD6nwGRPyiP5c21
8Jc5UQAXIx2Z8yGBjS3ahM5OcCxvZYzx1+QxT+Ocz0sVvOwZWy9MEiiNTcrKdrYRzCHeq1FxcCPm
DRsfKmnaOrvjCC3Wymc9L8rBOvel5buDdylz4VEY5Xyeq8JB+tMcj/3SQBRkkOfhzTT+kpiEnh+o
V+GJMLQldMVsuo96uDvGLAPjG0zC7yP0IP57pL72O+VEaPl7Ky0tzkk6xlZPiwydMO/RlVvF9wGT
Y5zuEuHZiLq2F12pPMF8IWafDKR0zxkLLNWOsylW9yCn+nMx5YaWf8o0XKmbz00uKMnz/FHiN9Vk
kCQudoswCMsinP2JYoDiyCAXvXImtHjq59E8m5XC/DzBHjHI3AsTPTjcchquAk6NsZ+5FLMN1MaL
gbqThVwNmJTnVF89se5vO8V76pYrARqGaxO+e0wcSzfbeKxDpEbCgX73wewtLwdrebB750nIXM/v
iElcnRJDfvUM8KRHxDlXE977c7MTIXLRDv9eonJyiLaVWSTQ2ujf6ZbTUAEs18bJe9KVAaJnz8W8
M5e2iK+KZp4TcwwH4mwTBa7ScJOVSu6CeWVpOmZb5xnKJDai8JzHMZyrTcjpbem3Qm7048DwQBza
tezVykMIbUjjWvLj5JgBTFH+dH02ODlQfqlYwjrrqBcrtzfGKJVE+BPt5f6N9ji/aVyAyRSuxbwB
b2Or8OAZzyrSQxzjKcDfaHLeO2Ik6vERq9GFovk/JHNY1b+ECXmuxOxPsPP/myRMsxITlRiE2RDT
yfJ6rwVmZfNCrTYvlIbStpsxKfj9ZAKqgEsikjN2u70lghNlWaqBqSqw71u21q6n+Z6UW5W5uW7d
AzyaeQ0mVp3vvvI9MSns0QXS0tdhwpfI3Ga7tXU8Zv+Ii1vwzI2F20UJVJBFOltwWxz5WuZZrj8D
rtDGqpyE0dFDxZKNshy4GiH4HGC2Mv/PVdfZqBWLUYJJoJQCfwX+rPw/SEJAdqzTxgGqFNnQXuTC
aszGlnnAjAwhvH3lvGWy8lRjUuU+pH9T4yB56B8BflWg3/vrLku6pumHZNI/pZD+2az0z365Rz1N
P0CTPh622v4U+KPUSx91lvz0tbk2MM7LZTz1YsW3Csc6ypGOdH1k9Vnn9G33WWb9/6WcLHSExUth
HKZtwDpVmO2IaDM5fZ3oyu0iez6IY41j9FEqS+8Glc3voGXfTwrYXZklMkEroKQ1O9fGAr7lRgpa
8d27BDs5Uq3cvxsV2E5x3+xIkBC6qHD18yrV0oNOkGCntdBLkluSYKcktGTN3ID7K8ktSbCzWugx
Hqc0IXSCnZbQRzqf68k9lp0gQasT+iiPQ7g1uSUJ8kFZK+nn/ph9Fo2Y1PZKmv96UYIEOeE/+J4k
BZrmED0AAAAASUVORK5CYII=
</field>
</record>
<record id="user_demo" model="res.users">
<field name="partner_id" ref="base.partner_demo"/>
<field name="login">demo</field>
@ -14,7 +82,7 @@
<field name="signature">--
Mr Demo</field>
<field name="company_id" ref="main_company"/>
<field name="groups_id" eval="[(6,0,[ref('base.group_user')])]"/>
<field name="groups_id" eval="[(6,0,[ref('base.group_user'), ref('base.group_partner_manager')])]"/>
<field name="image">/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEP
ERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4e
Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCACEAIQDASIA

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-12-10 22:51+0000\n"
"PO-Revision-Date: 2012-12-16 11:26+0000\n"
"Last-Translator: Felix Schubert <Unknown>\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: 2012-12-12 04:37+0000\n"
"X-Generator: Launchpad (build 16361)\n"
"X-Launchpad-Export-Date: 2012-12-17 04:43+0000\n"
"X-Generator: Launchpad (build 16372)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@ -1087,7 +1087,7 @@ msgstr "Gemeinsame Verzeichnisse (WebDav)"
#. module: base
#: view:res.users:0
msgid "Email Preferences"
msgstr "EMail Optionen"
msgstr "E-Mail Einstellungen"
#. module: base
#: code:addons/base/ir/ir_fields.py:196
@ -2878,7 +2878,7 @@ msgstr "Meine Filter"
#. module: base
#: field:ir.actions.server,email:0
msgid "Email Address"
msgstr "Email Addresse"
msgstr "E-Mail-Adresse"
#. module: base
#: model:ir.module.module,description:base.module_google_docs
@ -3842,7 +3842,7 @@ msgstr "Datenbankstruktur"
#. module: base
#: model:ir.actions.act_window,name:base.action_partner_mass_mail
msgid "Mass Mailing"
msgstr "EMail senden"
msgstr "Massen Mailing"
#. module: base
#: model:res.country,name:base.yt
@ -4185,7 +4185,7 @@ msgstr "Montenegro"
#. module: base
#: model:ir.module.module,shortdesc:base.module_fetchmail
msgid "Email Gateway"
msgstr "Email Gateway"
msgstr "E-Mail Gateway"
#. module: base
#: code:addons/base/ir/ir_mail_server.py:466
@ -4969,8 +4969,8 @@ msgid ""
"the same values as those available in the condition field, e.g. `Dear [[ "
"object.partner_id.name ]]`"
msgstr ""
"EMail Inhalt, der auch Python Ausdrücke in doppelten Klammern enthalten "
"kann, ähnlich wie ein Konditionenfeld, z.B. `Geehrte(r) [[ "
"E-Mail Inhalt, der auch Python Ausdrücke in doppelten Klammern enthalten "
"kann, ähnlich wie ein Bedingungsfeld, z.B. `Sehr Geehrte(r) [[ "
"object.partner_id.name ]]`"
#. module: base
@ -6621,7 +6621,7 @@ msgstr "Aktion"
#. module: base
#: view:ir.actions.server:0
msgid "Email Configuration"
msgstr "Email Konfiguration"
msgstr "E-Mail Konfiguration"
#. module: base
#: model:ir.model,name:base.model_ir_cron
@ -8149,9 +8149,9 @@ msgid ""
"the same values as those available in the condition field, e.g. `Hello [[ "
"object.partner_id.name ]]`"
msgstr ""
"EMail Betreff, kann Ausdrücke in Doppelklammern wie ein Konditionen Feld "
"E-Mail Betreff, kann Ausdrücke in Doppelklammern, wie ein Bedingungsfeld "
"enthalten. \r\n"
"zB `Hello [[ object.partner_id.name ]]`"
"z.B. `Hallo [[ object.partner_id.name ]]`"
#. module: base
#: help:res.partner,image:0
@ -9846,9 +9846,9 @@ msgid ""
"same values as for the condition field.\n"
"Example: object.invoice_address_id.email, or 'me@example.com'"
msgstr ""
"Ausdruck, der die EMail Adresse des Empfängers ermittelt. Ähnlich "
"Konditionen Feld.\n"
"zB object.invoice_address_id.email, or 'me@example.com'"
"Ausdruck, der die E-Mail Adresse des Empfängers zurückgibt. Ähnlich einem "
"Bedingungsfeld.\n"
"z.B.. object.invoice_address_id.email, oder 'me@example.com'"
#. module: base
#: model:ir.module.module,description:base.module_project_issue_sheet
@ -11018,7 +11018,7 @@ msgstr "Laos"
#: field:res.partner.address,email:0
#, python-format
msgid "Email"
msgstr "EMail"
msgstr "E-Mail Adresse"
#. module: base
#: model:res.partner.category,name:base.res_partner_category_12
@ -11848,17 +11848,17 @@ msgid ""
msgstr ""
"\n"
"Dieses Modul wird für das Thunderbird-Plugin benötig, damit dieses "
"funktionieren kann.\n"
"eingesetzt werden kann.\n"
"========================================================================\n"
"\n"
"Das Plugin erlaubt Ihnen die Archivierung von EMail mitsamt Anhängen in "
"Das Plugin erlaubt Ihnen die Archivierung von E-Mails inklusive Anhängen in "
"OpenERP-Objekten.\n"
"Sie können einen Partner, einer Aufgabe, ein Projekt, ein analytisches Konto "
"oder ein beliebiges \n"
"anderes Objekt in OpenERP auswählen und die gewünschte EMail als .eml-Datei "
"anderes Objekt in OpenERP auswählen und die gewünschte E-Mail als .eml-Datei "
"dem Objekt als\n"
"Anhang anfügen. Sie können aus der EMail neue Dokumente, in den Bereichen "
"Kunden-Leads,\n"
"Anhang anfügen. Sie können aus der E-Mail neue Dokumente, in den Bereichen "
"Leads,\n"
"Personal-Bewerber und Projekt-Problembearbeitung, anlegen.\n"
" "

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-08-20 15:47+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"PO-Revision-Date: 2012-12-17 20:41+0000\n"
"Last-Translator: David Bowers <sales@skitzotek.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: 2012-12-04 05:02+0000\n"
"X-Generator: Launchpad (build 16335)\n"
"X-Launchpad-Export-Date: 2012-12-18 04:58+0000\n"
"X-Generator: Launchpad (build 16372)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@ -48,7 +48,7 @@ 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 ""
"The second argument of the many2many field %s must be a SQL table !You used "
"The second argument of the many2many field %s must be a SQL table! You used "
"%s, which is not a valid SQL table name."
#. module: base
@ -101,7 +101,7 @@ msgstr ""
msgid ""
"Model name on which the method to be called is located, e.g. 'res.partner'."
msgstr ""
"Model name on which the method to be called is located, e.g. 'res.partner'."
"Model name in which the method to be called is located, e.g. 'res.partner'."
#. module: base
#: view:ir.module.module:0
@ -123,6 +123,17 @@ msgid ""
" * Product Attributes\n"
" "
msgstr ""
"\n"
"A module which adds manufacturers and attributes to the product form.\n"
"=====================================================================\n"
"\n"
"You can now define the following for a product:\n"
"-----------------------------------------------\n"
" * Manufacturer\n"
" * Manufacturer Product Name\n"
" * Manufacturer Product Code\n"
" * Product Attributes\n"
" "
#. module: base
#: field:ir.actions.client,params:0
@ -226,6 +237,35 @@ msgid ""
"* Planned Revenue by Stage and User (graph)\n"
"* Opportunities by Stage (graph)\n"
msgstr ""
"\n"
"The generic OpenERP Customer Relationship Management\n"
"=====================================================\n"
"\n"
"This application enables a group of people to intelligently and efficiently "
"manage leads, opportunities, meetings and phone calls.\n"
"\n"
"It manages key tasks such as communication, identification, prioritization, "
"assignment, resolution and notification.\n"
"\n"
"OpenERP ensures that all cases are successfully tracked by users, customers "
"and suppliers. It can automatically send reminders, escalate a request, "
"trigger specific methods and many other actions based on your own enterprise "
"rules.\n"
"\n"
"The greatest thing about this system is that users don't need to do anything "
"special. The CRM module has an email gateway for the synchronization "
"interface between mails and OpenERP. That way, users can just send emails to "
"the request tracker.\n"
"\n"
"OpenERP will take care of thanking them for their message, automatically "
"routing it to the appropriate staff and make sure all future correspondence "
"gets to the right place.\n"
"\n"
"\n"
"Dashboard for CRM will include:\n"
"-------------------------------\n"
"* Planned Revenue by Stage and User (graph)\n"
"* Opportunities by Stage (graph)\n"
#. module: base
#: code:addons/base/ir/ir_model.py:397
@ -235,7 +275,7 @@ msgid ""
"them through Python code, preferably through a custom addon!"
msgstr ""
"Properties of base fields cannot be altered in this manner! Please modify "
"them through Python code, preferably through a custom addon!"
"them through Python code, preferably by a custom addon!"
#. module: base
#: code:addons/osv.py:130
@ -318,6 +358,7 @@ msgid ""
"The internal user that is in charge of communicating with this contact if "
"any."
msgstr ""
"The internal user who is in charge of communicating with this contact if any."
#. module: base
#: view:res.partner:0
@ -625,6 +666,19 @@ msgid ""
"* Use emails to automatically confirm and send acknowledgements for any "
"event registration\n"
msgstr ""
"\n"
"Organization and management of Events.\n"
"======================================\n"
"\n"
"The event module allows you to efficiently organise events and all related "
"tasks: planning, registration tracking,\n"
"attendance, etc.\n"
"\n"
"Key Features\n"
"------------\n"
"* Manage your Events and Registrations\n"
"* Use emails to automatically confirm and send acknowledgements for any "
"event registration\n"
#. module: base
#: selection:base.language.install,lang:0
@ -860,7 +914,7 @@ msgstr "Eritrea"
#. module: base
#: sql_constraint:res.company:0
msgid "The company name must be unique !"
msgstr "The company name must be unique !"
msgstr "The company name must be unique!"
#. module: base
#: model:ir.ui.menu,name:base.menu_base_action_rule_admin
@ -884,6 +938,9 @@ msgid ""
"image, with aspect ratio preserved. Use this field anywhere a small image is "
"required."
msgstr ""
"Small-sized image of this contact. It is automatically resized to 64x64 "
"pixels with the aspect ratio preserved. Use this field anywhere a small "
"image is required."
#. module: base
#: help:ir.actions.server,mobile:0
@ -892,7 +949,7 @@ msgid ""
"invoice, then `object.invoice_address_id.mobile` is the field which gives "
"the correct mobile number"
msgstr ""
"Provides fields that be used to fetch the mobile number, e.g. you select the "
"Provides fields 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"
@ -988,8 +1045,6 @@ 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 ""
"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."
#. module: base
#: help:ir.actions.report.xml,report_type:0
@ -1089,6 +1144,13 @@ msgid ""
"actions(Sign in/Sign out) performed by them.\n"
" "
msgstr ""
"\n"
"This module aims to manage employees' attendances.\n"
"==================================================\n"
"\n"
"Keeps account of the attendances of employees based on the\n"
"actions (Sign in/Sign out) performed by them.\n"
" "
#. module: base
#: model:res.country,name:base.nu
@ -1148,7 +1210,7 @@ msgid ""
msgstr ""
"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"
"can use the same values as the condition field on the server action.\n"
"If Value type is selected, the value will be used directly without "
"evaluation."
@ -1234,7 +1296,7 @@ msgstr "Guam (USA)"
#. module: base
#: sql_constraint:res.country:0
msgid "The name of the country must be unique !"
msgstr "The country name must be unique !"
msgstr "The country name must be unique!"
#. module: base
#: field:ir.module.module,installed_version:0
@ -1382,9 +1444,9 @@ msgid ""
"decimal number [00,53]. All days in a new year preceding the first Monday "
"are considered to be in week 0."
msgstr ""
"%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."
"%W - Week number of the year (Monday being the first day of the week) as an "
"integer [00,53]. All days in a new year preceding the first Monday are "
"considered to be in week 0."
#. module: base
#: code:addons/base/module/wizard/base_language_install.py:53
@ -1724,8 +1786,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' contains too many dots. XML ids should not contain dots ! These are "
"used to refer to other modules data, as in module.reference_id"
"'%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"
#. module: base
#: model:ir.module.module,summary:base.module_sale
@ -1872,8 +1934,8 @@ msgid ""
"simplified payment mode encoding, automatic picking lists generation and "
"more."
msgstr ""
"Get the most out of your points of sales with fast sale encoding, simplified "
"payment mode encoding, automatic picking lists generation and more."
"Get the most out of your points of sale with fast sale encoding, simplified "
"payment mode encoding, automatic pick list generation and more."
#. module: base
#: code:addons/base/ir/ir_fields.py:165
@ -2021,6 +2083,14 @@ msgid ""
"with the effect of creating, editing and deleting either ways.\n"
" "
msgstr ""
"\n"
"Synchronization of project task work entries with timesheet entries.\n"
"====================================================================\n"
"\n"
"This module lets you transfer the entries under tasks defined for Project\n"
"Management to the Timesheet line entries for a particular date and user\n"
"with the effect of creating, editing and deleting either way.\n"
" "
#. module: base
#: model:ir.model,name:base.model_ir_model_access
@ -2132,6 +2202,25 @@ msgid ""
"* *Before Delivery*: A Draft invoice is created and must be paid before "
"delivery\n"
msgstr ""
"\n"
"Manage sales quotations and orders\n"
"==================================\n"
"\n"
"This module makes the link between the sales and warehouse management "
"applications.\n"
"\n"
"Preferences\n"
"-----------\n"
"* Shipping: Choice of delivery at once or partial delivery\n"
"* Invoicing: choose how invoices will be paid\n"
"* Incoterms: International Commercial terms\n"
"\n"
"You can choose flexible invoicing methods:\n"
"\n"
"* *On Demand*: Invoices are created manually from Sales Orders when needed\n"
"* *On Delivery Order*: Invoices are generated from picking (delivery)\n"
"* *Before Delivery*: A Draft invoice is created and must be paid before "
"delivery\n"
#. module: base
#: field:ir.ui.menu,complete_name:0
@ -2155,9 +2244,9 @@ msgid ""
"decimal number [00,53]. All days in a new year preceding the first Sunday "
"are considered to be in week 0."
msgstr ""
"%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."
"%U - Week number of the year (Sunday being the first day of the week) as an "
"integer [00,53]. All days in a new year preceding the first Sunday are "
"considered to be in week 0."
#. module: base
#: view:base.language.export:0
@ -2316,6 +2405,28 @@ msgid ""
"* Maximal difference between timesheet and attendances\n"
" "
msgstr ""
"\n"
"Record and validate timesheets and attendance easily\n"
"====================================================\n"
"\n"
"This application supplies a new screen enabling you to manage both "
"attendance (Sign in/Sign out) and your work encoding (timesheet) by period. "
"Timesheet entries are made by employees each day. At the end of the defined "
"period, employees validate their sheet and the manager must then approve "
"their team's entries. Periods are defined in the company forms and you can "
"set them to run monthly or weekly.\n"
"\n"
"The complete timesheet validation process is:\n"
"---------------------------------------------\n"
"* Draft sheet\n"
"* Confirmation at the end of the period by the employee\n"
"* Validation by the project manager\n"
"\n"
"The validation can be configured in the company:\n"
"------------------------------------------------\n"
"* Period size (Day, Week, Month)\n"
"* Maximal difference between timesheet and attendances\n"
" "
#. module: base
#: code:addons/base/ir/ir_fields.py:342
@ -2371,7 +2482,7 @@ msgstr "Belize"
#. module: base
#: help:ir.actions.report.xml,header:0
msgid "Add or not the corporate RML header"
msgstr "Add or not the corporate RML header"
msgstr "Optionally add the corporate RML header"
#. module: base
#: model:res.country,name:base.ge
@ -2410,6 +2521,32 @@ msgid ""
"\n"
" "
msgstr ""
"\n"
" \n"
"Belgian localization for in/outgoing invoices (prereq to account_coda):\n"
"=========================================================================\n"
" - Rename 'reference' field labels to 'Communication'\n"
" - Add support for Belgian Structured Communication\n"
"\n"
"A Structured Communication can be generated automatically on outgoing "
"invoices according to the following algorithms:\n"
"-----------------------------------------------------------------------------"
"----------------------------------------\n"
" 1) Random : +++RRR/RRRR/RRRDD+++\n"
" **R..R =** Random Digits, **DD =** Check Digits\n"
" 2) Date : +++DOY/YEAR/SSSDD+++\n"
" **DOY =** Day of the Year, **SSS =** Sequence Number, **DD =** Check "
"Digits\n"
" 3) Customer Reference +++RRR/RRRR/SSSDDD+++\n"
" **R..R =** Customer Reference without non-numeric characters, **SSS "
"=** Sequence Number, **DD =** Check Digits \n"
" \n"
"The preferred type of Structured Communication and associated Algorithm can "
"be\n"
"specified on the Partner records. A 'random' Structured Communication will\n"
"generated if no algorithm is specified on the Partner record. \n"
"\n"
" "
#. module: base
#: model:res.country,name:base.pl
@ -2454,8 +2591,8 @@ msgid ""
"order in Object, and you can have loop on the sales order line. Expression = "
"`object.order_line`."
msgstr ""
"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 = "
"Enter the field/expression that will return the list. E.g. selecting the "
"sale order in Object, you can loop on the sales order line: Expression = "
"`object.order_line`."
#. module: base
@ -2546,6 +2683,27 @@ msgid ""
"Print product labels with barcode.\n"
" "
msgstr ""
"\n"
"This is the base module for managing products and pricelists in OpenERP.\n"
"========================================================================\n"
"\n"
"Products support variants, various pricing methods, supplier information,\n"
"made to stock/order, different units of measures, packaging and other "
"properties.\n"
"\n"
"Pricelists support:\n"
"-------------------\n"
" * Multiple-levels of discount (by product, category, quantities)\n"
" * Compute price based on different criteria:\n"
" * Other pricelist\n"
" * Cost price\n"
" * List price\n"
" * Supplier price\n"
"\n"
"Set pricelist preferences by product and/or partner.\n"
"\n"
"Print product labels with barcode.\n"
" "
#. module: base
#: model:ir.module.module,description:base.module_account_analytic_default
@ -2563,6 +2721,18 @@ msgid ""
" * Date\n"
" "
msgstr ""
"\n"
"Set default values for your analytic accounts.\n"
"==============================================\n"
"\n"
"Allows to automatically select analytic accounts based on criteria:\n"
"---------------------------------------------------------------------\n"
" * Product\n"
" * Partner\n"
" * User\n"
" * Company\n"
" * Date\n"
" "
#. module: base
#: field:res.company,rml_header1:0
@ -2887,6 +3057,29 @@ msgid ""
"* Purchase Analysis\n"
" "
msgstr ""
"\n"
"Manage goods requirement by Purchase Orders easily\n"
"==================================================\n"
"\n"
"Purchase management enables you to track your suppliers' price quotations "
"and convert them into purchase orders if necessary.\n"
"OpenERP has several methods of monitoring invoices and tracking the receipt "
"of ordered goods. You can handle partial deliveries in OpenERP with the "
"ability to keep track of items yet to be delivered from orders and to issue "
"reminders automatically.\n"
"\n"
"OpenERPs replenishment-management rules enable the system to generate draft "
"purchase orders automatically. Alternatively you can configure it to run a "
"lean process driven entirely by current production needs.\n"
"\n"
"Dashboard / Reports for Purchase Management will include:\n"
"---------------------------------------------------------\n"
"* Request for Quotations\n"
"* Purchase Orders Waiting Approval \n"
"* Monthly Purchases by Category\n"
"* Receptions Analysis\n"
"* Purchase Analysis\n"
" "
#. module: base
#: model:ir.model,name:base.model_ir_actions_act_window_close
@ -3016,6 +3209,15 @@ msgid ""
" * ``base_stage``: stage management\n"
" "
msgstr ""
"\n"
"This module handles state and stage. It is derived from the crm_base and "
"crm_case classes of crm.\n"
"============================================================================="
"======================\n"
"\n"
" * ``base_state``: state management\n"
" * ``base_stage``: stage management\n"
" "
#. module: base
#: model:ir.module.module,shortdesc:base.module_web_linkedin
@ -3312,6 +3514,8 @@ msgid ""
"For more details about translating OpenERP in your language, please refer to "
"the"
msgstr ""
"For more details about translating OpenERP into your language, please refer "
"to the"
#. module: base
#: field:res.partner,image:0
@ -3563,19 +3767,11 @@ msgid ""
"Canadian accounting charts and localizations.\n"
" "
msgstr ""
"\n"
"This is the module to manage the English and French - Canadian accounting "
"chart in OpenERP.\n"
"============================================================================="
"==============\n"
"\n"
"Canadian accounting charts and localisations.\n"
" "
#. module: base
#: view:base.module.import:0
msgid "Select module package to import (.zip file):"
msgstr "Select module package to import (.zip file):"
msgstr "Select module package to import (*.zip file):"
#. module: base
#: view:ir.filters:0
@ -3674,6 +3870,14 @@ msgid ""
"easily\n"
"keep track and order all your purchase orders.\n"
msgstr ""
"\n"
"This module allows you to manage your Purchase Requisition.\n"
"===========================================================\n"
"\n"
"When a purchase order is created, you now have the opportunity to save the\n"
"related requisition. By regrouping, this new object will allow you to "
"easily\n"
"keep track of and order all your purchase orders.\n"
#. module: base
#: help:ir.mail_server,smtp_host:0
@ -3798,13 +4002,13 @@ msgstr "If not set, acts as a default value for new resources"
#: code:addons/orm.py:4213
#, python-format
msgid "Recursivity Detected."
msgstr "Recursivity detected."
msgstr "Recursion detected."
#. module: base
#: code:addons/base/module/module.py:345
#, python-format
msgid "Recursion error in modules dependencies !"
msgstr "Recursion error in modules dependencies !"
msgstr "Recursion error in modules dependencies!"
#. module: base
#: model:ir.module.module,description:base.module_analytic_user_function
@ -3947,7 +4151,7 @@ msgstr "12. %w ==> 5 ( Friday is the 6th day)"
#. module: base
#: constraint:res.partner.category:0
msgid "Error ! You can not create recursive categories."
msgstr "Error ! You can not create recursive categories."
msgstr "Error! You can not create recursive categories."
#. module: base
#: view:res.lang:0

View File

@ -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: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-12-11 00:59+0000\n"
"Last-Translator: Santi (Pexego) <santiago@pexego.es>\n"
"PO-Revision-Date: 2012-12-13 16:14+0000\n"
"Last-Translator: Roberto Lizana (trey.es) <Unknown>\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: 2012-12-12 04:38+0000\n"
"X-Generator: Launchpad (build 16361)\n"
"X-Launchpad-Export-Date: 2012-12-14 05:35+0000\n"
"X-Generator: Launchpad (build 16369)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@ -365,6 +365,8 @@ msgid ""
"Database ID of record to open in form view, when ``view_mode`` is set to "
"'form' only"
msgstr ""
"Id. de la base datos del registro para abrir en el formulario de vista, "
"cuando se establece el modo de visto únicamente a 'formulario'"
#. module: base
#: field:res.partner.address,name:0
@ -871,6 +873,11 @@ msgid ""
"This module provides the Integration of the LinkedIn with OpenERP.\n"
" "
msgstr ""
"\n"
"Módulo web de LinkedIn para OpenERP.\n"
"=================================\n"
"Este módulo provee integración de LinkedIn con OpenERP.\n"
" "
#. module: base
#: help:ir.actions.act_window,src_model:0
@ -918,7 +925,7 @@ msgstr "Rumanía - Contabilidad"
#. module: base
#: model:ir.model,name:base.model_res_config_settings
msgid "res.config.settings"
msgstr ""
msgstr "Parámetros de configuración"
#. module: base
#: help:res.partner,image_small:0
@ -1073,6 +1080,7 @@ msgstr "Zimbabwe"
msgid ""
"Type of the constraint: `f` for a foreign key, `u` for other constraints."
msgstr ""
"Tipo de restricción: 'f' para un clave ajena, 'u' para otras restricciones."
#. module: base
#: view:ir.actions.report.xml:0
@ -1214,7 +1222,7 @@ msgstr "Principado de Andorra"
#. module: base
#: field:ir.rule,perm_read:0
msgid "Apply for Read"
msgstr ""
msgstr "Aplicar para lectura"
#. module: base
#: model:res.country,name:base.mn
@ -1244,7 +1252,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:727
#, python-format
msgid "Document model"
msgstr ""
msgstr "Modelo de documento"
#. module: base
#: view:res.lang:0

File diff suppressed because it is too large Load Diff

View File

@ -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: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-08-20 15:46+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"PO-Revision-Date: 2012-12-17 19:42+0000\n"
"Last-Translator: Ahti Hinnov <sipelgas@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: 2012-12-04 04:55+0000\n"
"X-Generator: Launchpad (build 16335)\n"
"X-Launchpad-Export-Date: 2012-12-18 04:57+0000\n"
"X-Generator: Launchpad (build 16372)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@ -11604,7 +11604,7 @@ msgstr "Aruande tüüp"
#: view:res.country.state:0
#: field:res.partner,state_id:0
msgid "State"
msgstr "Olek"
msgstr "Maakond"
#. module: base
#: selection:base.language.install,lang:0

15072
openerp/addons/base/i18n/hi.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-11-28 13:28+0000\n"
"PO-Revision-Date: 2012-12-18 04:42+0000\n"
"Last-Translator: gobi <Unknown>\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: 2012-12-04 04:58+0000\n"
"X-Generator: Launchpad (build 16335)\n"
"X-Launchpad-Export-Date: 2012-12-18 04:58+0000\n"
"X-Generator: Launchpad (build 16372)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@ -357,6 +357,10 @@ msgid ""
"\n"
" "
msgstr ""
"\n"
"p\n"
"\n"
" "
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale
@ -614,7 +618,7 @@ msgstr "Харьцааны Нэр"
#. module: base
#: view:ir.rule:0
msgid "Create Access Right"
msgstr ""
msgstr "Хандах Эрх Үүсгэх"
#. module: base
#: model:res.country,name:base.tv
@ -1346,7 +1350,7 @@ msgstr "Андорра, Principality of"
#. module: base
#: field:ir.rule,perm_read:0
msgid "Apply for Read"
msgstr ""
msgstr "Уншихаар Хэрэгжүүлэх"
#. module: base
#: model:res.country,name:base.mn
@ -1431,7 +1435,7 @@ msgstr "Сүүлийн Хувилбар"
#. module: base
#: view:ir.rule:0
msgid "Delete Access Right"
msgstr ""
msgstr "Хандах Эрхийг Устгах"
#. module: base
#: code:addons/base/ir/ir_mail_server.py:213
@ -1486,7 +1490,7 @@ msgstr "Дэмжигчид"
#. module: base
#: field:ir.rule,perm_unlink:0
msgid "Apply for Delete"
msgstr ""
msgstr "Устгахаар Хэрэгжүүлэх"
#. module: base
#: selection:ir.property,type:0
@ -1561,6 +1565,9 @@ msgid ""
" for uploading to OpenERP's translation "
"platform,"
msgstr ""
"TGZ формат: Энэ нь шахагдсан архив бөгөөд PO файлуудыг агуулсан\n"
" шууд OpenERP-н орчуулгын хөрсрүү хуулахад "
"тохиромжтой файл юм."
#. module: base
#: view:res.lang:0
@ -1587,7 +1594,7 @@ msgstr "Тест"
#. module: base
#: field:ir.actions.report.xml,attachment:0
msgid "Save as Attachment Prefix"
msgstr ""
msgstr "Хавсралтыг нэрлэж хадгалах угтвар"
#. module: base
#: field:ir.ui.view_sc,res_id:0
@ -1624,7 +1631,7 @@ msgstr "Гаити"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_fr_hr_payroll
msgid "French Payroll"
msgstr ""
msgstr "Фран Цалин"
#. module: base
#: view:ir.ui.view:0
@ -1698,6 +1705,33 @@ msgid ""
"Also implements IETF RFC 5785 for services discovery on a http server,\n"
"which needs explicit configuration in openerp-server.conf too.\n"
msgstr ""
"\n"
"Энэ модулиар баримтуудын хувьд WebDAV сервер идэвхжинэ.\n"
"===============================================================\n"
"\n"
"Ингэснээр OpenObject дахь хавсралт баримтуудыг нийцтэй ямар ч интернет \n"
"тольдруураар харах боломжтой.\n"
"\n"
"Суулгасан дараагаараа WebDAV сервер нь серверийн тохиргооны файлын [webdav] "
"\n"
" гэсэн хэсэгт тохиргоог хийх боломжтой.\n"
"Серверийн тохиргооны параметр нь:\n"
"\n"
" [webdav]\n"
" ; enable = True ; http(s) протоколь дээр WebDAV идэвхжинэ\n"
" ; vdir = webdav ; WebDAV ажиллах директорын нэр.\n"
" ; энэхүү webdav гэсэн анхны утгын хувьд \n"
" ; дараах байдлаар хандана \\\"http://localhost:8069/webdav/\n"
" ; verbose = True ; webdav-н дэлгэрэнгүй мэдэгдэлтэй горимыг нээнэ\n"
" ; debug = True ; webdav-н дебаагдах горимыг идэвхжүүлнэ.\n"
" ; ингэснээр мессежүүд нь python log-руу бичигдэнэ. \n"
" ; логийн түвшин нь \\\"debug\\\" болон \\\"debug_rpc\\\" байдаг. эдгээр "
"\n"
"сонголтыг\n"
" ; хэвээр нь үлдээж болно.\n"
"\n"
"Түүнчлэн IETF RFC 5785-г http серверт хэрэгжүүлдэг. Тодорхой тохиргоог \n"
"openerp-server.conf-д тохируулах хэрэгтэй.\n"
#. module: base
#: model:ir.module.category,name:base.module_category_purchase_management
@ -1745,6 +1779,12 @@ msgid ""
"=============\n"
" "
msgstr ""
"\n"
"Энэ модуль нь хэрэв гомдол, порталь суулгагдсан байгаа бол гомдол меню болон "
"боломжийг портальд нэмдэг.\n"
"============================================================================="
"=============\n"
" "
#. module: base
#: model:ir.actions.act_window,help:base.action_res_partner_bank_account_form
@ -1791,7 +1831,7 @@ msgstr "Кодгүй хэл \"%s\" байна"
#: model:ir.module.category,name:base.module_category_social_network
#: model:ir.module.module,shortdesc:base.module_mail
msgid "Social Network"
msgstr ""
msgstr "Нийгмийн Сүлжээ"
#. module: base
#: view:res.lang:0
@ -1832,6 +1872,28 @@ msgid ""
"in their pockets, this module is essential.\n"
" "
msgstr ""
"\n"
"Энэ модуль нь үдийн цайг менеж хийх модуль.\n"
"================================\n"
"\n"
"Компаниуд нь ажилчиддаа орчин, нөхцлийг таатай болгох үүднээс олон "
"нийлүүлэгчээс хачиртай талх, пицца гэх мэтийг захиалах боломжийг санал "
"болгодог.\n"
"\n"
"Гэхдээ олон тооны ажилтан, нийлүүлэгч нар байгаа тохиолдолд зөв удирдлага "
"шаардлагатай болдог.\n"
"\n"
"\n"
"\"Үдийн цайны Захиалга\" модуль нь энэ менежментийг хялбар болгож ажилчидад "
"илүү өргөн багаж, хэрэглэгээг санал болгодог.\n"
"\n"
"Цаашлаад ажилчны тохиргоо дээр үндэслэн сануулга, хоол хурдан захиалах "
"боломж зэрэгийг санал болгодогоороо хоол болон нийлүүлэгчийн менежментийг "
"бүрэн гүйцэд болгодог.\n"
"\n"
"Ажилчид заавал задгай мөнгө кармалж явах заваан ажлаас ажилчдаа чөлөөлж "
"ажилчдынхаа цагийг хэмнэхэд энэ модуль нь туйлын чухал.\n"
" "
#. module: base
#: view:wizard.ir.model.menu.create:0
@ -1871,7 +1933,7 @@ msgstr ""
#. module: base
#: help:res.partner,website:0
msgid "Website of Partner or Company"
msgstr ""
msgstr "Харилцагч эсвэл Компаний веб сайт"
#. module: base
#: help:base.language.install,overwrite:0
@ -1916,7 +1978,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,summary:base.module_sale
msgid "Quotations, Sale Orders, Invoicing"
msgstr ""
msgstr "Үнийн санал, Борлуулалтын Захиалга, Нэхэмжлэл"
#. module: base
#: field:res.users,login:0
@ -1935,7 +1997,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_portal_project_issue
msgid "Portal Issue"
msgstr ""
msgstr "Портал Асуудал"
#. module: base
#: model:ir.ui.menu,name:base.menu_tools
@ -1955,11 +2017,15 @@ msgid ""
"Launch Manually Once: after having been launched manually, it sets "
"automatically to Done."
msgstr ""
"Гараар: Гараар ажилуулна.\n"
"Автомат: Системийн тохиргоо өөрчлөгдөх бүрт автомат ажиллана.\n"
"Гараар нэг удаа: гараар ажилуулсан дараа автоматаар Хийгдсэн болж \n"
"тохируулагдана."
#. module: base
#: field:res.partner,image_small:0
msgid "Small-sized image"
msgstr ""
msgstr "Жижиг-хэмжээт зураг"
#. module: base
#: model:ir.module.module,shortdesc:base.module_stock
@ -2040,6 +2106,15 @@ msgid ""
"It assigns manager and user access rights to the Administrator and only user "
"rights to the Demo user. \n"
msgstr ""
"\n"
"Санхүүгийн Хандах Эрх.\n"
"=========================\n"
"\n"
"Энэ модуль нь санхүүгийн журнал, дансны мод гэх мэт бүх боломж руу хандах \n"
"хандалтыг удирдах боломжийг олгодог.\n"
"\n"
"Энэ нь менежер, хэрэглэгч хандалтын эрхийг Администраторт олгож Demo \n"
"хэрэглэгчид хэрэглэгч эрхийг олгодог. \n"
#. module: base
#: field:ir.attachment,res_id:0
@ -2066,6 +2141,8 @@ msgstr ""
#, python-format
msgid "Unknown value '%s' for boolean field '%%(field)s', assuming '%s'"
msgstr ""
"'%s' гэсэн утга boolean '%%(field)s' талбарт мэдэгдэхгүй утга, '%s' гэж үзэж "
"байна"
#. module: base
#: model:res.country,name:base.nl
@ -2075,12 +2152,12 @@ msgstr "Нидерланд"
#. module: base
#: model:ir.module.module,shortdesc:base.module_portal_event
msgid "Portal Event"
msgstr ""
msgstr "Порталь Үйл явдал"
#. module: base
#: selection:ir.translation,state:0
msgid "Translation in Progress"
msgstr ""
msgstr "Орчуулга Хийгдэж байна"
#. module: base
#: model:ir.model,name:base.model_ir_rule
@ -2095,7 +2172,7 @@ msgstr "Өдөр"
#. module: base
#: model:ir.module.module,summary:base.module_fleet
msgid "Vehicle, leasing, insurances, costs"
msgstr ""
msgstr "Машин, лизинг, даатгал, өртөгүүд"
#. module: base
#: view:ir.model.access:0
@ -2123,6 +2200,23 @@ msgid ""
"synchronization with other companies.\n"
" "
msgstr ""
"\n"
"Энэ модуль нь ерөнхиий тохиолдолд хуваалцах боломжийг таны OpenERP өгөгдлийн "
"\n"
"баазад олгодог багаж юм.\n"
"========================================================================\n"
"\n"
"Энэ нь 'хуваалцах' даруулыг нэмдэг бөгөөд OpenERP-н дуртай өгөгдлийг хамт \n"
"ажиллагч, захиалагч, найз нартайгаа хуваалцах боломжийг вебэд олгодог.\n"
"\n"
"Систем нь шинэ хэрэглэгч болон группыг автоматаар үүсгэдэг. Зохистой хандах "
"\n"
"дүрэмийг ir.rules-д автоматаар нэмж зөвхөн хуваалцсан өгөгдөл рүү хандах \n"
"хандалтын хяналтаар хангаддаг.\n"
"\n"
"Энэ нь хамтран ажиллах, мэдлэгээ хуваалцах, бусад компанитай мэдээллээ \n"
"ижилтгэх зэрэгт маш зохимжтой.\n"
" "
#. module: base
#: model:ir.module.module,shortdesc:base.module_process
@ -2135,6 +2229,8 @@ msgid ""
"Check this box if this contact is a supplier. If it's not checked, purchase "
"people will not see it when encoding a purchase order."
msgstr ""
"Хэрэв холбогч нь нийлүүлэгч бол үүнийг тэмдэглэнэ. Хэрэв тэмдэглээгүй бол "
"худалдан авалтын хүмүүст худалдан авалтын захиалга шивэх үед харагдахгүй."
#. module: base
#: model:ir.module.module,shortdesc:base.module_hr_evaluation
@ -2183,6 +2279,7 @@ msgstr "БЗ-д даалгавар үүсгэх"
#, python-format
msgid "This column contains module data and cannot be removed!"
msgstr ""
"Энэ багана нь модулийн өгөгдлийг хадгалж байгаа тул устгагдах боломжгүй!"
#. module: base
#: field:ir.attachment,res_model:0
@ -2207,6 +2304,15 @@ msgid ""
"with the effect of creating, editing and deleting either ways.\n"
" "
msgstr ""
"\n"
"Төслийн даалгаврыг ажлын цагийн хуваарьтай ижилтгэх.\n"
"====================================================================\n"
"\n"
"Энэ модуль нь Төслийн Менежмент модуль дахь даалгавруудыг Цагийн хуваарийн\n"
"ажлууд руу тодорхой огноонд тодорхой хэрэглэгчид шилжүүлдэг. Мөн цагийн \n"
"хуваариас нөгөө чиглэлд үүсгэх, засах, устгах\n"
"хоёр чиглэлд хийх боломжтой.\n"
" "
#. module: base
#: model:ir.model,name:base.model_ir_model_access
@ -2226,6 +2332,13 @@ msgid ""
" templates to target objects.\n"
" "
msgstr ""
"\n"
" * Дансны Мод, Татвар, Татварын Код, Журналь, Дансны Үлгэр, Шинжилгээний "
"Дансны Мод, Шинжилгээний Журналиудад олон хэлийг нэмдэг.\n"
" * Тохируулах харилцах нь дараахыг өөрчилдөг.\n"
" - Үлгэрээс авагдсан Дансны Модт, Татвар, Татварын Код, Мөчлөг зэрэгт "
"орчуулгыг хуулна.\n"
" "
#. module: base
#: field:workflow.transition,act_from:0
@ -2317,6 +2430,25 @@ msgid ""
"* *Before Delivery*: A Draft invoice is created and must be paid before "
"delivery\n"
msgstr ""
"\n"
"Борлуулалтын үнийн санал, захиалгыг менеж хийх модуль\n"
"==================================\n"
"\n"
"Энэ модуль нь борлуулалт болон агуулахын модулийн хооронд холбох үүрэгтэй.\n"
"\n"
"Тохиргоо\n"
"-----------\n"
"* Хүргэлт: Хүргэлтийн сонголт буюу хэсэгчилсэн эсвэл нэг мөсөн\n"
"* Нэхэмжлэл: Нэхэмжлэл хэрхэн төлөгдөхийг сонгоно\n"
"* Инкотерм: Олон улсын худалдааны нөхцөл\n"
"\n"
"Нэхэмжлэх уян хатан аргуудыг сонгох боломжтой:\n"
"\n"
"* *Шаардалтаар*: Борлуулалтын захиалгаас дуртай үедээ гараар нэхэмжлэл "
"үүсгэх\n"
"* *Хүргэх захиалгаар*: Хүргэх захиалгаар нэхэмжлэл үүсгэх\n"
"* *Хүргэлтээс өмнө*: Ноорог нэхэмжлэл үүсгэгдэж хүргэхээс өмнө төлөгдсөн "
"байх ёстой\n"
#. module: base
#: field:ir.ui.menu,complete_name:0
@ -2347,7 +2479,7 @@ msgstr ""
#. module: base
#: view:base.language.export:0
msgid "PO(T) format: you should edit it with a PO editor such as"
msgstr ""
msgstr "PO(T) формат: PO текст засварлагчаар засварлах нь зохимжтой"
#. module: base
#: model:ir.ui.menu,name:base.menu_administration
@ -2371,7 +2503,7 @@ msgstr "Үүсгэх / Бичих / Хувилах"
#. module: base
#: view:ir.sequence:0
msgid "Second: %(sec)s"
msgstr ""
msgstr "Секунд: %(sec)s"
#. module: base
#: field:ir.actions.act_window,view_mode:0
@ -2436,7 +2568,7 @@ msgstr "Багамийн арлууд"
#. module: base
#: field:ir.rule,perm_create:0
msgid "Apply for Create"
msgstr ""
msgstr "Үүсгэхээр Хэрэгжүүлэх"
#. module: base
#: model:ir.module.category,name:base.module_category_tools
@ -2459,6 +2591,8 @@ msgid ""
"Appears by default on the top right corner of your printed documents (report "
"header)."
msgstr ""
"Хэвлэгдсэн баримтын баруун дээд (тайлангийн толгой) оройд анхны байдлаараа "
"байрладаг."
#. module: base
#: field:base.module.update,update:0
@ -2501,6 +2635,27 @@ msgid ""
"* Maximal difference between timesheet and attendances\n"
" "
msgstr ""
"\n"
"Цаг бүртгэл болон ирцийг хялбараар хөтлөж, шалгадаг\n"
"=====================================================\n"
"\n"
"Энэ аппликэйшн нь ирц (Нэвтрэх/Гарах), цаг бүртгэлийг бүртгэх ажлыг "
"гүйцэтгэх нэмэлт цонхтой байдаг. Цаг бүртгэлийн мөрүүдийг ажилчид өдөр бүр "
"хөтлөнө. Тодорхойлогсдон мөчлөгийн төгсгөлд ажилчин өөрийн цагийн хуудсыг "
"шалгах бөгөөд менежер нь цааш баталдаг. Мөчлөг нь компаний тохиргооны "
"маягтад тодорхойлогдсон байдаг сараа, долооногоор тааруулах боломжтой. \n"
"\n"
"Цаг бүртгэлийн шалгалтын бүрэн ажлын урсгал:\n"
"---------------------------------------------\n"
"* Ноорог хуудас\n"
"* Мөчлөгийн төгсгөлд ажилнчин цагийн хуудсыг магадлаж батлана\n"
"* Төслийн менежер шалгана\n"
"\n"
"Шалгалт нь компаний тохиргоонд тохируулах боломжтой:\n"
"------------------------------------------------\n"
"* Мөчлөгийн хэмжээ (Өдөрөөр, Долооогоор, Сараар)\n"
"* Цагийн хуудас ирцийн зөвшөөрөгдөх хамгийн их ялгаа\n"
" "
#. module: base
#: code:addons/base/ir/ir_fields.py:342
@ -2508,6 +2663,8 @@ msgstr ""
msgid ""
"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'"
msgstr ""
"%(field_type)s талбарт тохирох '%(value)s' гэсэн утга '%%(field)s' талбарт "
"алга"
#. module: base
#: model:ir.actions.act_window,help:base.action_ui_view
@ -2678,6 +2835,8 @@ msgid ""
"View type: Tree type to use for the tree view, set to 'tree' for a "
"hierarchical tree view, or 'form' for a regular list view"
msgstr ""
"Харагдацын төрөл: Мөчир төрөл нь мөчир төрлөөр харахад хэрэглэгдэх 'tree' "
"утга эсвэл 'form' утгаар энгийн жагсаалт харагдацыг тохируулдаг."
#. module: base
#: sql_constraint:ir.ui.view_sc:0
@ -2730,6 +2889,26 @@ msgid ""
"Print product labels with barcode.\n"
" "
msgstr ""
"\n"
"Энэ модуль нь OpenERP-д үнийн хүснэгт болон барааг менеж хийх модуль юм.\n"
"========================================================================\n"
"\n"
"Бараа нь хувилбарууд, ялгаатай үнийн аргууд, нийлүүлэгчийн мэдээлэл, "
"захиалуулах, хадгалуулах, ялгаатай хэмжих нэгжүүд, савлалт, үзүүлэлтүүд гэх "
"мэт олон зүйлийг дэмждэг.\n"
"\n"
"Үнийн хүснэгт нь дараах зүйлсийг дэмждэг:\n"
" * Олон түвшний хөнгөлөлт (бараагаар, ангилалаар, тоо ширхэгээр)\n"
" * Ялгаатай шалгууруудаар үнэ бодогдох\n"
" * Өөр үнийн хүснэгт,\n"
" * Өртөг үнэ,\n"
" * Суурь үнэ,\n"
" * Нийлүүлэгчийн үнэ, …\n"
"\n"
"Үнийн хүснэгтийн бараагаар болон/эсвэл харилцагчаарх тохиргоо.\n"
"\n"
"Барааны шошгыг зураасан кодтой хэвлэх.\n"
" "
#. module: base
#: model:ir.module.module,description:base.module_account_analytic_default
@ -2747,11 +2926,22 @@ msgid ""
" * Date\n"
" "
msgstr ""
"\n"
"Шинжилгээний дансдад анхны утгыг тохируулна.\n"
"Нөхцөл үндэслэн шинжилгээний дансыг автомат сонгох боломжийг олгоно:\n"
"=====================================================================\n"
"\n"
" * Бараа\n"
" * Харилцагч\n"
" * Хэрэглэгч\n"
" * Компани\n"
" * Огноо\n"
" "
#. module: base
#: field:res.company,rml_header1:0
msgid "Company Slogan"
msgstr ""
msgstr "Компаний уриа"
#. module: base
#: model:res.country,name:base.bb
@ -2775,7 +2965,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_auth_oauth_signup
msgid "Signup with OAuth2 Authentication"
msgstr ""
msgstr "OAuth2 эрхийн хяналтаар бүртгүүлэх"
#. module: base
#: selection:ir.model,state:0
@ -2802,7 +2992,7 @@ msgstr "Грек / Ελληνικά"
#. module: base
#: field:res.company,custom_footer:0
msgid "Custom Footer"
msgstr ""
msgstr "Өөриймшүүлсэн Хөл"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_crm
@ -2870,7 +3060,7 @@ msgstr "Хурдан холбоосын нэр"
#. module: base
#: field:res.partner,contact_address:0
msgid "Complete Address"
msgstr ""
msgstr "Бүтэн Хаяг"
#. module: base
#: help:ir.actions.act_window,limit:0
@ -2930,6 +3120,39 @@ msgid ""
"* Monthly Turnover (Graph)\n"
" "
msgstr ""
"\n"
"Борлуулалтын үнийн санал, захиалгыг менежмент хийх модуль\n"
"==================================\n"
"\n"
"Энэ аппликэйшн нь борлуулалтын бүх захиалга болон түүхийг хөтлөж оновчтой, "
"зохистой аргаар борлуулалтын зорилгыг менежмент хийх боломжийг олгодог.\n"
"\n"
"Борлуулалтын бүрэн ажлын урсгалыг удирддаг:\n"
"\n"
"* **Үнийн санал** -> **Борлуулалтын Захиалга** -> **Нэхэмжлэл**\n"
"\n"
"Тохиргоо (Агуулахын модултай хамт суусан үед)\n"
"------------------------------------------------------\n"
"\n"
"Хэрэв агуулахын модуль суусан байвал дараах тохиргоонуудыг хийх боломжтой:\n"
"\n"
"* Хүргэлт: Бүхэлд нь эсвэл хэсэгчилж хүргэх сонголт\n"
"* Нэхэмжлэл: Нэхэмжлэл хэрхэн төлөгдөх сонголт\n"
"* Инкотерм: Олон улсын худалдааны нөхцөл\n"
"\n"
"Нэхэмжлэх уян хатан аргуудыг сонгох боломжтой:\n"
"\n"
"* *Шаардалтаар*: Борлуулалтын захиалгаас дуртай үедээ гараар үүсгэх\n"
"* *Хүргэх захиалгаар*: Нэхэмжлэх нь бэлтгэх(хүргэх) баримтаас үүснэ\n"
"* *Хүргэлтээс өмнө*: Ноорог нэмэжлэл үүсгэгдэж хүргэхээс өмнө төлөгдсөн байх "
"ёстой\n"
"\n"
"\n"
"Борлуулалтын Менежерийн Хянах Самбар нь дараах зүйлсийг агуулна\n"
"------------------------------------------------\n"
"* Миний Үнийн Саналууд\n"
"* Сарын Эргэц (График)\n"
" "
#. module: base
#: field:ir.actions.act_window,res_id:0
@ -2942,7 +3165,7 @@ msgstr "Бичлэгийн ID"
#. module: base
#: view:ir.filters:0
msgid "My Filters"
msgstr ""
msgstr "Миний Шүүлтүүрүүд"
#. module: base
#: field:ir.actions.server,email:0
@ -2956,12 +3179,15 @@ msgid ""
"Module to attach a google document to any model.\n"
"================================================\n"
msgstr ""
"\n"
"Google баримтыг хавсаргадаг модуль.\n"
"================================================\n"
#. module: base
#: code:addons/base/ir/ir_fields.py:334
#, python-format
msgid "Found multiple matches for field '%%(field)s' (%d matches)"
msgstr ""
msgstr "'%%(field)s' талбарын хувьд олон олдоц байна (%d олдоцууд)"
#. module: base
#: selection:base.language.install,lang:0
@ -2995,7 +3221,7 @@ msgstr "Клиент рүү харах таагийн хамт илгээгдс
#. module: base
#: model:ir.module.module,summary:base.module_contacts
msgid "Contacts, People and Companies"
msgstr ""
msgstr "Холбогч, Хүмүүс, Компаниуд"
#. module: base
#: model:res.country,name:base.tt

View File

@ -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: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-12-11 11:47+0000\n"
"PO-Revision-Date: 2012-12-17 20:05+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: 2012-12-12 04:38+0000\n"
"X-Generator: Launchpad (build 16361)\n"
"X-Launchpad-Export-Date: 2012-12-18 04:58+0000\n"
"X-Generator: Launchpad (build 16372)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@ -1591,7 +1591,7 @@ msgstr ""
#. module: base
#: model:res.country,name:base.mf
msgid "Saint Martin (French part)"
msgstr ""
msgstr "Saint-Martin (część francuska)"
#. module: base
#: model:ir.model,name:base.model_ir_exports
@ -1623,7 +1623,7 @@ msgstr "Konfiguracja stopki raportów"
#. module: base
#: field:ir.translation,comments:0
msgid "Translation comments"
msgstr ""
msgstr "Komentarze do tłumaczenia"
#. module: base
#: model:ir.module.module,description:base.module_lunch
@ -1895,7 +1895,7 @@ msgstr ""
#. module: base
#: selection:ir.translation,state:0
msgid "Translation in Progress"
msgstr ""
msgstr "Tłumaczenie w toku"
#. module: base
#: model:ir.model,name:base.model_ir_rule
@ -4448,7 +4448,7 @@ msgstr "Fakturowanie czasu zadań"
#: model:ir.ui.menu,name:base.marketing_menu
#: model:ir.ui.menu,name:base.menu_report_marketing
msgid "Marketing"
msgstr ""
msgstr "Marketing"
#. module: base
#: view:res.partner.bank:0
@ -4489,7 +4489,7 @@ msgstr ""
#: model:ir.actions.act_window,name:base.action_view_base_language_install
#: model:ir.ui.menu,name:base.menu_view_base_language_install
msgid "Load a Translation"
msgstr ""
msgstr "Pobierz tłumaczenie"
#. module: base
#: field:ir.module.module,latest_version:0
@ -11768,7 +11768,7 @@ msgstr ""
#. module: base
#: selection:res.request,state:0
msgid "waiting"
msgstr ""
msgstr "oczekiwanie"
#. module: base
#: model:ir.model,name:base.model_workflow_triggers
@ -14342,7 +14342,7 @@ msgstr "Prawo"
#: field:res.partner,vat:0
#, python-format
msgid "TIN"
msgstr ""
msgstr "NIP"
#. module: base
#: model:res.country,name:base.aw

View File

@ -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: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-12-11 10:27+0000\n"
"Last-Translator: Virgílio Oliveira <virgilio.oliveira@multibase.pt>\n"
"PO-Revision-Date: 2012-12-17 16:10+0000\n"
"Last-Translator: Rui Franco (multibase.pt) <Unknown>\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: 2012-12-12 04:38+0000\n"
"X-Generator: Launchpad (build 16361)\n"
"X-Launchpad-Export-Date: 2012-12-18 04:58+0000\n"
"X-Generator: Launchpad (build 16372)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@ -1734,7 +1734,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,summary:base.module_sale
msgid "Quotations, Sale Orders, Invoicing"
msgstr ""
msgstr "Orçamentos, ordens de venda, faturação"
#. module: base
#: field:res.users,login:0
@ -2146,7 +2146,7 @@ msgstr "Caminho completo"
#. module: base
#: view:base.language.export:0
msgid "The next step depends on the file format:"
msgstr ""
msgstr "O próximo passo depende do tipo de ficheiro:"
#. module: base
#: model:ir.module.module,shortdesc:base.module_idea
@ -2328,6 +2328,8 @@ msgstr ""
msgid ""
"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'"
msgstr ""
"Não foi encontrado o registo para %(field_type)s '%(value)s' no campo "
"'%%(field)s'"
#. module: base
#: model:ir.actions.act_window,help:base.action_ui_view
@ -3144,6 +3146,8 @@ msgid ""
"the user will have an access to the human resources configuration as well as "
"statistic reports."
msgstr ""
"O utilizador terá acesso às configurações de recursos humanos, bem como aos "
"relatórios de estatísticas."
#. module: base
#: model:ir.module.module,description:base.module_web_shortcuts
@ -4448,7 +4452,7 @@ msgstr "`code` deve ser único"
#. module: base
#: model:ir.module.module,shortdesc:base.module_knowledge
msgid "Knowledge Management System"
msgstr ""
msgstr "Sistema de gestão do conhecimento"
#. module: base
#: view:workflow.activity:0
@ -5937,6 +5941,12 @@ msgid ""
"Allows users to create custom dashboard.\n"
" "
msgstr ""
"\n"
"Permite ao utilizador criar um painel personalizado.\n"
"========================================\n"
"\n"
"Permite aos utilizadores criarem um painel personalizado.\n"
" "
#. module: base
#: model:ir.actions.act_window,name:base.ir_access_act
@ -7240,7 +7250,7 @@ msgstr ""
#. module: base
#: field:res.partner,function:0
msgid "Job Position"
msgstr ""
msgstr "Cargo"
#. module: base
#: view:res.partner:0
@ -7447,7 +7457,7 @@ msgstr "mdx"
#. module: base
#: view:ir.cron:0
msgid "Scheduled Action"
msgstr ""
msgstr "Ação calendarizada"
#. module: base
#: model:res.country,name:base.bi
@ -7930,6 +7940,8 @@ msgid ""
"Select this if you want to set company's address information for this "
"contact"
msgstr ""
"Selecione esta opção se deseja definir as informações do endereço da empresa "
"para este contacto"
#. module: base
#: field:ir.default,field_name:0
@ -9608,6 +9620,13 @@ msgid ""
"Allow administrator to click a button to send a \"Reset Password\" request "
"to a user.\n"
msgstr ""
"\n"
"Recriar senha\n"
"==============\n"
"\n"
"Permite aos utilizadores recriarem a sua senha de acesso.\n"
"Permite ao administrador carregar num botão para enviar um pedido de "
"\"Recriar senha\" a um utilizador.\n"
#. module: base
#: help:ir.actions.server,email:0
@ -10397,6 +10416,8 @@ msgstr "ir.translation"
msgid ""
"Please contact your system administrator if you think this is an error."
msgstr ""
"Por favor, contacte o seu administrador de sistemas se julga que isto é um "
"erro."
#. module: base
#: code:addons/base/module/module.py:519
@ -10582,7 +10603,7 @@ msgstr ""
#. module: base
#: help:res.partner,ean13:0
msgid "BarCode"
msgstr ""
msgstr "Código de barras"
#. module: base
#: help:ir.model.fields,model_id:0
@ -11150,7 +11171,7 @@ msgstr "Granada"
#. module: base
#: help:res.partner,customer:0
msgid "Check this box if this contact is a customer."
msgstr ""
msgstr "Selecione esta opção se este contacto é de um cliente."
#. module: base
#: view:ir.actions.server:0
@ -12037,7 +12058,7 @@ msgstr ""
#. module: base
#: model:res.country,name:base.cd
msgid "Congo, Democratic Republic of the"
msgstr ""
msgstr "Congo, República Democrática do"
#. module: base
#: model:res.country,name:base.cr
@ -12084,7 +12105,7 @@ msgstr "Moedas"
#. module: base
#: model:res.partner.category,name:base.res_partner_category_8
msgid "Consultancy Services"
msgstr ""
msgstr "Serviços de consultoria"
#. module: base
#: help:ir.values,value:0
@ -12094,7 +12115,7 @@ msgstr "O valor padrão (em conserva) ou referência a uma ação"
#. module: base
#: field:ir.actions.report.xml,auto:0
msgid "Custom Python Parser"
msgstr ""
msgstr "Interpretador de Python (à medida)"
#. module: base
#: sql_constraint:res.groups:0
@ -13456,6 +13477,8 @@ msgid ""
"This cron task is currently being executed and may not be modified, please "
"try again in a few minutes"
msgstr ""
"Esta tarefa está sendo executada e não pode ser alterada. Por favor, tente "
"daqui a alguns minutos.."
#. module: base
#: view:base.language.export:0
@ -13506,7 +13529,7 @@ msgstr "A Atividade Destino"
#. module: base
#: model:ir.module.module,shortdesc:base.module_project_issue
msgid "Issue Tracker"
msgstr ""
msgstr "Acompanhamento de problemas"
#. module: base
#: view:base.module.update:0
@ -13544,7 +13567,7 @@ msgstr ""
#. module: base
#: model:res.country,name:base.bq
msgid "Bonaire, Sint Eustatius and Saba"
msgstr ""
msgstr "Bonaire, Sint Eustatius e Saba"
#. module: base
#: model:ir.actions.report.xml,name:base.ir_module_reference_print
@ -13631,7 +13654,7 @@ msgstr "Origem"
#: field:ir.model.constraint,date_init:0
#: field:ir.model.relation,date_init:0
msgid "Initialization Date"
msgstr ""
msgstr "Data de inicialização"
#. module: base
#: model:res.country,name:base.vu
@ -14148,7 +14171,7 @@ msgstr "Módulos a Atualizar"
#. module: base
#: model:ir.ui.menu,name:base.menu_custom_multicompany
msgid "Multi-Companies"
msgstr ""
msgstr "Multiempresas"
#. module: base
#: field:workflow,osv:0
@ -14213,6 +14236,11 @@ msgid ""
"Web pages\n"
" "
msgstr ""
"\n"
"Páginas\n"
"=====\n"
"Páginas web\n"
" "
#. module: base
#: help:ir.actions.server,code:0
@ -14816,7 +14844,7 @@ msgstr "'Plug-in' para o Thunderbird"
#. module: base
#: model:ir.module.module,summary:base.module_event
msgid "Trainings, Conferences, Meetings, Exhibitions, Registrations"
msgstr ""
msgstr "Formação, conferẽncias, reuniões, exposições, inscrições"
#. module: base
#: model:ir.model,name:base.model_res_country
@ -14834,7 +14862,7 @@ msgstr "País"
#. module: base
#: model:res.partner.category,name:base.res_partner_category_15
msgid "Wholesaler"
msgstr ""
msgstr "Vendedor por atacado"
#. module: base
#: model:ir.module.module,shortdesc:base.module_base_vat

View File

@ -7,15 +7,15 @@ msgstr ""
"Project-Id-Version: pt_BR\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-12-11 11:52+0000\n"
"PO-Revision-Date: 2012-12-16 22:18+0000\n"
"Last-Translator: Fábio Martinelli - http://zupy.com.br "
"<webmaster@guaru.net>\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: 2012-12-12 04:39+0000\n"
"X-Generator: Launchpad (build 16361)\n"
"X-Launchpad-Export-Date: 2012-12-17 04:44+0000\n"
"X-Generator: Launchpad (build 16372)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@ -26,8 +26,8 @@ msgid ""
" "
msgstr ""
"\n"
"Módulo para Verificar Escrita e Impressão.\n"
"========================================\n"
"Módulo para Criar e Imprimir Cheques.\n"
"=====================================\n"
" "
#. module: base
@ -93,7 +93,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,summary:base.module_point_of_sale
msgid "Touchscreen Interface for Shops"
msgstr "Interface Touchscreen para lojas"
msgstr "Interface Toque na Tela para Lojas"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll
@ -159,7 +159,7 @@ msgstr ""
#. module: base
#: help:res.partner,employee:0
msgid "Check this box if this contact is an Employee."
msgstr "Marque se este contato é um empregado."
msgstr "Marque a opção se este contato é um empregado."
#. module: base
#: help:ir.model.fields,domain:0
@ -6594,7 +6594,7 @@ msgstr "Cancelar Entradas de Diário"
#. module: base
#: field:res.partner,tz_offset:0
msgid "Timezone offset"
msgstr ""
msgstr "Deslocamento de Fuso Horário"
#. module: base
#: model:ir.module.module,description:base.module_marketing_campaign
@ -7938,7 +7938,7 @@ msgstr "Ref. Visão de Pesquisa"
#. module: base
#: help:res.users,partner_id:0
msgid "Partner-related data of the user"
msgstr ""
msgstr "Dados do usuário relacionado ao Parceiro"
#. module: base
#: model:ir.module.module,description:base.module_crm_todo
@ -8437,7 +8437,7 @@ msgstr "Determina onde o símbolo deve ser colocado após ou antes o valor."
#. module: base
#: model:ir.module.module,shortdesc:base.module_pad_project
msgid "Pad on tasks"
msgstr ""
msgstr "Blocos nas Tarefas"
#. module: base
#: model:ir.model,name:base.model_base_update_translations
@ -9563,6 +9563,18 @@ msgid ""
"Thank you in advance for your cooperation.\n"
"Best Regards,"
msgstr ""
"Prezado Senhor / Senhora,\n"
"\n"
"Nossos registros indicam que alguns pagamentos em sua conta estão em aberto. "
"Por favor, veja os detalhes abaixo.\n"
"Se o valor já tiver sido pago, por favor desconsidere este aviso. Caso "
"contrário, regularize os pagamentos o mais breve possível.\n"
"Se você tiver alguma dúvida sobre seus pagamentos, por favor, entre em "
"contato conosco.\n"
"\n"
"Obrigado antecipadamente pela sua colaboração.\n"
"\n"
"Atenciosamente,"
#. module: base
#: view:ir.module.category:0
@ -9708,6 +9720,14 @@ msgid ""
"If set to true it allows user to cancel entries & invoices.\n"
" "
msgstr ""
"\n"
"Permite cancelar entradas contábeis.\n"
"====================================\n"
"\n"
"Este módulo adiciona um campo 'Permitir Cancelamento de Entradas' no "
"formulário de um diário contábil.\n"
"Se estiver marcado permite ao usuário cancelar entradas & faturas.\n"
" "
#. module: base
#: model:ir.module.module,shortdesc:base.module_plugin
@ -10141,7 +10161,7 @@ msgstr "Descrição dos Campos"
#. module: base
#: model:ir.module.module,shortdesc:base.module_analytic_contract_hr_expense
msgid "Contracts Management: hr_expense link"
msgstr ""
msgstr "Gerenciamento de Contratos: link hr_expense"
#. module: base
#: view:ir.attachment:0
@ -10758,7 +10778,7 @@ msgstr "A fazer"
#. module: base
#: model:ir.module.module,shortdesc:base.module_portal_hr_employees
msgid "Portal HR employees"
msgstr ""
msgstr "Portal RH funcionários"
#. module: base
#: selection:base.language.install,lang:0
@ -11724,6 +11744,17 @@ msgid ""
"automatically new claims based on incoming emails.\n"
" "
msgstr ""
"\n"
"\n"
"Gerenciar solicitações dos clientes.\n"
"================================================== "
"==============================\n"
"Esta aplicação permite-lhe controlar as solicitações e reclamações dos seus "
"clientes / fornecedores.\n"
"\n"
"É totalmente integrado com o gateway de e-mail para que você possa criar\n"
"novos pedidos automaticamente baseados em e-mails recebidos.\n"
" "
#. module: base
#: selection:ir.module.module,license:0
@ -13551,6 +13582,9 @@ msgid ""
"128x128px image, with aspect ratio preserved. Use this field in form views "
"or some kanban views."
msgstr ""
"Imagem média deste contato. Ela é automaticamente redimensionada como uma "
"imagem de 128x128px, mantendo o aspecto original. Utilize este campo em "
"visões de formulário ou algumas visões de kanban."
#. module: base
#: view:base.update.translations:0
@ -13826,12 +13860,12 @@ msgstr "Espanha - Contabilidade(PGCE 2008)"
#. module: base
#: model:ir.module.module,shortdesc:base.module_stock_no_autopicking
msgid "Picking Before Manufacturing"
msgstr ""
msgstr "Separação antes da Produção"
#. module: base
#: model:ir.module.module,summary:base.module_note_pad
msgid "Sticky memos, Collaborative"
msgstr ""
msgstr "Notas Colaborativas (post it)"
#. module: base
#: model:res.country,name:base.wf
@ -14095,6 +14129,10 @@ msgid ""
"your home page.\n"
"You can track your suppliers, customers and other contacts.\n"
msgstr ""
"\n"
"Este módulo oferece uma visão rápida da sua agenda de endereços, acessível a "
"partir de sua página inicial.\n"
"Você pode acompanhar os seus fornecedores, clientes e outros contatos.\n"
#. module: base
#: help:res.company,custom_footer:0
@ -14548,7 +14586,7 @@ msgstr "Prospectos & Oportunidades"
#. module: base
#: model:res.country,name:base.gg
msgid "Guernsey"
msgstr ""
msgstr "Guernsey"
#. module: base
#: selection:base.language.install,lang:0
@ -15070,7 +15108,7 @@ msgstr "Relatórios Avançados"
#. module: base
#: model:ir.module.module,summary:base.module_purchase
msgid "Purchase Orders, Receptions, Supplier Invoices"
msgstr ""
msgstr "Pedidos de Compra, Recepções, Faturas de Fornecedores"
#. module: base
#: model:ir.module.module,description:base.module_hr_payroll
@ -15275,7 +15313,7 @@ msgstr "Módulos Genéricos"
#. module: base
#: model:res.country,name:base.mk
msgid "Macedonia, the former Yugoslav Republic of"
msgstr ""
msgstr "Macedônia"
#. module: base
#: model:res.country,name:base.rw
@ -15412,7 +15450,7 @@ msgstr "Holanda - Contabilidade"
#. module: base
#: model:res.country,name:base.gs
msgid "South Georgia and the South Sandwich Islands"
msgstr ""
msgstr "Geórgia do Sul e Ilhas Sandwich do Sul"
#. module: base
#: view:res.lang:0
@ -15709,6 +15747,8 @@ msgid ""
"Tax Identification Number. Check the box if this contact is subjected to "
"taxes. Used by the some of the legal statements."
msgstr ""
"Número de Identificação Fiscal. Marque a caixa se este contato está sujeito "
"a impostos. Usado pela algumas das declarações legais."
#. module: base
#: field:res.partner.bank,partner_id:0
@ -15885,6 +15925,16 @@ msgid ""
" </p>\n"
" "
msgstr ""
"<p class=\"oe_view_nocontent_create\">\n"
" Clique para adicionar um contato em sua agenda de "
"endereços.\n"
" </p><p>\n"
" O OpenERP auxilia a rastrear todas as atividades "
"relacionadas a\n"
" um cliente; debates, histórico de oportunidades\n"
" de negócios, documentos, etc.\n"
" </p>\n"
" "
#. module: base
#: model:res.partner.category,name:base.res_partner_category_2

View File

@ -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: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-08-20 15:27+0000\n"
"Last-Translator: Dorin <dhongu@gmail.com>\n"
"PO-Revision-Date: 2012-12-16 18:26+0000\n"
"Last-Translator: Fekete Mihai <mihai@erpsystems.ro>\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: 2012-12-04 04:59+0000\n"
"X-Generator: Launchpad (build 16335)\n"
"X-Launchpad-Export-Date: 2012-12-17 04:44+0000\n"
"X-Generator: Launchpad (build 16372)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@ -24,6 +24,10 @@ msgid ""
"================================================\n"
" "
msgstr ""
"\n"
"Modul pentru Verifica Scrisul si Verifica Imprimarea.\n"
"================================================\n"
" "
#. module: base
#: model:res.country,name:base.sh
@ -59,7 +63,7 @@ msgstr "Alcatuirea vizualizarii"
#. module: base
#: model:ir.module.module,summary:base.module_sale_stock
msgid "Quotation, Sale Orders, Delivery & Invoicing Control"
msgstr ""
msgstr "Cotatie, Ordine de vanzari, Controlul Livrarii & Facturarii"
#. module: base
#: selection:ir.sequence,implementation:0
@ -88,25 +92,25 @@ msgstr ""
#. module: base
#: model:ir.module.module,summary:base.module_point_of_sale
msgid "Touchscreen Interface for Shops"
msgstr ""
msgstr "Interfata cu Ecran tactil pentru Magazine"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll
msgid "Indian Payroll"
msgstr ""
msgstr "Stat de plata indian"
#. module: base
#: help:ir.cron,model:0
msgid ""
"Model name on which the method to be called is located, e.g. 'res.partner'."
msgstr ""
"Numele modelului unde este localizata metoda care urmeaza a fi efectuata, de "
"exemplu 'res.partener'."
"Numele modelului unde este localizata metoda care va fi numita, de exemplu "
"'res.partener'."
#. module: base
#: view:ir.module.module:0
msgid "Created Views"
msgstr "Afisari Create"
msgstr "Vizualizari Create"
#. module: base
#: model:ir.module.module,description:base.module_product_manufacturer
@ -123,6 +127,17 @@ msgid ""
" * Product Attributes\n"
" "
msgstr ""
"\n"
"Un modul care adauga producatori si atribute la formularul produsului.\n"
"====================================================================\n"
"\n"
"Acum puteti defini urmatoarele pentru un produs:\n"
"-----------------------------------------------\n"
" * Producator\n"
" * Numele Producatorului Produsului\n"
" * Codul Producatorului Produsului\n"
" * Atributele Produsului\n"
" "
#. module: base
#: field:ir.actions.client,params:0
@ -136,11 +151,14 @@ msgid ""
"The module adds google user in res user.\n"
"========================================\n"
msgstr ""
"\n"
"Acest modul adauga utilizatorul google la utilizatorul res.\n"
"========================================\n"
#. module: base
#: help:res.partner,employee:0
msgid "Check this box if this contact is an Employee."
msgstr ""
msgstr "Bifati aceasta casuta daca acest contact este un Angajat."
#. module: base
#: help:ir.model.fields,domain:0

File diff suppressed because it is too large Load Diff

View File

@ -671,7 +671,7 @@ class actions_server(osv.osv):
context['object'] = obj
for i in expr:
context['active_id'] = i.id
result = self.run(cr, uid, [action.loop_action.id], context)
self.run(cr, uid, [action.loop_action.id], context)
if action.state == 'object_write':
res = {}
@ -716,8 +716,6 @@ class actions_server(osv.osv):
expr = exp.value
res[exp.col1.name] = expr
obj_pool = None
res_id = False
obj_pool = self.pool.get(action.srcmodel_id.model)
res_id = obj_pool.create(cr, uid, res)
if action.record_id:
@ -736,7 +734,7 @@ class actions_server(osv.osv):
model = action.copy_object.split(',')[0]
cid = action.copy_object.split(',')[1]
obj_pool = self.pool.get(model)
res_id = obj_pool.copy(cr, uid, int(cid), res)
obj_pool.copy(cr, uid, int(cid), res)
return False

View File

@ -231,7 +231,7 @@ class ir_cron(osv.osv):
_logger.warning('Tried to poll an undefined table on database %s.', db_name)
else:
raise
except Exception, ex:
except Exception:
_logger.warning('Exception in cron:', exc_info=True)
finally:

View File

@ -24,9 +24,6 @@ from osv import osv, fields
from tools.translate import _
class ir_filters(osv.osv):
'''
Filters
'''
_name = 'ir.filters'
_description = 'Filters'

View File

@ -228,7 +228,7 @@ class ir_mail_server(osv.osv):
: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 string encryption: optional, ``'ssl'`` | ``'starttls'``
:param bool smtp_debug: toggle debugging of SMTP sessions (all i/o
will be output in logs)
"""

View File

@ -158,9 +158,10 @@ class ir_model(osv.osv):
if context is None: context = {}
if isinstance(ids, (int, long)):
ids = [ids]
if not context.get(MODULE_UNINSTALL_FLAG) and \
any(model.state != 'manual' for model in self.browse(cr, user, ids, context)):
raise except_orm(_('Error'), _("Model '%s' contains module data and cannot be removed!") % (model.name,))
if not context.get(MODULE_UNINSTALL_FLAG):
for model in self.browse(cr, user, ids, context):
if model.state != 'manual':
raise except_orm(_('Error'), _("Model '%s' contains module data and cannot be removed!") % (model.name,))
self._drop_table(cr, user, ids, context)
res = super(ir_model, self).unlink(cr, user, ids, context)
@ -256,7 +257,7 @@ class ir_model_fields(osv.osv):
'selection': "",
'domain': "[]",
'name': 'x_',
'state': lambda self,cr,uid,ctx={}: (ctx and ctx.get('manual',False)) and 'manual' or 'base',
'state': lambda self,cr,uid,ctx=None: (ctx and ctx.get('manual',False)) and 'manual' or 'base',
'on_delete': 'set null',
'select_level': '0',
'size': 64,
@ -271,7 +272,7 @@ class ir_model_fields(osv.osv):
except Exception:
_logger.warning('Invalid selection list definition for fields.selection', exc_info=True)
raise except_orm(_('Error'),
_("The Selection Options expression is not a valid Pythonic expression." \
_("The Selection Options expression is not a valid Pythonic expression."
"Please provide an expression in the [('key','Label'), ...] format."))
check = True
@ -514,7 +515,7 @@ class ir_model_constraint(Model):
# double-check we are really going to delete all the owners of this schema element
cr.execute("""SELECT id from ir_model_constraint where name=%s""", (data.name,))
external_ids = [x[0] for x in cr.fetchall()]
if (set(external_ids)-ids_set):
if set(external_ids)-ids_set:
# as installed modules have defined this element we must not delete it!
continue
@ -567,13 +568,12 @@ class ir_model_relation(Model):
ids.reverse()
for data in self.browse(cr, uid, ids, context):
model = data.model
model_obj = self.pool.get(model)
name = openerp.tools.ustr(data.name)
# double-check we are really going to delete all the owners of this schema element
cr.execute("""SELECT id from ir_model_relation where name = %s""", (data.name,))
external_ids = [x[0] for x in cr.fetchall()]
if (set(external_ids)-ids_set):
if set(external_ids)-ids_set:
# as installed modules have defined this element we must not delete it!
continue
@ -585,7 +585,7 @@ class ir_model_relation(Model):
# drop m2m relation tables
for table in to_drop_table:
cr.execute('DROP TABLE %s CASCADE'% (table),)
cr.execute('DROP TABLE %s CASCADE'% table,)
_logger.info('Dropped table %s', table)
cr.commit()
@ -862,7 +862,7 @@ class ir_model_data(osv.osv):
res = self.read(cr, uid, data_id, ['model', 'res_id'])
if not res['res_id']:
raise ValueError('No such external ID currently defined in the system: %s.%s' % (module, xml_id))
return (res['model'], res['res_id'])
return res['model'], res['res_id']
def get_object(self, cr, uid, module, xml_id, context=None):
"""Returns a browsable record for the given module name and xml_id or raise ValueError if not found"""
@ -903,7 +903,7 @@ class ir_model_data(osv.osv):
# records created during module install should not display the messages of OpenChatter
context = dict(context, install_mode=True)
if xml_id and ('.' in xml_id):
assert len(xml_id.split('.'))==2, _("'%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") % (xml_id)
assert len(xml_id.split('.'))==2, _("'%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") % xml_id
module, xml_id = xml_id.split('.')
if (not xml_id) and (not self.doinit):
return False
@ -1073,7 +1073,6 @@ class ir_model_data(osv.osv):
if model == 'ir.model.fields')
ir_model_relation = self.pool.get('ir.model.relation')
relation_ids = ir_model_relation.search(cr, uid, [('module', 'in', modules_to_remove)])
ir_module_module = self.pool.get('ir.module.module')
modules_to_remove_ids = ir_module_module.search(cr, uid, [('name', 'in', modules_to_remove)])
relation_ids = ir_model_relation.search(cr, uid, [('module', 'in', modules_to_remove_ids)])

View File

@ -246,8 +246,8 @@
<tree string="External Identifiers">
<field name="complete_name"/>
<field name="display_name"/>
<field name="res_id"/>
<field name="model" groups="base.group_no_one"/>
<field name="res_id"/>
</tree>
</field>
</record>
@ -255,12 +255,10 @@
<field name="model">ir.model.data</field>
<field name="arch" type="xml">
<search string="External Identifiers">
<field name="name"
filter_domain="['|', '|', ('name','ilike',self), ('model','ilike',self), ('module','ilike',self)]"
string="External Identifier"/>
<filter icon="terp-camera_test"
string="Updatable"
domain="[('noupdate', '=', False)]"/>
<field name="name" filter_domain="[('name','ilike',self)]" string="External Identifier"/>
<filter string="Updatable" domain="[('noupdate', '=', False)]"/>
<field name="module"/>
<field name="model"/>
<field name="res_id"/>
<field name="noupdate"/>
<group expand="0" string="Group By...">

View File

@ -23,7 +23,7 @@ from osv import osv
class ir_needaction_mixin(osv.AbstractModel):
'''Mixin class for objects using the need action feature.
"""Mixin class for objects using the need action feature.
Need action feature can be used by models that have to be able to
signal that an action is required on a particular record. If in
@ -37,7 +37,7 @@ class ir_needaction_mixin(osv.AbstractModel):
This class also offers several global services:
- ``_needaction_count``: returns the number of actions uid has to perform
'''
"""
_name = 'ir.needaction_mixin'
_needaction = True
@ -56,7 +56,7 @@ class ir_needaction_mixin(osv.AbstractModel):
# "Need action" API
#------------------------------------------------------
def _needaction_count(self, cr, uid, domain=[], context=None):
def _needaction_count(self, cr, uid, domain=None, context=None):
""" Get the number of actions uid has to perform. """
dom = self._needaction_domain_get(cr, uid, context=context)
if not dom:

View File

@ -140,7 +140,7 @@ class ir_sequence(openerp.osv.osv.osv):
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'])
self._create_sequence(cr, values['id'], values['number_increment'], values['number_next'])
return values['id']
def unlink(self, cr, uid, ids, context=None):

View File

@ -134,7 +134,7 @@ class ir_translation_import_cursor(object):
""" % (self._parent_table, self._table_name, self._parent_table, find_expr))
if self._debug:
cr.execute('SELECT COUNT(*) FROM ONLY %s' % (self._parent_table))
cr.execute('SELECT COUNT(*) FROM ONLY %s' % self._parent_table)
c1 = cr.fetchone()[0]
cr.execute('SELECT COUNT(*) FROM ONLY %s AS irt, %s AS ti WHERE %s' % \
(self._parent_table, self._table_name, find_expr))
@ -217,11 +217,11 @@ class ir_translation(osv.osv):
def _get_ids(self, cr, uid, name, tt, lang, ids):
translations = dict.fromkeys(ids, False)
if ids:
cr.execute('select res_id,value ' \
'from ir_translation ' \
'where lang=%s ' \
'and type=%s ' \
'and name=%s ' \
cr.execute('select res_id,value '
'from ir_translation '
'where lang=%s '
'and type=%s '
'and name=%s '
'and res_id IN %s',
(lang,tt,name,tuple(ids)))
for res_id, value in cr.fetchall():
@ -237,10 +237,10 @@ class ir_translation(osv.osv):
self._get_ids.clear_cache(self, uid, name, tt, lang, res_id)
self._get_source.clear_cache(self, uid, name, tt, lang)
cr.execute('delete from ir_translation ' \
'where lang=%s ' \
'and type=%s ' \
'and name=%s ' \
cr.execute('delete from ir_translation '
'where lang=%s '
'and type=%s '
'and name=%s '
'and res_id IN %s',
(lang,tt,name,tuple(ids),))
for id in ids:

View File

@ -44,9 +44,8 @@ class ir_ui_menu(osv.osv):
def __init__(self, *args, **kwargs):
self.cache_lock = threading.RLock()
self._cache = {}
r = super(ir_ui_menu, self).__init__(*args, **kwargs)
super(ir_ui_menu, self).__init__(*args, **kwargs)
self.pool.get('ir.model.access').register_cache_clearing_method(self._name, 'clear_cache')
return r
def clear_cache(self):
with self.cache_lock:
@ -66,7 +65,7 @@ class ir_ui_menu(osv.osv):
modelaccess = self.pool.get('ir.model.access')
user_groups = set(self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['groups_id'])['groups_id'])
result = []
for menu in self.browse(cr, SUPERUSER_ID, ids, context=context):
for menu in self.browse(cr, uid, ids, context=context):
# this key works because user access rights are all based on user's groups (cfr ir_model_access.check)
key = (cr.dbname, menu.id, tuple(user_groups))
if key in self._cache:
@ -144,7 +143,7 @@ class ir_ui_menu(osv.osv):
return res
def _get_full_name(self, cr, uid, ids, name=None, args=None, context=None):
if context == None:
if context is None:
context = {}
res = {}
for elmt in self.browse(cr, uid, ids, context=context):
@ -168,9 +167,22 @@ class ir_ui_menu(osv.osv):
self.clear_cache()
return super(ir_ui_menu, self).write(*args, **kwargs)
def unlink(self, *args, **kwargs):
def unlink(self, cr, uid, ids, context=None):
# Detach children and promote them to top-level, because it would be unwise to
# cascade-delete submenus blindly. We also can't use ondelete=set null because
# that is not supported when _parent_store is used (would silently corrupt it).
# TODO: ideally we should move them under a generic "Orphans" menu somewhere?
if isinstance(ids, (int, long)):
ids = [ids]
local_context = dict(context or {})
local_context['ir.ui.menu.full_list'] = True
direct_children_ids = self.search(cr, uid, [('parent_id', 'in', ids)], context=local_context)
if direct_children_ids:
self.write(cr, uid, direct_children_ids, {'parent_id': False})
result = super(ir_ui_menu, self).unlink(cr, uid, ids, context=context)
self.clear_cache()
return super(ir_ui_menu, self).unlink(*args, **kwargs)
return result
def copy(self, cr, uid, id, default=None, context=None):
ir_values_obj = self.pool.get('ir.values')
@ -182,7 +194,7 @@ class ir_ui_menu(osv.osv):
next_num=int(concat[0])+1
datas['name']=rex.sub(('(%d)'%next_num),datas['name'])
else:
datas['name']=datas['name']+'(1)'
datas['name'] += '(1)'
self.write(cr,uid,[res],{'name':datas['name']})
ids = ir_values_obj.search(cr, uid, [
('model', '=', 'ir.ui.menu'),
@ -307,7 +319,9 @@ class ir_ui_menu(osv.osv):
'name': fields.char('Menu', size=64, required=True, translate=True),
'sequence': fields.integer('Sequence'),
'child_id': fields.one2many('ir.ui.menu', 'parent_id', 'Child IDs'),
'parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', select=True),
'parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', select=True, ondelete="restrict"),
'parent_left': fields.integer('Parent Left', select=True),
'parent_right': fields.integer('Parent Right', select=True),
'groups_id': fields.many2many('res.groups', 'ir_ui_menu_group_rel',
'menu_id', 'gid', 'Groups', help="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."),
@ -348,5 +362,6 @@ class ir_ui_menu(osv.osv):
'sequence': 10,
}
_order = "sequence,id"
_parent_store = True
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -254,7 +254,7 @@ class view(osv.osv):
if label:
for lbl in eval(label):
if t.has_key(tools.ustr(lbl)) and tools.ustr(t[lbl])=='False':
label_string = label_string + ' '
label_string += ' '
else:
label_string = label_string + " " + tools.ustr(t[lbl])
labels[str(t['id'])] = (a['id'],label_string)

View File

@ -307,10 +307,10 @@ class ir_values(osv.osv):
ORDER BY v.user_id, u.company_id"""
params = ('default', model, uid, uid)
if condition:
query = query % 'AND v.key2 = %s'
query %= 'AND v.key2 = %s'
params += (condition[:200],)
else:
query = query % 'AND v.key2 is NULL'
query %= 'AND v.key2 is NULL'
cr.execute(query, params)
# keep only the highest priority default for each field
@ -417,7 +417,7 @@ class ir_values(osv.osv):
continue
# keep only the first action registered for each action name
results[action['name']] = (action['id'], action['name'], action_def)
except except_orm, e:
except except_orm:
continue
return sorted(results.values())

View File

@ -77,8 +77,10 @@ def graph_get(cr, graph, wkf_ids, nested, workitem, processed_subflows):
for t in transitions:
if not t['act_to'] in activities:
continue
args = {}
args['label'] = str(t['condition']).replace(' or ', '\\nor ').replace(' and ', '\\nand ')
args = {
'label': str(t['condition']).replace(' or ', '\\nor ')
.replace(' and ','\\nand ')
}
if t['signal']:
args['label'] += '\\n'+str(t['signal'])
args['style'] = 'bold'
@ -94,20 +96,19 @@ def graph_get(cr, graph, wkf_ids, nested, workitem, processed_subflows):
activity_from = actfrom[t['act_from']][1].get(t['signal'], actfrom[t['act_from']][0])
activity_to = actto[t['act_to']][1].get(t['signal'], actto[t['act_to']][0])
graph.add_edge(pydot.Edge( str(activity_from) ,str(activity_to), fontsize='10', **args))
nodes = cr.dictfetchall()
cr.execute('select * from wkf_activity where flow_start=True and wkf_id in ('+','.join(['%s']*len(wkf_ids))+')', wkf_ids)
start = cr.fetchone()[0]
cr.execute("select 'subflow.'||name,id from wkf_activity where flow_stop=True and wkf_id in ("+','.join(['%s']*len(wkf_ids))+')', wkf_ids)
stop = cr.fetchall()
if (stop):
if stop:
stop = (stop[0][1], dict(stop))
else:
stop = ("stop",{})
return ((start,{}),stop)
return (start, {}), stop
def graph_instance_get(cr, graph, inst_id, nested=False):
workitems = {}
cr.execute('select wkf_id from wkf_instance where id=%s', (inst_id,))
inst = cr.fetchall()
@ -169,7 +170,7 @@ showpage'''
inst_id = inst_id[0]
graph_instance_get(cr, graph, inst_id, data.get('nested', False))
ps_string = graph.create(prog='dot', format='ps')
except Exception, e:
except Exception:
_logger.exception('Exception in call:')
# string is in PS, like the success message would have been
ps_string = '''%PS-Adobe-3.0
@ -206,13 +207,13 @@ class report_graph(report.interface.report_int):
def result(self):
if self.obj.is_done():
return (True, self.obj.get(), 'pdf')
return True, self.obj.get(), 'pdf'
else:
return (False, False, False)
return False, False, False
def create(self, cr, uid, ids, data, context=None):
self.obj = report_graph_instance(cr, uid, ids, data)
return (self.obj.get(), 'pdf')
return self.obj.get(), 'pdf'
report_graph('report.workflow.instance.graph', 'ir.workflow')

View File

@ -3,16 +3,16 @@
<template pageSize="(595.0,842.0)" title="Test" author="Martin Simon" allowSplitting="20">
<pageTemplate id="first">
<frame id="first" x1="42.0" y1="42.0" width="511" height="758"/>
<header>
<pageGraphics>
<setFont name="Helvetica-Bold" size="9"/>
<drawString x="1.0cm" y="28.1cm">[[ company.name ]]</drawString>
<drawRightString x="20cm" y="28.1cm"> Reference Guide </drawRightString>
<lineMode width="0.7"/>
<stroke color="black"/>
<lines>1cm 28cm 20cm 28cm</lines>
</pageGraphics>
</header>
<header>
<pageGraphics>
<setFont name="Helvetica-Bold" size="9"/>
<drawString x="1.0cm" y="28.1cm">[[ company.name ]]</drawString>
<drawRightString x="20cm" y="28.1cm"> Reference Guide </drawRightString>
<lineMode width="0.7"/>
<stroke color="black"/>
<lines>1cm 28cm 20cm 28cm</lines>
</pageGraphics>
</header>
</pageTemplate>
</template>
@ -236,7 +236,7 @@
<tr>
<td>
<para style="terp_default_9">[[ repeatIn(objdoc2(object.model) or [], 'sline') ]]</para>
<para style="terp_default_9"> [[ sline ]] </para>
<para style="terp_default_9"> [[ sline ]] </para>
</td>
</tr>
</blockTable>

View File

@ -1,75 +0,0 @@
# -*- 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 glob
import imp
import tools
import zipfile
from osv import osv
class base_module_scan(osv.osv_memory):
""" scan module """
_name = "base.module.scan"
_description = "scan module"
def watch_dir(self, cr, uid, ids, context):
mod_obj = self.pool.get('ir.module.module')
all_mods = mod_obj.read(cr, uid, mod_obj.search(cr, uid, []), ['name', 'state'])
known_modules = [x['name'] for x in all_mods]
ls_ad = glob.glob(os.path.join(tools.config['addons_path'], '*', '__terp__.py'))
modules = [module_name_re.match(name).group(1) for name in ls_ad]
for fname in os.listdir(tools.config['addons_path']):
if zipfile.is_zipfile(fname):
modules.append( fname.split('.')[0])
for module in modules:
if module in known_modules:
continue
terp = mod_obj.get_module_info(module)
if not terp.get('installable', True):
continue
# XXX check if this code is correct...
fm = imp.find_module(module)
try:
imp.load_module(module, *fm)
finally:
if fm[0]:
fm[0].close()
values = mod_obj.get_values_from_terp(terp)
mod_id = mod_obj.create(cr, uid, dict(name=module, state='uninstalled', **values))
dependencies = terp.get('depends', [])
for d in dependencies:
cr.execute('insert into ir_module_module_dependency (module_id,name) values (%s, %s)', (mod_id, d))
for module in known_modules:
terp = mod_obj.get_module_info(module)
if terp.get('installable', True):
for mod in all_mods:
if mod['name'] == module and mod['state'] == 'uninstallable':
mod_obj.write(cr, uid, [mod['id']], {'state': 'uninstalled'})
return {}
base_module_scan()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_base_module_scan" model="ir.ui.view">
<field name="name">Module Scan</field>
<field name="model">base.module.scan</field>
<field name="arch" type="xml">
<form string="Scan for new modules" version="7.0">
<label string="This function will check if you installed new modules in the 'addons' path of your server installation."/>
<footer>
<button name="watch_dir" string="Check new modules" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_view_base_module_scan" model="ir.actions.act_window">
<field name="name">Module Scan</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">base.module.scan</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -18,13 +18,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv
from osv import fields
import os
import tools
import openerp
from openerp import SUPERUSER_ID
from openerp.osv import osv, fields
from openerp import tools
from openerp.tools import image_resize_image
from tools.translate import _
from tools.safe_eval import safe_eval as eval
@ -102,6 +102,16 @@ class res_company(osv.osv):
part_obj.create(cr, uid, {name: value or False, 'parent_id': company.partner_id.id}, context=context)
return True
def _get_logo_web(self, cr, uid, ids, _field_name, _args, context=None):
result = dict.fromkeys(ids, False)
for record in self.browse(cr, uid, ids, context=context):
size = (180, None)
result[record.id] = image_resize_image(record.partner_id.image, size)
return result
def _get_companies_from_partner(self, cr, uid, ids, context=None):
return self.pool['res.company'].search(cr, uid, [('partner_id', 'in', ids)], context=context)
_columns = {
'name': fields.related('partner_id', 'name', string='Company Name', size=128, required=True, store=True, type='char'),
'parent_id': fields.many2one('res.company', 'Parent Company', select=True),
@ -115,6 +125,10 @@ class res_company(osv.osv):
'rml_footer_readonly': fields.related('rml_footer', type='text', string='Report Footer', readonly=True),
'custom_footer': fields.boolean('Custom Footer', help="Check this to define the report footer manually. Otherwise it will be filled in automatically."),
'logo': fields.related('partner_id', 'image', string="Logo", type="binary"),
'logo_web': fields.function(_get_logo_web, string="Logo Web", type="binary", store={
'res.company': (lambda s, c, u, i, x: i, ['partner_id'], 10),
'res.partner': (_get_companies_from_partner, ['image'], 10),
}),
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
'currency_ids': fields.one2many('res.currency', 'company_id', 'Currency'),
'user_ids': fields.many2many('res.users', 'res_company_users_rel', 'cid', 'user_id', 'Accepted Users'),
@ -352,7 +366,4 @@ class res_company(osv.osv):
]
res_company()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -21,10 +21,10 @@
<form string="Company" version="7.0">
<sheet>
<div>
<field name="logo" nolabel="1" widget="image" class="oe_avatar oe_left"/>
<field name="logo" widget="image" class="oe_avatar oe_left"/>
</div>
<div class="oe_right oe_button_box" name="button_box">
<button name="%(preview_report)d" string="Preview Header/Footer" type="action" icon="gtk-print" class="oe_inline oe_right"/>
<button name="%(preview_report)d" string="Preview Header/Footer" type="action"/>
</div>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>

View File

@ -309,7 +309,7 @@ class res_config_installer(osv.osv_memory):
hooks_results = set()
for module in base:
hook = getattr(self, '_if_%s'%(module), None)
hook = getattr(self, '_if_%s'% module, None)
if hook:
hooks_results.update(hook(cr, uid, ids, context=None) or set())

View File

@ -1186,7 +1186,7 @@
<record id="us" model="res.country">
<field name="name">United States</field>
<field name="code">us</field>
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s'" />
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(city)s, %(state_code)s %(zip)s\n%(country_name)s'" />
<field name="currency_id" ref="USD"/>
</record>
<record id="uy" model="res.country">

View File

@ -99,7 +99,7 @@ class res_currency(osv.osv):
res = super(res_currency, self).read(cr, user, ids, fields, context, load)
currency_rate_obj = self.pool.get('res.currency.rate')
values = res
if not isinstance(values, (list)):
if not isinstance(values, list):
values = [values]
for r in values:
if r.__contains__('rate_ids'):
@ -217,7 +217,7 @@ class res_currency(osv.osv):
if round:
return self.round(cr, uid, to_currency, from_amount * rate)
else:
return (from_amount * rate)
return from_amount * rate
res_currency()

View File

@ -168,7 +168,7 @@ class lang(osv.osv):
thousands_sep = lang_obj.thousands_sep or conv[monetary and 'mon_thousands_sep' or 'thousands_sep']
decimal_point = lang_obj.decimal_point
grouping = lang_obj.grouping
return (grouping, thousands_sep, decimal_point)
return grouping, thousands_sep, decimal_point
def write(self, cr, uid, ids, vals, context=None):
for lang_id in ids :
@ -231,7 +231,7 @@ lang()
def original_group(s, grouping, thousands_sep=''):
if not grouping:
return (s, 0)
return s, 0
result = ""
seps = 0

View File

@ -220,10 +220,6 @@ class res_partner(osv.osv, format_address):
'bank_ids': fields.one2many('res.partner.bank', 'partner_id', 'Banks'),
'website': fields.char('Website', size=64, help="Website of Partner or Company"),
'comment': fields.text('Notes'),
'address': fields.one2many('res.partner.address', 'partner_id', 'Addresses',
deprecated="The address information is now directly stored on each Partner record. "\
"Multiple contacts with their own address can be added via the child_ids relationship. "\
"This field will be removed as of OpenERP 7.1."),
'category_id': fields.many2many('res.partner.category', id1='partner_id', id2='category_id', string='Tags'),
'credit_limit': fields.float(string='Credit Limit'),
'ean13': fields.char('EAN13', size=13),
@ -321,7 +317,7 @@ class res_partner(osv.osv, format_address):
if default is None:
default = {}
name = self.read(cr, uid, [id], ['name'], context)[0]['name']
default.update({'name': _('%s (copy)') % (name)})
default.update({'name': _('%s (copy)') % name})
return super(res_partner, self).copy(cr, uid, id, default, context)
def onchange_type(self, cr, uid, ids, is_company, context=None):
@ -531,7 +527,7 @@ class res_partner(osv.osv, format_address):
def view_header_get(self, cr, uid, view_id, view_type, context):
res = super(res_partner, self).view_header_get(cr, uid, view_id, view_type, context)
if res: return res
if (not context.get('category_id', False)):
if not context.get('category_id', False):
return False
return _('Partners: ')+self.pool.get('res.partner.category').browse(cr, uid, context['category_id'], context).name
@ -550,7 +546,7 @@ class res_partner(osv.osv, format_address):
The purpose of this function is to build and return an address formatted accordingly to the
standards of the country where it belongs.
:param address: browse record of the res.partner.address to format
:param address: browse record of the res.partner to format
:returns: the address formatted in a display that fit its country habits (or the default ones
if not country is specified)
:rtype: string
@ -576,55 +572,4 @@ class res_partner(osv.osv, format_address):
address_format = '%(company_name)s\n' + address_format
return address_format % args
# res.partner.address is deprecated; it is still there for backward compability only and will be removed in next version
class res_partner_address(osv.osv):
_table = "res_partner"
_name = 'res.partner.address'
_order = 'type, name'
_columns = {
'parent_id': fields.many2one('res.partner', 'Company', ondelete='set null', select=True),
'partner_id': fields.related('parent_id', type='many2one', relation='res.partner', string='Partner'), # for backward compatibility
'type': fields.selection( [ ('default','Default'),('invoice','Invoice'), ('delivery','Delivery'), ('contact','Contact'), ('other','Other') ],'Address Type', help="Used to select automatically the right address according to the context in sales and purchases documents."),
'function': fields.char('Function', size=128),
'title': fields.many2one('res.partner.title','Title'),
'name': fields.char('Contact Name', size=64, select=1),
'street': fields.char('Street', size=128),
'street2': fields.char('Street2', size=128),
'zip': fields.char('Zip', change_default=True, size=24),
'city': fields.char('City', size=128),
'state_id': fields.many2one("res.country.state", 'Fed. State', domain="[('country_id','=',country_id)]"),
'country_id': fields.many2one('res.country', 'Country'),
'email': fields.char('Email', size=240),
'phone': fields.char('Phone', size=64),
'fax': fields.char('Fax', size=64),
'mobile': fields.char('Mobile', size=64),
'birthdate': fields.char('Birthdate', size=64),
'is_customer_add': fields.related('partner_id', 'customer', type='boolean', string='Customer'),
'is_supplier_add': fields.related('partner_id', 'supplier', type='boolean', string='Supplier'),
'active': fields.boolean('Active', help="Uncheck the active field to hide the contact."),
'company_id': fields.many2one('res.company', 'Company',select=1),
'color': fields.integer('Color Index'),
}
_defaults = {
'active': True,
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner', context=c),
'color': 0,
'type': 'default',
}
def write(self, cr, uid, ids, vals, context=None):
logging.getLogger('res.partner').warning("Deprecated use of res.partner.address")
if 'partner_id' in vals:
vals['parent_id'] = vals.get('partner_id')
del(vals['partner_id'])
return self.pool.get('res.partner').write(cr, uid, ids, vals, context=context)
def create(self, cr, uid, vals, context=None):
logging.getLogger('res.partner').warning("Deprecated use of res.partner.address")
if 'partner_id' in vals:
vals['parent_id'] = vals.get('partner_id')
del(vals['partner_id'])
return self.pool.get('res.partner').create(cr, uid, vals, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -58,7 +58,7 @@ class res_request(osv.osv):
ids = map(lambda x:x[0], cr.fetchall())
cr.execute('select id from res_request where act_from=%s and (act_to<>%s) and (trigger_date<=%s or trigger_date is null) and active=True and state != %s', (uid,uid,time.strftime('%Y-%m-%d'), 'closed'))
ids2 = map(lambda x:x[0], cr.fetchall())
return (ids, ids2)
return ids, ids2
_columns = {
'create_date': fields.datetime('Created Date', readonly=True),

View File

@ -142,7 +142,7 @@ class res_users(osv.osv):
'id': fields.integer('ID'),
'login_date': fields.date('Latest connection', select=1),
'partner_id': fields.many2one('res.partner', required=True,
string='Related Partner', ondelete='cascade',
string='Related Partner', ondelete='restrict',
help='Partner-related data of the user'),
'login': fields.char('Login', size=64, required=True,
help="Used to log into the system"),
@ -253,7 +253,7 @@ class res_users(osv.osv):
# User can write on a few of his own fields (but not his groups for example)
SELF_WRITEABLE_FIELDS = ['password', 'signature', 'action_id', 'company_id', 'email', 'name', 'image', 'image_medium', 'image_small', 'lang', 'tz']
# User can read a few of his own fields
SELF_READABLE_FIELDS = ['signature', 'company_id', 'login', 'email', 'name', 'image', 'image_medium', 'image_small', 'lang', 'tz', 'groups_id', 'partner_id', '__last_update']
SELF_READABLE_FIELDS = ['signature', 'company_id', 'login', 'email', 'name', 'image', 'image_medium', 'image_small', 'lang', 'tz', 'tz_offset', 'groups_id', 'partner_id', '__last_update']
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
def override_password(o):
@ -303,6 +303,7 @@ class res_users(osv.osv):
for id in ids:
if id in self._uid_cache[db]:
del self._uid_cache[db][id]
self.context_get.clear_cache(self, cr)
return res
@ -337,6 +338,7 @@ class res_users(osv.osv):
default['login'] = _("%s (copy)") % user2copy['login']
return super(res_users, self).copy(cr, uid, id, default, context)
@tools.ormcache(skiparg=2)
def context_get(self, cr, uid, context=None):
user = self.browse(cr, SUPERUSER_ID, uid, context)
result = {}

View File

@ -1,4 +0,0 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_res_partner_address_group_partner_manager","res_partner_address group_partner_manager","model_res_partner_address","group_partner_manager",1,1,1,1
"access_res_partner_address_group_user","res_partner_address group_user","model_res_partner_address","group_user",1,0,0,0
"access_res_partner_address","res.partner.address","model_res_partner_address","group_system",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_res_partner_address_group_partner_manager res_partner_address group_partner_manager model_res_partner_address group_partner_manager 1 1 1 1
3 access_res_partner_address_group_user res_partner_address group_user model_res_partner_address group_user 1 0 0 0
4 access_res_partner_address res.partner.address model_res_partner_address group_system 1 1 1 1

View File

@ -1,8 +1,9 @@
import test_base, test_expression, test_search, test_ir_values
import test_base, test_expression, test_search, test_ir_values, test_menu
checks = [
test_base,
test_expression,
test_search,
test_ir_values,
test_menu,
]

View File

@ -0,0 +1,34 @@
import unittest2
import openerp.tests.common as common
class test_menu(common.TransactionCase):
def setUp(self):
super(test_menu,self).setUp()
self.Menus = self.registry('ir.ui.menu')
def test_00_menu_deletion(self):
"""Verify that menu deletion works properly when there are child menus, and those
are indeed made orphans"""
cr, uid, Menus = self.cr, self.uid, self.Menus
# Generic trick necessary for search() calls to avoid hidden menus
ctx = {'ir.ui.menu.full_list': True}
root_id = Menus.create(cr, uid, {'name': 'Test root'})
child1_id = Menus.create(cr, uid, {'name': 'Test child 1', 'parent_id': root_id})
child2_id = Menus.create(cr, uid, {'name': 'Test child 2', 'parent_id': root_id})
child21_id = Menus.create(cr, uid, {'name': 'Test child 2-1', 'parent_id': child2_id})
all_ids = [root_id, child1_id, child2_id, child21_id]
# delete and check that direct children are promoted to top-level
# cfr. explanation in menu.unlink()
Menus.unlink(cr, uid, [root_id])
remaining_ids = Menus.search(cr, uid, [('id', 'in', all_ids)], order="id", context=ctx)
self.assertEqual([child1_id, child2_id, child21_id], remaining_ids)
orphan_ids = Menus.search(cr, uid, [('id', 'in', all_ids), ('parent_id', '=', False)], order="id", context=ctx)
self.assertEqual([child1_id, child2_id], orphan_ids)

View File

@ -30,6 +30,7 @@ import time
import pickle
import base64
import socket
import string
admin_passwd = 'admin'
waittime = 10
@ -67,10 +68,10 @@ def execute(connector, method, *args):
except socket.error,e:
if e.args[0] == 111:
if wait_count > wait_limit:
print "Server is taking too long to start, it has exceeded the maximum limit of %d seconds."%(wait_limit)
print "Server is taking too long to start, it has exceeded the maximum limit of %d seconds." % wait_limit
clean()
sys.exit(1)
print 'Please wait %d sec to start server....'%(waittime)
print 'Please wait %d sec to start server....' % waittime
wait_count += 1
time.sleep(waittime)
res = execute(connector, method, *args)
@ -136,7 +137,7 @@ def check_quality(uri, user, pwd, dbname, modules, quality_logs):
detail_html +='''<div id=\"%s\"><h3>%s (Score : %s)</h3><font color=red><h5>%s</h5></font>%s</div>'''%(test.replace(' ', '-'), test, score, msg, detail.get('detail', ''))
test_detail[test] = (score,msg,detail.get('detail',''))
html += "</ul>"
html += "%s"%(detail_html)
html += "%s"% detail_html
html += "</div></body></html>"
if not os.path.isdir(quality_logs):
os.mkdir(quality_logs)
@ -305,13 +306,11 @@ options = {
'port' : opt.port or 8069,
'netport':opt.netport or 8070,
'database': opt.db_name or 'terp',
'modules' : opt.modules or [],
'modules' : map(string.strip, opt.modules.split(',')) if opt.modules else [],
'login' : opt.login or 'admin',
'pwd' : opt.pwd or '',
'extra-addons':opt.extra_addons or []
}
options['modules'] = opt.modules and map(lambda m: m.strip(), opt.modules.split(',')) or []
# Hint:i18n-import=purchase:ar_AR.po+sale:fr_FR.po,nl_BE.po
if opt.translate_in:
translate = opt.translate_in

View File

@ -94,10 +94,8 @@ def setup_pid_file():
def preload_registry(dbname):
""" Preload a registry, and start the cron."""
try:
db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=openerp.tools.config['init'] or openerp.tools.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()
update_module = True if openerp.tools.config['init'] or openerp.tools.config['update'] else False
db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=update_module, pooljobs=False)
except Exception:
_logger.exception('Failed to initialize database `%s`.', dbname)

View File

@ -110,7 +110,7 @@ def get_encodings(hint_encoding='utf-8'):
# some defaults (also taking care of pure ASCII)
for charset in ['utf8','latin1']:
if not (hint_encoding) or (charset.lower() != hint_encoding.lower()):
if not hint_encoding or (charset.lower() != hint_encoding.lower()):
yield charset
from locale import getpreferredencoding
@ -129,7 +129,7 @@ def ustr(value, hint_encoding='utf-8', errors='strict'):
:param: value: the value to convert
:param: hint_encoding: an optional encoding that was detecte
upstream and should be tried first to decode ``value``.
:param str error: optional `errors` flag to pass to the unicode
:param str errors: optional `errors` flag to pass to the unicode
built-in to indicate how illegal character values should be
treated when converting a string: 'strict', 'ignore' or 'replace'
(see ``unicode()`` constructor).

View File

@ -142,9 +142,13 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
migrations = openerp.modules.migration.MigrationManager(cr, graph)
_logger.debug('loading %d packages...', len(graph))
# get db timestamp
cr.execute("select (now() at time zone 'UTC')::timestamp")
dt_before_load = cr.fetchone()[0]
# Query manual fields for all models at once and save them on the registry
# so the initialization code for each model does not have to do it
# one model at a time.
pool.fields_by_model = {}
cr.execute('SELECT * FROM ir_model_fields WHERE state=%s', ('manual',))
for field in cr.dictfetchall():
pool.fields_by_model.setdefault(field['model'], []).append(field)
# register, instantiate and initialize models for each modules
for index, package in enumerate(graph):
@ -159,6 +163,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
load_openerp_module(package.name)
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)
@ -220,6 +225,10 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
delattr(package, kind)
cr.commit()
# The query won't be valid for models created later (i.e. custom model
# created after the registry has been loaded), so empty its result.
pool.fields_by_model = None
cr.commit()
@ -239,7 +248,7 @@ def _check_module_names(cr, module_names):
incorrect_names = mod_names.difference([x['name'] for x in cr.dictfetchall()])
_logger.warning('invalid module names, ignored: %s', ", ".join(incorrect_names))
def load_marked_modules(cr, graph, states, force, progressdict, report, loaded_modules):
def load_marked_modules(cr, graph, states, force, progressdict, report, loaded_modules, perform_checks):
"""Loads modules marked with ``states``, adding them to ``graph`` and
``loaded_modules`` and returns a list of installed/upgraded modules."""
processed_modules = []
@ -248,7 +257,7 @@ def load_marked_modules(cr, graph, states, force, progressdict, report, loaded_m
module_list = [name for (name,) in cr.fetchall() if name not in graph]
graph.add_modules(cr, module_list, force)
_logger.debug('Updating graph with %d more modules', len(module_list))
loaded, processed = load_module_graph(cr, graph, progressdict, report=report, skip_modules=loaded_modules)
loaded, processed = load_module_graph(cr, graph, progressdict, report=report, skip_modules=loaded_modules, perform_checks=perform_checks)
processed_modules.extend(processed)
loaded_modules.extend(loaded)
if not processed: break
@ -293,7 +302,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
# processed_modules: for cleanup step after install
# loaded_modules: to avoid double loading
report = pool._assertion_report
loaded_modules, processed_modules = load_module_graph(cr, graph, status, perform_checks=(not update_module), report=report)
loaded_modules, processed_modules = load_module_graph(cr, graph, status, perform_checks=update_module, report=report)
if tools.config['load_language']:
for lang in tools.config['load_language'].split(','):
@ -333,11 +342,11 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
# be dropped in STEP 6 later, before restarting the loading
# process.
states_to_load = ['installed', 'to upgrade', 'to remove']
processed = load_marked_modules(cr, graph, states_to_load, force, status, report, loaded_modules)
processed = load_marked_modules(cr, graph, states_to_load, force, status, report, loaded_modules, update_module)
processed_modules.extend(processed)
if update_module:
states_to_load = ['to install']
processed = load_marked_modules(cr, graph, states_to_load, force, status, report, loaded_modules)
processed = load_marked_modules(cr, graph, states_to_load, force, status, report, loaded_modules, update_module)
processed_modules.extend(processed)
# load custom models

View File

@ -50,6 +50,7 @@ class Registry(object):
self._init = True
self._init_parent = {}
self._assertion_report = assertion_report.assertion_report()
self.fields_by_model = None
# modules fully loaded (maintained during init phase by `loading` module)
self._init_modules = set()
@ -109,15 +110,16 @@ class Registry(object):
and registers them in the registry.
"""
res = []
models_to_load = [] # need to preserve loading order
# 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
# models register themselves in self.models
model = cls.create_instance(self, cr)
if model._name not in models_to_load:
# avoid double-loading models whose declaration is split
models_to_load.append(model._name)
return [self.models[m] for m in models_to_load]
def schedule_cron_jobs(self):
""" Make the cron thread care about this registry/database jobs.

View File

@ -332,33 +332,31 @@ def generate_table_alias(src_table_alias, joined_tables=[]):
- src_model='res_users', join_tables=[(res.partner, 'parent_id')]
alias = ('res_users__parent_id', '"res_partner" as "res_users__parent_id"')
:param model src_model: model source of the alias
:param list join_tables: list of tuples
(dst_model, link_field)
:param model src_table_alias: model source of the alias
:param list joined_tables: list of tuples
(dst_model, link_field)
:return tuple: (table_alias, alias statement for from clause with quotes added)
"""
alias = src_table_alias
if not joined_tables:
return ('%s' % alias, '%s' % _quote(alias))
return '%s' % alias, '%s' % _quote(alias)
for link in joined_tables:
alias += '__' + link[1]
assert len(alias) < 64, 'Table alias name %s is longer than the 64 characters size accepted by default in postgresql.' % (alias)
return ('%s' % alias, '%s as %s' % (_quote(joined_tables[-1][0]), _quote(alias)))
assert len(alias) < 64, 'Table alias name %s is longer than the 64 characters size accepted by default in postgresql.' % alias
return '%s' % alias, '%s as %s' % (_quote(joined_tables[-1][0]), _quote(alias))
def get_alias_from_query(from_query):
""" :param string from_query: is something like :
- '"res_partner"' OR
- '"res_partner" as "res_users__partner_id"''
:param tuple result: (unquoted table name, unquoted alias)
i.e. (res_partners, res_partner) OR (res_partner, res_users__partner_id)
"""
from_splitted = from_query.split(' as ')
if len(from_splitted) > 1:
return (from_splitted[0].replace('"', ''), from_splitted[1].replace('"', ''))
return from_splitted[0].replace('"', ''), from_splitted[1].replace('"', '')
else:
return (from_splitted[0].replace('"', ''), from_splitted[0].replace('"', ''))
return from_splitted[0].replace('"', ''), from_splitted[0].replace('"', '')
def normalize_leaf(element):
@ -377,7 +375,7 @@ def normalize_leaf(element):
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)
return left, operator, right
def is_operator(element):
@ -497,11 +495,19 @@ class ExtendedLeaf(object):
adding joins
:attr list join_context: list of join contexts. This is a list of
tuples like ``(lhs, table, lhs_col, col, link)``
:param obj lhs: source (left hand) model
:param obj model: destination (right hand) model
:param string lhs_col: source model column for join condition
:param string col: destination model column for join condition
:param link: link column between source and destination model
where
lhs
source (left hand) model
model
destination (right hand) model
lhs_col
source model column for join condition
col
destination model column for join condition
link
link column between source and destination model
that is not necessarily (but generally) a real column used
in the condition (i.e. in many2one); this link is used to
compute aliases
@ -829,7 +835,7 @@ class expression(object):
push(create_substitution_leaf(leaf, AND_OPERATOR, relational_model))
elif len(field_path) > 1 and field._auto_join:
raise NotImplementedError('_auto_join attribute not supported on many2many field %s' % (left))
raise NotImplementedError('_auto_join attribute not supported on many2many field %s' % left)
elif len(field_path) > 1 and field._type == 'many2one':
right_ids = relational_model.search(cr, uid, [(field_path[1], operator, right)], context=context)
@ -989,7 +995,7 @@ class expression(object):
res_ids = [x[0] for x in relational_model.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)
return left, 'in', res_ids
# resolve string-based m2o criterion into IDs
if isinstance(right, basestring) or \
right and isinstance(right, (tuple, list)) and all(isinstance(item, basestring) for item in right):
@ -1098,7 +1104,7 @@ class expression(object):
query = '(%s."%s" IS %s)' % (table_alias, left, r)
params = []
elif isinstance(right, (list, tuple)):
params = right[:]
params = list(right)
check_nulls = False
for i in range(len(params))[::-1]:
if params[i] == False:
@ -1140,8 +1146,8 @@ class expression(object):
query = '%s."%s" IS NOT NULL' % (table_alias, left)
params = []
elif (operator == '=?'):
if (right is False or right is None):
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 = []
@ -1187,7 +1193,7 @@ class expression(object):
if isinstance(params, basestring):
params = [params]
return (query, params)
return query, params
def to_sql(self):
stack = []
@ -1213,6 +1219,6 @@ class expression(object):
if joins:
query = '(%s) AND %s' % (joins, query)
return (query, tools.flatten(params))
return query, tools.flatten(params)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -668,7 +668,7 @@ class many2many(_column):
col1 = '%s_id' % source_model._table
if not col2:
col2 = '%s_id' % dest_model._table
return (tbl, col1, col2)
return tbl, col1, col2
def _get_query_and_where_params(self, cr, model, ids, values, where_params):
""" Extracted from ``get`` to facilitate fine-tuning of the generated
@ -1304,7 +1304,7 @@ class sparse(function):
def __init__(self, serialization_field, **kwargs):
self.serialization_field = serialization_field
return super(sparse, self).__init__(self._fnct_read, fnct_inv=self._fnct_write, multi='__sparse_multi', **kwargs)
super(sparse, self).__init__(self._fnct_read, fnct_inv=self._fnct_write, multi='__sparse_multi', **kwargs)
@ -1560,7 +1560,7 @@ class column_info(object):
def __str__(self):
return '%s(%s, %s, %s, %s, %s)' % (
self.__name__, self.name, self.column,
self.__class__.__name__, self.name, self.column,
self.parent_model, self.parent_column, self.original_parent)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -454,7 +454,7 @@ class browse_record(object):
new_data[field_name] = browse_null()
elif field_column._type in ('one2many', 'many2many') and len(result_line[field_name]):
new_data[field_name] = self._list_class([browse_record(self._cr, self._uid, id, self._table.pool.get(field_column._obj), self._cache, context=self._context, list_class=self._list_class, fields_process=self._fields_process) for id in result_line[field_name]], self._context)
elif field_column._type in ('reference'):
elif field_column._type == 'reference':
if result_line[field_name]:
if isinstance(result_line[field_name], browse_record):
new_data[field_name] = result_line[field_name]
@ -865,10 +865,6 @@ class BaseModel(object):
parent_names = [parent_names]
else:
name = cls._name
# for res.parnter.address compatiblity, should be remove in v7
if 'res.partner.address' in parent_names:
parent_names.pop(parent_names.index('res.partner.address'))
parent_names.append('res.partner')
if not name:
raise TypeError('_name is mandatory in case of multiple inheritance')
@ -1018,45 +1014,50 @@ class BaseModel(object):
# Load manual fields
cr.execute("SELECT id FROM ir_model_fields WHERE name=%s AND model=%s", ('state', 'ir.model.fields'))
if cr.fetchone():
# Check the query is already done for all modules of if we need to
# do it ourselves.
if self.pool.fields_by_model is not None:
manual_fields = self.pool.fields_by_model.get(self._name, [])
else:
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'])
}
manual_fields = cr.dictfetchall()
for field in manual_fields:
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['serialization_field_id']:
cr.execute('SELECT name FROM ir_model_fields WHERE id=%s', (field['serialization_field_id'],))
attrs.update({'serialization_field': cr.fetchone()[0], 'type': field['ttype']})
if field['ttype'] in ['many2one', 'one2many', 'many2many']:
attrs.update({'relation': field['relation']})
self._columns[field['name']] = fields.sparse(**attrs)
elif 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)
if field['serialization_field_id']:
cr.execute('SELECT name FROM ir_model_fields WHERE id=%s', (field['serialization_field_id'],))
attrs.update({'serialization_field': cr.fetchone()[0], 'type': field['ttype']})
if field['ttype'] in ['many2one', 'one2many', 'many2many']:
attrs.update({'relation': field['relation']})
self._columns[field['name']] = fields.sparse(**attrs)
elif 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:
@ -1741,7 +1742,7 @@ class BaseModel(object):
views = {}
xml = "<form>"
for f in node:
if f.tag in ('field'):
if f.tag == 'field':
xml += etree.tostring(f, encoding="utf-8")
xml += "</form>"
new_xml = etree.fromstring(encode(xml))
@ -2010,7 +2011,7 @@ class BaseModel(object):
view = etree.Element('calendar', string=self._description)
etree.SubElement(view, 'field', self._rec_name_fallback(cr, user, context))
if (self._date_name not in self._columns):
if self._date_name not in self._columns:
date_found = False
for dt in ['date', 'date_start', 'x_date', 'x_date_start']:
if dt in self._columns:
@ -2031,7 +2032,7 @@ class BaseModel(object):
self._columns, 'date_delay'):
raise except_orm(
_('Invalid Object Architecture!'),
_("Insufficient fields to generate a Calendar View for %s, missing a date_stop or a date_delay" % (self._name)))
_("Insufficient fields to generate a Calendar View for %s, missing a date_stop or a date_delay" % self._name))
return view
@ -2411,7 +2412,7 @@ class BaseModel(object):
: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);
rec_id = self.create(cr, uid, {self._rec_name: name}, context)
return self.name_get(cr, uid, [rec_id], context)[0]
# private implementation of name_search, allows passing a dedicated user for the name_get part to
@ -2675,7 +2676,7 @@ class BaseModel(object):
groupby = group_by
for r in cr.dictfetchall():
for fld, val in r.items():
if val == None: r[fld] = False
if val is None: r[fld] = False
alldata[r['id']] = r
del r['id']
@ -2889,15 +2890,15 @@ class BaseModel(object):
# 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'))
_schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s",
self._table, source_field, dest_model._table, ondelete)
fk_def = (self._table, source_field, dest_model._table, ondelete or 'set null')
self._foreign_keys.add(fk_def)
_schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s", *fk_def)
# 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'))
_schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s",
source_table, source_field, dest_model._table, ondelete)
fk_def = (source_table, source_field, dest_model._table, ondelete or 'set null')
self._foreign_keys.add(fk_def)
_schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s", *fk_def)
def _drop_constraint(self, cr, source_table, constraint_name):
cr.execute("ALTER TABLE %s DROP CONSTRAINT %s" % (source_table,constraint_name))
@ -2928,18 +2929,22 @@ class BaseModel(object):
cons, = constraints
if cons['ondelete_rule'] != POSTGRES_CONFDELTYPES.get((ondelete or 'set null').upper(), 'a')\
or cons['foreign_table'] != dest_model._table:
# Wrong FK: drop it and recreate
_schema.debug("Table '%s': dropping obsolete FK constraint: '%s'",
source_table, cons['constraint_name'])
self._drop_constraint(cr, source_table, cons['constraint_name'])
self._m2o_add_foreign_key_checked(source_field, dest_model, ondelete)
# else it's all good, nothing to do!
else:
# it's all good, nothing to do!
return
else:
# Multiple FKs found for the same field, drop them all, and re-create
for cons in constraints:
_schema.debug("Table '%s': dropping duplicate FK constraints: '%s'",
source_table, cons['constraint_name'])
self._drop_constraint(cr, source_table, cons['constraint_name'])
self._m2o_add_foreign_key_checked(source_field, dest_model, ondelete)
# (re-)create the FK
self._m2o_add_foreign_key_checked(source_field, dest_model, ondelete)
@ -2961,7 +2966,7 @@ class BaseModel(object):
_auto_end).
"""
self._foreign_keys = []
self._foreign_keys = set()
raise_on_invalid_object_name(self._name)
if context is None:
context = {}
@ -3097,7 +3102,7 @@ class BaseModel(object):
else:
default = self._defaults[k]
if (default is not None):
if default is not None:
ss = self._columns[k]._symbol_set
query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (self._table, k, ss[0], k)
cr.execute(query, (ss[1](default),))
@ -3176,7 +3181,7 @@ class BaseModel(object):
# and add constraints if needed
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,))
raise except_orm('Programming Error', 'There is no reference available for %s' % (f._obj,))
dest_model = self.pool.get(f._obj)
ref = dest_model._table
# ir_actions is inherited so foreign key doesn't work on it
@ -3262,8 +3267,8 @@ class BaseModel(object):
elif not self._columns['parent_right'].select:
_logger.error('parent_right column on object %s must be indexed! Add select=1 to the field definition)',
self._table)
if self._columns[self._parent_name].ondelete != 'cascade':
_logger.error("The column %s on object %s must be set as ondelete='cascade'",
if self._columns[self._parent_name].ondelete not in ('cascade', 'restrict'):
_logger.error("The column %s on object %s must be set as ondelete='cascade' or 'restrict'",
self._parent_name, self._name)
cr.commit()
@ -3303,7 +3308,7 @@ class BaseModel(object):
# TODO the condition could use fields_get_keys().
if f._fields_id not in other._columns.keys():
if f._fields_id not in other._inherit_fields.keys():
raise except_orm('Programming Error', ("There is no reference field '%s' found for '%s'") % (f._fields_id, f._obj,))
raise except_orm('Programming Error', "There is no reference field '%s' found for '%s'" % (f._fields_id, f._obj,))
def _m2m_raise_or_create_relation(self, cr, f):
m2m_tbl, col1, col2 = f._sql_names(self)
@ -3311,7 +3316,7 @@ class BaseModel(object):
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', ('Many2Many destination model does not exist: `%s`') % (f._obj,))
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"))' % (m2m_tbl, col1, col2, col1, col2))
@ -3445,8 +3450,8 @@ class BaseModel(object):
_logger.info('Missing many2one field definition for _inherits reference "%s" in "%s", using default one.', field_name, self._name)
self._columns[field_name] = fields.many2one(table, string="Automatically created field to link to parent %s" % table,
required=True, ondelete="cascade")
elif not self._columns[field_name].required or self._columns[field_name].ondelete.lower() != "cascade":
_logger.warning('Field definition for _inherits reference "%s" in "%s" must be marked as "required" with ondelete="cascade", forcing it.', field_name, self._name)
elif not self._columns[field_name].required or self._columns[field_name].ondelete.lower() not in ("cascade", "restrict"):
_logger.warning('Field definition for _inherits reference "%s" in "%s" must be marked as "required" with ondelete="cascade" or "restrict", forcing it to required + cascade.', field_name, self._name)
self._columns[field_name].required = True
self._columns[field_name].ondelete = "cascade"
@ -3485,7 +3490,7 @@ class BaseModel(object):
:param cr: database cursor
:param user: current user id
:param fields: list of fields
:param allfields: list of fields
:param context: context arguments, like lang, time zone
:return: dictionary of field dictionaries, each one describing a field of the business object
:raise AccessError: * if user has no create/write rights on the requested object
@ -3536,6 +3541,37 @@ class BaseModel(object):
return res
def check_field_access_rights(self, cr, user, operation, fields, context=None):
"""
Check the user access rights on the given fields. This raises Access
Denied if the user does not have the rights. Otherwise it returns the
fields (as is if the fields is not falsy, or the readable/writable
fields if fields is falsy).
"""
def p(field_name):
"""Predicate to test if the user has access to the given field name."""
# Ignore requested field if it doesn't exist. This is ugly but
# it seems to happen at least with 'name_alias' on res.partner.
if field_name not in self._all_columns:
return True
field = self._all_columns[field_name].column
if field.groups:
return self.user_has_groups(cr, user, groups=field.groups, context=context)
else:
return True
if not fields:
fields = filter(p, self._all_columns.keys())
else:
filtered_fields = filter(lambda a: not p(a), fields)
if filtered_fields:
_logger.warning('Access Denied by ACLs for operation: %s, uid: %s, model: %s, fields: %s', operation, user, self._name, ', '.join(filtered_fields))
raise except_orm(
_('Access Denied'),
_('The requested operation cannot be completed due to security restrictions. '
'Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % \
(self._description, operation))
return fields
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
""" Read records with given ids with the given fields
@ -3561,8 +3597,7 @@ class BaseModel(object):
if not context:
context = {}
self.check_access_rights(cr, user, 'read')
if not fields:
fields = list(set(self._columns.keys() + self._inherit_fields.keys()))
fields = self.check_field_access_rights(cr, user, 'read', fields)
if isinstance(ids, (int, long)):
select = [ids]
else:
@ -3584,7 +3619,7 @@ class BaseModel(object):
context = {}
if not ids:
return []
if fields_to_read == None:
if fields_to_read is None:
fields_to_read = self._columns.keys()
# Construct a clause for the security rules.
@ -3628,15 +3663,16 @@ class BaseModel(object):
else:
res = map(lambda x: {'id': x}, ids)
for f in fields_pre:
if f == self.CONCURRENCY_CHECK_FIELD:
continue
if self._columns[f].translate:
ids = [x['id'] for x in res]
#TODO: optimize out of this loop
res_trans = self.pool.get('ir.translation')._get_ids(cr, user, self._name+','+f, 'model', context.get('lang', False) or 'en_US', ids)
for r in res:
r[f] = res_trans.get(r['id'], False) or r[f]
if context.get('lang'):
for f in fields_pre:
if f == self.CONCURRENCY_CHECK_FIELD:
continue
if self._columns[f].translate:
ids = [x['id'] for x in res]
#TODO: optimize out of this loop
res_trans = self.pool.get('ir.translation')._get_ids(cr, user, self._name+','+f, 'model', context['lang'], ids)
for r in res:
r[f] = res_trans.get(r['id'], False) or r[f]
for table in self._inherits:
col = self._inherits[table]
@ -4018,6 +4054,7 @@ class BaseModel(object):
"""
readonly = None
self.check_field_access_rights(cr, user, 'write', vals.keys())
for field in vals.copy():
fobj = None
if field in self._columns:
@ -4672,7 +4709,7 @@ class BaseModel(object):
new_tables = []
for table in added_tables:
# table is just a table name -> switch to the full alias
if table == '"%s"' % (parent_table):
if table == '"%s"' % parent_table:
new_tables.append('"%s" as "%s"' % (parent_table, parent_alias))
# table is already a full statement -> replace reference to the table to its alias, is correct with the way aliases are generated
else:
@ -4838,7 +4875,7 @@ class BaseModel(object):
Copy given record's data with all its fields values
:param cr: database cursor
:param user: current user id
:param uid: current user id
:param id: id of the record to copy
:param default: field values to override in the original values of the copied record
:type default: dictionary
@ -4997,7 +5034,7 @@ class BaseModel(object):
"""
if type(ids) in (int, long):
ids = [ids]
query = 'SELECT id FROM "%s"' % (self._table)
query = 'SELECT id FROM "%s"' % self._table
cr.execute(query + "WHERE ID IN %s", (tuple(ids),))
return [x[0] for x in cr.fetchall()]

View File

@ -151,7 +151,7 @@ class Query(object):
query_from = add_joins_for_table(table_alias, query_from)
query_from += ','
query_from = query_from[:-1] # drop last comma
return (query_from, " AND ".join(self.where_clause), self.where_clause_params)
return query_from, " AND ".join(self.where_clause), self.where_clause_params
def __str__(self):
return '<osv.Query: "SELECT ... FROM %s WHERE %s" with params: %r>' % self.get_sql()

View File

@ -96,7 +96,7 @@ class report_custom(report_int):
else:
# Process group_by data first
key = []
if group_by != None and fields[group_by] != None:
if group_by is not None and fields[group_by] is not None:
if fields[group_by][0] in levels.keys():
key.append(fields[group_by][0])
for l in levels.keys():
@ -144,10 +144,11 @@ class report_custom(report_int):
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
fct['gety'] = lambda x: x.split('-')[0]
fct['in'] = lambda x: x.split(',')
fct = {
'id': lambda x: x,
'gety': lambda x: x.split('-')[0],
'in': lambda x: x.split(',')
}
new_fields = []
new_cond = []
for f in fields:
@ -212,7 +213,7 @@ class report_custom(report_int):
new_res = []
prev = None
if groupby != None:
if groupby is not None:
res_dic = {}
for line in results:
if not line[groupby] and prev in res_dic:
@ -272,7 +273,7 @@ class report_custom(report_int):
res = self._create_bars(cr,uid, ids, report, fields, results2, context)
elif report['type']=='line':
res = self._create_lines(cr,uid, ids, report, fields, results2, context)
return (self.obj.get(), 'pdf')
return self.obj.get(), 'pdf'
def _create_tree(self, uid, ids, report, fields, level, results, context):
pageSize=common.pageSize.get(report['print_format'], [210.0,297.0])
@ -322,7 +323,7 @@ class report_custom(report_int):
col.attrib.update(para='yes',
tree='yes',
space=str(3*shift)+'mm')
if line[f] != None:
if line[f] is not None:
col.text = prefix+str(line[f]) or ''
else:
col.text = '/'
@ -350,15 +351,17 @@ class report_custom(report_int):
x_axis = axis.X(label = fields[0]['name'], format="/a-30{}%s"),
y_axis = axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:]))))
process_date = {}
process_date['D'] = lambda x : reduce(lambda xx,yy : xx+'-'+yy,x.split('-')[1:3])
process_date['M'] = lambda x : x.split('-')[1]
process_date['Y'] = lambda x : x.split('-')[0]
process_date = {
'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]),
'M': lambda x: x.split('-')[1],
'Y': lambda x: x.split('-')[0]
}
order_date = {}
order_date['D'] = lambda x : time.mktime((2005,int(x.split('-')[0]), int(x.split('-')[1]),0,0,0,0,0,0))
order_date['M'] = lambda x : x
order_date['Y'] = lambda x : x
order_date = {
'D': lambda x: time.mktime((2005, int(x.split('-')[0]), int(x.split('-')[1]), 0, 0, 0, 0, 0, 0)),
'M': lambda x: x,
'Y': lambda x: x
}
abscissa = []
@ -381,7 +384,7 @@ class report_custom(report_int):
# plots are usually displayed year by year
# so we do so if the first field is a date
data_by_year = {}
if date_idx != None:
if date_idx is not None:
for r in results:
key = process_date['Y'](r[date_idx])
if key not in data_by_year:
@ -447,15 +450,17 @@ class report_custom(report_int):
can.show(80,380,'/16/H'+report['title'])
process_date = {}
process_date['D'] = lambda x : reduce(lambda xx,yy : xx+'-'+yy,x.split('-')[1:3])
process_date['M'] = lambda x : x.split('-')[1]
process_date['Y'] = lambda x : x.split('-')[0]
process_date = {
'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]),
'M': lambda x: x.split('-')[1],
'Y': lambda x: x.split('-')[0]
}
order_date = {}
order_date['D'] = lambda x : time.mktime((2005,int(x.split('-')[0]), int(x.split('-')[1]),0,0,0,0,0,0))
order_date['M'] = lambda x : x
order_date['Y'] = lambda x : x
order_date = {
'D': lambda x: time.mktime((2005, int(x.split('-')[0]), int(x.split('-')[1]), 0, 0, 0, 0, 0, 0)),
'M': lambda x: x,
'Y': lambda x: x
}
ar = area.T(size=(350,350),
x_axis = axis.X(label = fields[0]['name'], format="/a-30{}%s"),
@ -480,7 +485,7 @@ class report_custom(report_int):
# plot are usually displayed year by year
# so we do so if the first field is a date
data_by_year = {}
if date_idx != None:
if date_idx is not None:
for r in results:
key = process_date['Y'](r[date_idx])
if key not in data_by_year:
@ -602,7 +607,7 @@ class report_custom(report_int):
node_line = etree.SubElement(lines, 'row')
for f in range(len(fields)):
col = etree.SubElement(node_line, 'col', tree='no')
if line[f] != None:
if line[f] is not None:
col.text = line[f] or ''
else:
col.text = '/'

View File

@ -52,7 +52,7 @@ def _1000_to_text(chiffre):
d2 = chiffre/100
if d2>0 and d:
return centaine[d2]+' '+d
elif d2>1 and not(d):
elif d2>1 and not d:
return centaine[d2]+'s'
else:
return centaine[d2] or d

View File

@ -55,13 +55,12 @@ class report_int(netsvc.Service):
def create(self, cr, uid, ids, datas, context=None):
return False
"""
Class to automatically build a document using the transformation process:
XML -> DATAS -> RML -> PDF
-> HTML
using a XSL:RML transformation
"""
class report_rml(report_int):
"""
Automatically builds a document using the transformation process:
XML -> DATAS -> RML -> PDF -> HTML
using a XSL:RML transformation
"""
def __init__(self, name, table, tmpl, xsl):
super(report_rml, self).__init__(name)
self.table = table
@ -85,7 +84,7 @@ class report_rml(report_int):
xml = tools.ustr(xml).encode('utf8')
report_type = datas.get('report_type', 'pdf')
if report_type == 'raw':
return (xml,report_type)
return xml, report_type
rml = self.create_rml(cr, xml, uid, context)
pool = pooler.get_pool(cr.dbname)
ir_actions_report_xml_obj = pool.get('ir.actions.report.xml')
@ -93,7 +92,7 @@ class report_rml(report_int):
self.title = report_xml_ids and ir_actions_report_xml_obj.browse(cr,uid,report_xml_ids)[0].name or 'OpenERP Report'
create_doc = self.generators[report_type]
pdf = create_doc(rml, title=self.title)
return (pdf, report_type)
return pdf, report_type
def create_xml(self, cr, uid, ids, datas, context=None):
if not context:
@ -244,10 +243,10 @@ class report_rml(report_int):
return obj.get()
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
return [
self.tmpl.replace(os.path.sep, '/').rsplit('/', 1)[0],
'addons',
tools.config['root_path']
]
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -65,7 +65,7 @@ class report_printscreen_list(report_int):
fields_order = self._parse_string(result['arch'])
rows = model.read(cr, uid, datas['ids'], result['fields'].keys() )
self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model._description)
return (self.obj.get(), 'pdf')
return self.obj.get(), 'pdf'
def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
@ -119,7 +119,7 @@ class report_printscreen_list(report_int):
precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
line[f]=round(line[f],precision)
col = etree.SubElement(node_line, 'col', tree='no')
if line[f] != None:
if line[f] is not None:
col.text = tools.ustr(line[f] or '')
else:
col.text = '/'

View File

@ -115,7 +115,7 @@ class report_printscreen_list(report_int):
rows_new += [elem for elem in rows if elem['id'] == id]
rows = rows_new
res = self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model_desc)
return (self.obj.get(), 'pdf')
return self.obj.get(), 'pdf'
def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
@ -147,7 +147,7 @@ class report_printscreen_list(report_int):
for i in range(0, len(fields_order)):
temp.append(0)
tsum.append(0)
ince = -1;
ince = -1
for f in fields_order:
s = 0
ince += 1
@ -230,14 +230,14 @@ class report_printscreen_list(report_int):
col.text = line[f] = 'Undefined'
col.set('tree', 'undefined')
if line[f] != None:
if line[f] is not None:
col.text = tools.ustr(line[f] or '')
if float_flag:
col.set('tree','float')
if line.get('__no_leaf') and temp[count] == 1 and f != 'id' and not line['__context']['group_by']:
tsum[count] = float(tsum[count]) + float(line[f])
if not line.get('__group') and f != 'id' and temp[count] == 1:
tsum[count] = float(tsum[count]) + float(line[f]);
tsum[count] = float(tsum[count]) + float(line[f])
else:
col.text = '/'
@ -245,7 +245,7 @@ class report_printscreen_list(report_int):
for f in range(0, len(fields_order)):
col = etree.SubElement(node_line, 'col', para='group', tree='no')
col.set('tree', 'float')
if tsum[f] != None:
if tsum[f] is not None:
if tsum[f] != 0.0:
digits = fields[fields_order[f]].get('digits', (16, 2))
prec = '%%.%sf' % (digits[1], )

View File

@ -106,7 +106,7 @@ class FlateDecode(object):
if predictor != 1:
columns = decodeParms["/Columns"]
# PNG prediction:
if predictor >= 10 and predictor <= 15:
if 10 <= predictor <= 15:
output = StringIO()
# PNG prediction can vary from row to row
rowlength = columns + 1
@ -191,7 +191,7 @@ class ASCII85Decode(object):
break
else:
c = ord(c) - 33
assert c >= 0 and c < 85
assert 0 <= c < 85
group += [ c ]
if len(group) >= 5:
b = group[0] * (85**4) + \

View File

@ -81,7 +81,7 @@ def readObject(stream, pdf):
return NumberObject.readFromStream(stream)
peek = stream.read(20)
stream.seek(-len(peek), 1) # reset to start
if re.match(r"(\d+)\s(\d+)\sR[^a-zA-Z]", peek) != None:
if re.match(r"(\d+)\s(\d+)\sR[^a-zA-Z]", peek) is not None:
return IndirectObject.readFromStream(stream, pdf)
else:
return NumberObject.readFromStream(stream)
@ -169,7 +169,7 @@ class IndirectObject(PdfObject):
def __eq__(self, other):
return (
other != None and
other is not None and
isinstance(other, IndirectObject) and
self.idnum == other.idnum and
self.generation == other.generation and
@ -489,7 +489,7 @@ class DictionaryObject(dict, PdfObject):
# return None if no metadata was found on the document root.
def getXmpMetadata(self):
metadata = self.get("/Metadata", None)
if metadata == None:
if metadata is None:
return None
metadata = metadata.getObject()
import xmp

View File

@ -53,13 +53,7 @@ import utils
from generic import *
from utils import readNonWhitespace, readUntilWhitespace, ConvertFunctionsToVirtualList
if version_info < ( 2, 4 ):
from sets import ImmutableSet as frozenset
if version_info < ( 2, 5 ):
from md5 import md5
else:
from hashlib import md5
from hashlib import md5
##
# This class supports writing PDF files out, given pages produced by another
@ -197,7 +191,7 @@ class PdfFileWriter(object):
# flag is on.
def encrypt(self, user_pwd, owner_pwd = None, use_128bit = True):
import time, random
if owner_pwd == None:
if owner_pwd is None:
owner_pwd = user_pwd
if use_128bit:
V = 2
@ -251,7 +245,7 @@ class PdfFileWriter(object):
# copying in a new copy of the page object.
for objIndex in xrange(len(self._objects)):
obj = self._objects[objIndex]
if isinstance(obj, PageObject) and obj.indirectRef != None:
if isinstance(obj, PageObject) and obj.indirectRef is not None:
data = obj.indirectRef
if not externalReferenceMap.has_key(data.pdf):
externalReferenceMap[data.pdf] = {}
@ -305,7 +299,7 @@ class PdfFileWriter(object):
trailer.writeToStream(stream, None)
# eof
stream.write("\nstartxref\n%s\n%%%%EOF\n" % (xref_location))
stream.write("\nstartxref\n%s\n%%%%EOF\n" % xref_location)
def _sweepIndirectReferences(self, externMap, data):
if isinstance(data, DictionaryObject):
@ -340,7 +334,7 @@ class PdfFileWriter(object):
return data
else:
newobj = externMap.get(data.pdf, {}).get(data.generation, {}).get(data.idnum, None)
if newobj == None:
if newobj is None:
newobj = data.pdf.getObject(data)
self._objects.append(None) # placeholder
idnum = len(self._objects)
@ -426,7 +420,7 @@ class PdfFileReader(object):
# Stability: Added in v1.0, will exist for all v1.x releases.
# @return Returns an integer.
def getNumPages(self):
if self.flattenedPages == None:
if self.flattenedPages is None:
self._flatten()
return len(self.flattenedPages)
@ -445,7 +439,7 @@ class PdfFileReader(object):
def getPage(self, pageNumber):
## ensure that we're not trying to access an encrypted PDF
#assert not self.trailer.has_key("/Encrypt")
if self.flattenedPages == None:
if self.flattenedPages is None:
self._flatten()
return self.flattenedPages[pageNumber]
@ -465,7 +459,7 @@ class PdfFileReader(object):
# @return Returns a dict which maps names to {@link #Destination
# destinations}.
def getNamedDestinations(self, tree=None, retval=None):
if retval == None:
if retval is None:
retval = {}
catalog = self.trailer["/Root"]
@ -477,7 +471,7 @@ class PdfFileReader(object):
if names.has_key("/Dests"):
tree = names['/Dests']
if tree == None:
if tree is None:
return retval
if tree.has_key("/Kids"):
@ -493,7 +487,7 @@ class PdfFileReader(object):
if isinstance(val, DictionaryObject) and val.has_key('/D'):
val = val['/D']
dest = self._buildDestination(key, val)
if dest != None:
if dest is not None:
retval[key] = dest
return retval
@ -511,7 +505,7 @@ class PdfFileReader(object):
# Stability: Added in v1.10, will exist for all future v1.x releases.
# @return Returns a nested list of {@link #Destination destinations}.
def getOutlines(self, node=None, outlines=None):
if outlines == None:
if outlines is None:
outlines = []
catalog = self.trailer["/Root"]
@ -522,7 +516,7 @@ class PdfFileReader(object):
node = lines["/First"]
self._namedDests = self.getNamedDestinations()
if node == None:
if node is None:
return outlines
# see if there are any more outlines
@ -588,9 +582,9 @@ class PdfFileReader(object):
NameObject("/Resources"), NameObject("/MediaBox"),
NameObject("/CropBox"), NameObject("/Rotate")
)
if inherit == None:
if inherit is None:
inherit = dict()
if pages == None:
if pages is None:
self.flattenedPages = []
catalog = self.trailer["/Root"].getObject()
pages = catalog["/Pages"].getObject()
@ -616,7 +610,7 @@ class PdfFileReader(object):
def getObject(self, indirectReference):
retval = self.resolvedObjects.get(indirectReference.generation, {}).get(indirectReference.idnum, None)
if retval != None:
if retval is not None:
return retval
if indirectReference.generation == 0 and \
self.xref_objStm.has_key(indirectReference.idnum):
@ -844,7 +838,6 @@ class PdfFileReader(object):
else:
# no xref table found at specified location
assert False
break
def _pairs(self, array):
i = 0
@ -959,10 +952,10 @@ def getRectangle(self, name, defaults):
retval = self.get(name)
if isinstance(retval, RectangleObject):
return retval
if retval == None:
if retval is None:
for d in defaults:
retval = self.get(d)
if retval != None:
if retval is not None:
break
if isinstance(retval, IndirectObject):
retval = self.pdf.getObject(retval)

View File

@ -78,7 +78,7 @@ class ConvertFunctionsToVirtualList(object):
len_self = len(self)
if index < 0:
# support negative indexes
index = len_self + index
index += len_self
if index < 0 or index >= len_self:
raise IndexError, "sequence index out of range"
return self.getFunction(index)

View File

@ -66,7 +66,7 @@ class XmpInformation(PdfObject):
for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
if desc.getAttributeNS(RDF_NAMESPACE, "about") == aboutUri:
attr = desc.getAttributeNodeNS(namespace, name)
if attr != None:
if attr is not None:
yield attr
for element in desc.getElementsByTagNameNS(namespace, name):
yield element
@ -187,7 +187,7 @@ class XmpInformation(PdfObject):
else:
value = self._getText(element)
break
if value != None:
if value is not None:
value = converter(value)
ns_cache = self.cache.setdefault(namespace, {})
ns_cache[name] = value
@ -353,5 +353,5 @@ class XmpInformation(PdfObject):
custom_properties = property(custom_properties)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -391,7 +391,7 @@ class _rml_doc(object):
list_story.append(story_text)
del f
if template.data:
tag = '''<img src = '%s' width=80 height=72/>'''%(template.data)
tag = '''<img src = '%s' width=80 height=72/>'''% template.data
else:
tag = ''
self.result +='''

View File

@ -28,14 +28,14 @@ regex_t = re.compile('\(([0-9\.]*),([0-9\.]*),([0-9\.]*)\)')
regex_h = re.compile('#([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])')
def get(col_str):
if col_str == None:
if col_str is None:
col_str = ''
global allcols
if col_str in allcols.keys():
return allcols[col_str]
res = regex_t.search(col_str, 0)
if res:
return (float(res.group(1)),float(res.group(2)),float(res.group(3)))
return float(res.group(1)), float(res.group(2)), float(res.group(3))
res = regex_h.search(col_str, 0)
if res:
return tuple([ float(int(res.group(i),16))/255 for i in range(1,4)])

View File

@ -96,7 +96,7 @@ class NumberedCanvas(canvas.Canvas):
key=self._pageCounter
if not self.pages.get(key,False):
while not self.pages.get(key,False):
key = key + 1
key += 1
self.setFont("Helvetica", 8)
self.drawRightString((self._pagesize[0]-30), (self._pagesize[1]-40),
" %(this)i / %(total)i" % {
@ -123,7 +123,7 @@ class PageCount(platypus.Flowable):
self.story_count = story_count
def draw(self):
self.canv.beginForm("pageCount%d" % (self.story_count))
self.canv.beginForm("pageCount%d" % self.story_count)
self.canv.setFont("Helvetica", utils.unit_get(str(8)))
self.canv.drawString(0, 0, str(self.canv.getPageNumber()))
self.canv.endForm()
@ -268,18 +268,18 @@ class _rml_doc(object):
if fontname not in pdfmetrics._fonts:
pdfmetrics.registerFont(TTFont(fontname, filename))
if (mode == 'all'):
if mode == 'all':
addMapping(face, 0, 0, fontname) #normal
addMapping(face, 0, 1, fontname) #italic
addMapping(face, 1, 0, fontname) #bold
addMapping(face, 1, 1, fontname) #italic and bold
elif (mode== 'normal') or (mode == 'regular'):
addMapping(face, 0, 0, fontname) #normal
elif (mode == 'italic'):
elif mode == 'italic':
addMapping(face, 0, 1, fontname) #italic
elif (mode == 'bold'):
elif mode == 'bold':
addMapping(face, 1, 0, fontname) #bold
elif (mode == 'bolditalic'):
elif mode == 'bolditalic':
addMapping(face, 1, 1, fontname) #italic and bold
def _textual_image(self, node):
@ -602,7 +602,7 @@ class _rml_Illustration(platypus.flowables.Flowable):
self.height = utils.unit_get(node.get('height'))
self.self2 = self2
def wrap(self, *args):
return (self.width, self.height)
return self.width, self.height
def draw(self):
drw = _rml_draw(self.localcontext ,self.node,self.styles, images=self.self2.images, path=self.self2.path, title=self.self2.title)
drw.render(self.canv, None)
@ -890,7 +890,7 @@ class TinyDocTemplate(platypus.BaseDocTemplate):
self.canv._storyCount = 0
def ___handle_pageBegin(self):
self.page = self.page + 1
self.page += 1
self.pageTemplate.beforeDrawPage(self.canv,self)
self.pageTemplate.checkPageSize(self.canv,self)
self.pageTemplate.onPage(self.canv,self)

View File

@ -29,7 +29,8 @@ import utils
Font_size= 10.0
def verbose(text):
sys.stderr.write(text+"\n");
sys.stderr.write(text+"\n")
class textbox(object):
"""A box containing plain text.
@ -107,11 +108,11 @@ class textbox(object):
def haplines(self,arr,offset,cc= ''):
""" Horizontaly append lines
"""
while (len(self.lines) < len(arr)):
while len(self.lines) < len(arr):
self.lines.append("")
for i in range(len(self.lines)):
while (len(self.lines[i]) < offset):
while len(self.lines[i]) < offset:
self.lines[i] += " "
for i in range(len(arr)):
self.lines[i] += cc +arr[i]
@ -220,7 +221,7 @@ class _flowable(object):
def rec_render(self,node):
""" Recursive render: fill outarr with text of current node
"""
if node.tag != None:
if node.tag is not None:
if node.tag in self._tags:
self._tags[node.tag](node)
else:
@ -255,12 +256,10 @@ class _rml_tmpl_frame(_rml_tmpl_tag):
self.posx = posx
def tag_start(self):
return "frame start"
return '<table border="0" width="%d"><tr><td width="%d">&nbsp;</td><td>' % (self.width+self.posx,self.posx)
def tag_end(self):
return True
def tag_stop(self):
return "frame stop"
return '</td></tr></table><br/>'
def tag_mergeable(self):
return False
@ -282,24 +281,7 @@ class _rml_tmpl_draw_string(_rml_tmpl_tag):
def tag_start(self):
return "draw string \"%s\" @(%d,%d)..\n" %("txt",self.posx,self.posy)
self.pos.sort()
res = '\\table ...'
posx = 0
i = 0
for (x,y,align,txt, style, fs) in self.pos:
if align=="left":
pos2 = len(txt)*fs
res+='<td width="%d"></td><td style="%s" width="%d">%s</td>' % (x - posx, style, pos2, txt)
posx = x+pos2
if align=="right":
res+='<td width="%d" align="right" style="%s">%s</td>' % (x - posx, style, txt)
posx = x
if align=="center":
res+='<td width="%d" align="center" style="%s">%s</td>' % ((x - posx)*2, style, txt)
posx = 2*x-posx
i+=1
res+='\\table end'
return res
def merge(self, ds):
self.pos+=ds.pos
@ -316,10 +298,6 @@ class _rml_tmpl_draw_lines(_rml_tmpl_tag):
def tag_start(self):
return "draw lines..\n"
if self.ok:
return '<table border="0" cellpadding="0" cellspacing="0" width="%d"><tr><td width="%d"></td><td><hr width="100%%" style="margin:0px; %s"></td></tr></table>' % (self.posx+self.width,self.posx,self.style)
else:
return ''
class _rml_stylesheet(object):
def __init__(self, stylesheet, doc):
@ -456,11 +434,6 @@ class _rml_template(object):
def end(self):
return "template end\n"
result = ''
while not self.loop:
result += self.frame_start()
result += self.frame_stop()
return result
class _rml_doc(object):
def __init__(self, node, localcontext=None, images=None, path='.', title=None):

View File

@ -441,7 +441,7 @@ class report_sxw(report_rml, preprocess.report):
raise NotImplementedError(_('Unknown report type: %s') % report_type)
fnct_ret = fnct(cr, uid, ids, data, report_xml, context)
if not fnct_ret:
return (False,False)
return False, False
return fnct_ret
def create_source_odt(self, cr, uid, ids, data, report_xml, context=None):
@ -531,7 +531,7 @@ class report_sxw(report_rml, preprocess.report):
logo = base64.decodestring(rml_parser.logo)
create_doc = self.generators[report_xml.report_type]
pdf = create_doc(etree.tostring(processed_rml),rml_parser.localcontext,logo,title.encode('utf8'))
return (pdf, report_xml.report_type)
return pdf, report_xml.report_type
def create_single_odt(self, cr, uid, ids, data, report_xml, context=None):
if not context:
@ -644,7 +644,7 @@ class report_sxw(report_rml, preprocess.report):
sxw_z.close()
final_op = sxw_io.getvalue()
sxw_io.close()
return (final_op, mime_type)
return final_op, mime_type
def create_single_html2html(self, cr, uid, ids, data, report_xml, context=None):
if not context:
@ -666,7 +666,7 @@ class report_sxw(report_rml, preprocess.report):
create_doc = self.generators['html2html']
html = etree.tostring(create_doc(html_dom, html_parser.localcontext))
return (html.replace('&amp;','&').replace('&lt;', '<').replace('&gt;', '>').replace('</br>',''), report_type)
return html.replace('&amp;','&').replace('&lt;', '<').replace('&gt;', '>').replace('</br>',''), report_type
def create_single_mako2html(self, cr, uid, ids, data, report_xml, context=None):
mako_html = report_xml.report_rml_content
@ -675,7 +675,7 @@ class report_sxw(report_rml, preprocess.report):
html_parser.set_context(objs, data, ids, 'html')
create_doc = self.generators['makohtml2html']
html = create_doc(mako_html,html_parser.localcontext)
return (html,'html')
return html,'html'
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -139,7 +139,7 @@ class OpenERPAuthProvider(AuthProvider):
uid = security.login(db,user,passwd)
if uid is False:
return False
return (user, passwd, db, uid)
return user, passwd, db, uid
except Exception,e:
_logger.debug("Fail auth: %s" % e )
return False

View File

@ -172,13 +172,13 @@ class db(netsvc.ExportService):
def exp_get_progress(self, id):
if self.actions[id]['thread'].isAlive():
# return openerp.modules.init_progress[db_name]
return (min(self.actions[id].get('progress', 0),0.95), [])
return min(self.actions[id].get('progress', 0),0.95), []
else:
clean = self.actions[id]['clean']
if clean:
users = self.actions[id]['users']
self.actions.pop(id)
return (1.0, users)
return 1.0, users
else:
e = self.actions[id]['exception'] # TODO this seems wrong: actions[id]['traceback'] is set, but not 'exception'.
self.actions.pop(id)
@ -543,7 +543,7 @@ GNU Public Licence.
if os.name == 'posix':
if platform.system() == 'Linux':
lsbinfo = os.popen('lsb_release -a').read()
environment += '%s'%(lsbinfo)
environment += '%s'% lsbinfo
else:
environment += 'Your System is not lsb compliant\n'
environment += 'Operating System Release : %s\n' \

View File

@ -226,9 +226,9 @@ class HttpOptions:
Sometimes, like in special DAV folders, the OPTIONS may contain
extra keywords, perhaps also dependant on the request url.
@param the options already. MUST be copied before being altered
@return the updated options.
:param opts: MUST be copied before being altered
:returns: the updated options.
"""
return opts

View File

@ -74,8 +74,8 @@ import threading
from inspect import currentframe
import re
re_from = re.compile('.* from "?([a-zA-Z_0-9]+)"? .*$');
re_into = re.compile('.* into "?([a-zA-Z_0-9]+)"? .*$');
re_from = re.compile('.* from "?([a-zA-Z_0-9]+)"? .*$')
re_into = re.compile('.* into "?([a-zA-Z_0-9]+)"? .*$')
sql_counter = 0
@ -226,11 +226,11 @@ class Cursor(object):
params = params or None
res = self._obj.execute(query, params)
except psycopg2.ProgrammingError, pe:
if (self._default_log_exceptions if log_exceptions is None else log_exceptions):
if self._default_log_exceptions if log_exceptions is None else log_exceptions:
_logger.error("Programming error: %s, in query %s", pe, query)
raise
except Exception:
if (self._default_log_exceptions if log_exceptions is None else log_exceptions):
if self._default_log_exceptions if log_exceptions is None else log_exceptions:
_logger.exception("bad query: %s", self._obj.query or query)
raise
@ -357,11 +357,6 @@ class Cursor(object):
def __getattr__(self, name):
return getattr(self._obj, name)
""" Set the mode of postgres operations for all cursors
"""
"""Obtain the mode of postgres operations for all cursors
"""
class PsycoConnection(psycopg2.extensions.connection):
pass
@ -521,8 +516,8 @@ def db_connect(db_name):
return Connection(_Pool, db_name)
def close_db(db_name):
global _Pool
""" You might want to call openerp.modules.registry.RegistryManager.delete(db_name) along this function."""
global _Pool
if _Pool:
_Pool.close_all(dsn(db_name))
ct = currentThread()

View File

@ -8,6 +8,7 @@ Tests can be explicitely added to the `fast_suite` or `checks` lists or not.
See the :ref:`test-framework` section in the :ref:`features` list.
"""
from . import test_acl
from . import test_expression, test_mail, test_ir_sequence, test_orm, \
test_fields, test_basecase, \
test_view_validation, test_uninstall, test_misc, test_db_cursor, \
@ -20,6 +21,7 @@ fast_suite = [
]
checks = [
test_acl,
test_expression,
test_mail,
test_db_cursor,

View File

@ -1,6 +1,9 @@
import unittest2
from lxml import etree
import openerp
from openerp.tools.misc import mute_logger
import common
# test group that demo user should not have
@ -55,6 +58,7 @@ class TestACL(common.TransactionCase):
self.tech_group.write({'users': [(3, self.demo_uid)]})
self.res_currency._columns['rate'].groups = False
@mute_logger('openerp.osv.orm')
def test_field_crud_restriction(self):
"Read/Write RPC access to restricted field should be forbidden"
# Verify the test environment first
@ -65,12 +69,10 @@ class TestACL(common.TransactionCase):
# Now restrict access to the field and check it's forbidden
self.res_partner._columns['bank_ids'].groups = GROUP_TECHNICAL_FEATURES
# FIXME TODO: enable next tests when access rights checks per field are implemented
# from openerp.osv.orm import except_orm
# with self.assertRaises(except_orm):
# self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids'])
# with self.assertRaises(except_orm):
# self.res_partner.write(self.cr, self.demo_uid, [1], {'bank_ids': []})
with self.assertRaises(openerp.osv.orm.except_orm):
self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids'])
with self.assertRaises(openerp.osv.orm.except_orm):
self.res_partner.write(self.cr, self.demo_uid, [1], {'bank_ids': []})
# Add the restricted group, and check that it works again
self.tech_group.write({'users': [(4, self.demo_uid)]})
@ -86,4 +88,4 @@ class TestACL(common.TransactionCase):
if __name__ == '__main__':
unittest2.main()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -53,31 +53,46 @@ class TestRelatedField(common.TransactionCase):
def test_1_single_related(self):
""" test a related field with a single indirection like fields.related('foo') """
# add a related field test_related_company_id on res.partner
# and simulate a _inherits_reload() to populate _all_columns.
old_columns = self.partner._columns
old_all_columns = self.partner._all_columns
self.partner._columns = dict(old_columns)
self.partner._all_columns = dict(old_all_columns)
self.partner._columns.update({
'single_related_company_id': fields.related('company_id', type='many2one', obj='res.company'),
})
self.partner._all_columns.update({
'single_related_company_id': fields.column_info('single_related_company_id', self.partner._columns['single_related_company_id'], None, None, None)
})
self.do_test_company_field('single_related_company_id')
# restore res.partner fields
self.partner._columns = old_columns
self.partner._all_columns = old_all_columns
def test_2_related_related(self):
""" test a related field referring to a related field """
# add a related field on a related field on res.partner
# and simulate a _inherits_reload() to populate _all_columns.
old_columns = self.partner._columns
old_all_columns = self.partner._all_columns
self.partner._columns = dict(old_columns)
self.partner._all_columns = dict(old_all_columns)
self.partner._columns.update({
'single_related_company_id': fields.related('company_id', type='many2one', obj='res.company'),
'related_related_company_id': fields.related('single_related_company_id', type='many2one', obj='res.company'),
})
self.partner._all_columns.update({
'single_related_company_id': fields.column_info('single_related_company_id', self.partner._columns['single_related_company_id'], None, None, None),
'related_related_company_id': fields.column_info('related_related_company_id', self.partner._columns['related_related_company_id'], None, None, None)
})
self.do_test_company_field('related_related_company_id')
# restore res.partner fields
self.partner._columns = old_columns
self.partner._all_columns = old_all_columns
def test_3_read_write(self):
""" write on a related field """

View File

@ -182,7 +182,7 @@ class TestO2MSerialization(common.TransactionCase):
def test_no_command(self):
" empty list of commands yields an empty list of records "
results = self.partner.resolve_2many_commands(
self.cr, UID, 'address', [])
self.cr, UID, 'child_ids', [])
self.assertEqual(results, [])
@ -190,7 +190,7 @@ class TestO2MSerialization(common.TransactionCase):
" returns the VALUES dict as-is "
values = [{'foo': 'bar'}, {'foo': 'baz'}, {'foo': 'baq'}]
results = self.partner.resolve_2many_commands(
self.cr, UID, 'address', map(CREATE, values))
self.cr, UID, 'child_ids', map(CREATE, values))
self.assertEqual(results, values)
@ -204,7 +204,7 @@ class TestO2MSerialization(common.TransactionCase):
commands = map(LINK_TO, ids)
results = self.partner.resolve_2many_commands(
self.cr, UID, 'address', commands, ['name'])
self.cr, UID, 'child_ids', commands, ['name'])
self.assertEqual(sorted_by_id(results), sorted_by_id([
{'id': ids[0], 'name': 'foo'},
@ -221,7 +221,7 @@ class TestO2MSerialization(common.TransactionCase):
]
results = self.partner.resolve_2many_commands(
self.cr, UID, 'address', ids, ['name'])
self.cr, UID, 'child_ids', ids, ['name'])
self.assertEqual(sorted_by_id(results), sorted_by_id([
{'id': ids[0], 'name': 'foo'},
@ -236,7 +236,7 @@ class TestO2MSerialization(common.TransactionCase):
id_baz = self.partner.create(self.cr, UID, {'name': 'baz', 'city': 'tag'})
results = self.partner.resolve_2many_commands(
self.cr, UID, 'address', [
self.cr, UID, 'child_ids', [
LINK_TO(id_foo),
UPDATE(id_bar, {'name': 'qux', 'city': 'tagtag'}),
UPDATE(id_baz, {'name': 'quux'})
@ -258,7 +258,7 @@ class TestO2MSerialization(common.TransactionCase):
commands = [DELETE(ids[0]), DELETE(ids[1]), DELETE(ids[2])]
results = self.partner.resolve_2many_commands(
self.cr, UID, 'address', commands, ['name'])
self.cr, UID, 'child_ids', commands, ['name'])
self.assertEqual(results, [])
@ -269,7 +269,7 @@ class TestO2MSerialization(common.TransactionCase):
]
results = self.partner.resolve_2many_commands(
self.cr, UID, 'address', [
self.cr, UID, 'child_ids', [
CREATE({'name': 'foo'}),
UPDATE(ids[0], {'name': 'bar'}),
LINK_TO(ids[1]),
@ -300,7 +300,7 @@ class TestO2MSerialization(common.TransactionCase):
commands = map(lambda id: (4, id), ids)
results = self.partner.resolve_2many_commands(
self.cr, UID, 'address', commands, ['name'])
self.cr, UID, 'child_ids', commands, ['name'])
self.assertEqual(sorted_by_id(results), sorted_by_id([
{'id': ids[0], 'name': 'foo'},
@ -311,7 +311,7 @@ class TestO2MSerialization(common.TransactionCase):
def test_singleton_commands(self):
"DELETE_ALL can appear as a singleton"
results = self.partner.resolve_2many_commands(
self.cr, UID, 'address', [DELETE_ALL()], ['name'])
self.cr, UID, 'child_ids', [DELETE_ALL()], ['name'])
self.assertEqual(results, [])

View File

@ -57,9 +57,9 @@ def _convert_nnn_fr(val):
if rem > 0:
word = to_19_fr[rem] + ' Cent'
if mod > 0:
word = word + ' '
word += ' '
if mod > 0:
word = word + _convert_nn_fr(mod)
word += _convert_nn_fr(mod)
return word
def french_number(val):
@ -125,9 +125,9 @@ def _convert_nnn_nl(val):
if rem > 0:
word = to_19_nl[rem] + ' Honderd'
if mod > 0:
word = word + ' '
word += ' '
if mod > 0:
word = word + _convert_nn_nl(mod)
word += _convert_nn_nl(mod)
return word
def dutch_number(val):

View File

@ -60,9 +60,9 @@ def _convert_nnn(val):
if rem > 0:
word = to_19[rem] + ' Hundred'
if mod > 0:
word = word + ' '
word += ' '
if mod > 0:
word = word + _convert_nn(mod)
word += _convert_nn(mod)
return word
def english_number(val):

View File

@ -352,7 +352,7 @@ class configmanager(object):
# Check if the config file exists (-c used, but not -s)
die(not opt.save and opt.config and not os.path.exists(opt.config),
"The config file '%s' selected with -c/--config doesn't exist, "\
"use -s/--save if you want to generate it"%(opt.config))
"use -s/--save if you want to generate it"% opt.config)
# place/search the config file on Win32 near the server installation
# (../etc from the server)

View File

@ -662,7 +662,7 @@ form: module.record_id""" % (xml_id,)
if rec.get('action') and pid:
action = "ir.actions.%s,%d" % (a_type, a_id)
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(pid))], action, True, True, xml_id=rec_id)
return ('ir.ui.menu', pid)
return 'ir.ui.menu', pid
def _assert_equals(self, f1, f2, prec=4):
return not round(f1 - f2, prec)

View File

@ -45,7 +45,7 @@ def frame_codeinfo(fframe, back=0):
try:
if not fframe:
return ("<unknown>", '')
return "<unknown>", ''
for i in range(back):
fframe = fframe.f_back
try:
@ -53,8 +53,8 @@ def frame_codeinfo(fframe, back=0):
except TypeError:
fname = '<builtin>'
lineno = fframe.f_lineno or ''
return (fname, lineno)
return fname, lineno
except Exception:
return ("<unknown>", '')
return "<unknown>", ''
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -51,7 +51,7 @@ class graph(object):
for link in self.links:
self.edge_wt[link] = self.result[link[1]]['x'] - self.result[link[0]]['x']
tot_node = self.partial_order.__len__()
tot_node = len(self.partial_order)
#do until all the nodes in the component are searched
while self.tight_tree()<tot_node:
list_node = []
@ -68,9 +68,9 @@ class graph(object):
slack = 100
for edge in list_edge:
if ((self.reachable_nodes.__contains__(edge[0]) and edge[1] not in self.reachable_nodes) or
(self.reachable_nodes.__contains__(edge[1]) and edge[0] not in self.reachable_nodes)):
if(slack>self.edge_wt[edge]-1):
if ((edge[0] in self.reachable_nodes and edge[1] not in self.reachable_nodes) or
(edge[1] in self.reachable_nodes and edge[0] not in self.reachable_nodes)):
if slack > self.edge_wt[edge]-1:
slack = self.edge_wt[edge]-1
new_edge = edge
@ -93,7 +93,7 @@ class graph(object):
self.reachable_nodes = []
self.tree_edges = []
self.reachable_node(self.start)
return self.reachable_nodes.__len__()
return len(self.reachable_nodes)
def reachable_node(self, node):
@ -117,13 +117,13 @@ class graph(object):
"""
self.cut_edges = {}
self.head_nodes = []
i=0;
i=0
for edge in self.tree_edges:
self.head_nodes = []
rest_edges = []
rest_edges += self.tree_edges
rest_edges.__delitem__(i)
del rest_edges[i]
self.head_component(self.start, rest_edges)
i+=1
positive = 0
@ -197,7 +197,7 @@ class graph(object):
des = link[1]
edge_len = self.partial_order[des]['level'] - self.partial_order[src]['level']
if edge_len < 0:
self.links.__delitem__(i)
del self.links[i]
self.links.insert(i, (des, src))
self.transitions[src].remove(des)
self.transitions.setdefault(des, []).append(src)
@ -210,10 +210,10 @@ class graph(object):
def exchange(self, e, f):
"""Exchange edges to make feasible-tree optimized
@param edge edge with negative cut-value
@param edge new edge with minimum slack-value
:param e: edge with negative cut-value
:param f: new edge with minimum slack-value
"""
self.tree_edges.__delitem__(self.tree_edges.index(e))
del self.tree_edges[self.tree_edges.index(e)]
self.tree_edges.append(f)
self.init_cutvalues()
@ -227,13 +227,13 @@ class graph(object):
self.head_nodes = []
rest_edges = []
rest_edges += self.tree_edges
rest_edges.__delitem__(rest_edges.index(edge))
del rest_edges[rest_edges.index(edge)]
self.head_component(self.start, rest_edges)
if self.head_nodes.__contains__(edge[1]):
if edge[1] in self.head_nodes:
l = []
for node in self.result:
if not self.head_nodes.__contains__(node):
if node not in self.head_nodes:
l.append(node)
self.head_nodes = l
@ -243,7 +243,7 @@ class graph(object):
if source_node in self.head_nodes:
for dest_node in self.transitions[source_node]:
if dest_node not in self.head_nodes:
if(slack>(self.edge_wt[edge]-1)):
if slack>(self.edge_wt[edge]-1):
slack = self.edge_wt[edge]-1
new_edge = (source_node, dest_node)
@ -276,7 +276,7 @@ class graph(object):
least_rank = min(map(lambda x: x['x'], self.result.values()))
if(least_rank!=0):
if least_rank!=0:
for node in self.result:
self.result[node]['x']-=least_rank
@ -310,7 +310,7 @@ class graph(object):
"""
if not self.result[node]['y']:
self.result[node]['y'] = self.order[level]
self.order[level] = self.order[level]+1
self.order[level] += 1
for sec_end in self.transitions.get(node, []):
if node!=sec_end:
@ -377,7 +377,7 @@ class graph(object):
if pre_level_nodes:
for src in pre_level_nodes:
if (self.transitions.get(src) and self.transitions[src].__contains__(node)):
if self.transitions.get(src) and node in self.transitions[src]:
adj_nodes.append(self.result[src]['y'])
return adj_nodes
@ -455,7 +455,7 @@ class graph(object):
mid_node = l[no/2]
self.result[mid_node]['y'] = mid_pos
if self.transitions.get((mid_node), False):
if self.transitions.get(mid_node, False):
if last:
self.result[mid_node]['y'] = last + len(self.transitions[mid_node])/2 + 1
if node!=mid_node:
@ -494,7 +494,7 @@ class graph(object):
if max_level%2:
self.result[self.start]['y'] = (max_level+1)/2 + self.max_order + (self.max_order and 1)
else:
self.result[self.start]['y'] = (max_level)/2 + self.max_order + (self.max_order and 1)
self.result[self.start]['y'] = max_level /2 + self.max_order + (self.max_order and 1)
self.graph_order()
@ -511,7 +511,7 @@ class graph(object):
for start in self.start_nodes[:index]:
same = True
for edge in self.tree_list[start][1:]:
if self.tree_list[self.start].__contains__(edge):
if edge in self.tree_list[self.start]:
continue
else:
same = False
@ -590,9 +590,9 @@ class graph(object):
for edge in largest_tree:
if rem_nodes.__contains__(edge[0]):
if edge[0] in rem_nodes:
rem_nodes.remove(edge[0])
if rem_nodes.__contains__(edge[1]):
if edge[1] in rem_nodes:
rem_nodes.remove(edge[1])
if not rem_nodes:
@ -601,8 +601,6 @@ class graph(object):
def rank(self):
"""Finds the optimized rank of the nodes using Network-simplex algorithm
@param start starting node of the component
"""
self.levels = {}
self.critical_edges = []
@ -641,8 +639,6 @@ class graph(object):
def order_in_rank(self):
"""Finds optimized order of the nodes within their ranks using median heuristic
@param start: starting node of the component
"""
self.make_chain()
@ -716,7 +712,7 @@ class graph(object):
#for flat edges ie. source an destination nodes are on the same rank
for src in self.transitions:
for des in self.transitions[src]:
if (self.result[des]['x'] - self.result[src]['x'] == 0):
if self.result[des]['x'] - self.result[src]['x'] == 0:
self.result[src]['x'] += 0.08
self.result[des]['x'] -= 0.08

View File

@ -23,7 +23,7 @@ import io
import StringIO
from PIL import Image
from PIL import ImageEnhance
from PIL import ImageEnhance, ImageOps
from random import random
# ----------------------------------------
@ -64,7 +64,6 @@ def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', file
return False
if size == (None, None):
return base64_source
image_stream = io.BytesIO(base64_source.decode(encoding))
image = Image.open(image_stream)
@ -78,17 +77,13 @@ def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', file
# check image size: do not create a thumbnail if avoiding smaller images
if avoid_if_small and image.size[0] <= size[0] and image.size[1] <= size[1]:
return base64_source
# create a thumbnail: will resize and keep ratios, then sharpen for better looking result
image.thumbnail(size, Image.ANTIALIAS)
sharpener = ImageEnhance.Sharpness(image.convert('RGBA'))
image = sharpener.enhance(2.0)
# create a transparent image for background
background = Image.new('RGBA', size, (255, 255, 255, 0))
# past the resized image on the background
background.paste(image, ((size[0] - image.size[0]) / 2, (size[1] - image.size[1]) / 2))
# return an encoded image
if image.size <> size:
# If you need faster thumbnails you may use use Image.NEAREST
image = ImageOps.fit(image, size, Image.ANTIALIAS)
background_stream = StringIO.StringIO()
background.save(background_stream, filetype)
image.save(background_stream, filetype)
return background_stream.getvalue().encode(encoding)
def image_resize_image_big(base64_source, size=(1204, 1204), encoding='base64', filetype='PNG', avoid_if_small=True):
@ -170,3 +165,13 @@ def image_get_resized_images(base64_source, return_big=False, return_medium=True
return_dict[small_name] = image_resize_image_small(base64_source, avoid_if_small=avoid_resize_small)
return return_dict
if __name__=="__main__":
import sys
assert len(sys.argv)==3, 'Usage to Test: image.py SRC.png DEST.png'
img = file(sys.argv[1],'rb').read().encode('base64')
new = image_resize_image(img, (128,100))
file(sys.argv[2], 'wb').write(new.decode('base64'))

View File

@ -77,7 +77,7 @@ class LRU(object):
@synchronized()
def __iter__(self):
cur = self.first
while cur != None:
while cur is not None:
cur2 = cur.next
yield cur.me[1]
cur = cur2
@ -89,7 +89,7 @@ class LRU(object):
@synchronized()
def iteritems(self):
cur = self.first
while cur != None:
while cur is not None:
cur2 = cur.next
yield cur.me
cur = cur2

View File

@ -92,7 +92,7 @@ def exec_pg_command_pipe(name, *args):
pop = subprocess.Popen((prog,) + args, bufsize= -1,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
close_fds=(os.name=="posix"))
return (pop.stdin, pop.stdout)
return pop.stdin, pop.stdout
def exec_command_pipe(name, *args):
prog = find_in_path(name)
@ -103,7 +103,7 @@ def exec_command_pipe(name, *args):
pop = subprocess.Popen((prog,) + args, bufsize= -1,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
close_fds=(os.name=="posix"))
return (pop.stdin, pop.stdout)
return pop.stdin, pop.stdout
#----------------------------------------------------------
# File paths
@ -181,7 +181,7 @@ def _fileopen(path, mode, basedir, pathinfo, basename=None):
if os.path.isfile(name):
fo = open(name, mode)
if pathinfo:
return (fo, name)
return fo, name
return fo
# Support for loading modules in zipped form.
@ -208,7 +208,7 @@ def _fileopen(path, mode, basedir, pathinfo, basename=None):
os.sep, '/')))
fo.seek(0)
if pathinfo:
return (fo, name)
return fo, name
return fo
except Exception:
pass
@ -561,8 +561,8 @@ def human_size(sz):
sz=len(sz)
s, i = float(sz), 0
while s >= 1024 and i < len(units)-1:
s = s / 1024
i = i + 1
s /= 1024
i += 1
return "%0.2f %s" % (s, units[i])
def logged(f):
@ -725,7 +725,7 @@ def get_win32_timezone():
@return the standard name of the current win32 timezone, or False if it cannot be found.
"""
res = False
if (sys.platform == "win32"):
if sys.platform == "win32":
try:
import _winreg
hklm = _winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE)
@ -756,7 +756,7 @@ def detect_server_timezone():
(time.tzname[0], 'time.tzname'),
(os.environ.get('TZ',False),'TZ environment variable'), ]
# Option 4: OS-specific: /etc/timezone on Unix
if (os.path.exists("/etc/timezone")):
if os.path.exists("/etc/timezone"):
tz_value = False
try:
f = open("/etc/timezone")
@ -767,7 +767,7 @@ def detect_server_timezone():
f.close()
sources.append((tz_value,"/etc/timezone file"))
# Option 5: timezone info from registry on Win32
if (sys.platform == "win32"):
if sys.platform == "win32":
# Timezone info is stored in windows registry.
# However this is not likely to work very well as the standard name
# of timezones in windows is rarely something that is known to pytz.

View File

@ -27,16 +27,16 @@ import os
from os.path import join as opj
def listdir(dir, recursive=False):
"""Allow to recursively get the file listing"""
dir = os.path.normpath(dir)
if not recursive:
return os.listdir(dir)
"""Allow to recursively get the file listing"""
dir = os.path.normpath(dir)
if not recursive:
return os.listdir(dir)
res = []
for root, dirs, files in walksymlinks(dir):
root = root[len(dir)+1:]
res.extend([opj(root, f) for f in files])
return res
res = []
for root, dirs, files in walksymlinks(dir):
root = root[len(dir)+1:]
res.extend([opj(root, f) for f in files])
return res
def walksymlinks(top, topdown=True, onerror=None):
"""
@ -58,7 +58,7 @@ def walksymlinks(top, topdown=True, onerror=None):
if __name__ == '__main__':
from pprint import pprint as pp
pp(listdir('../report', True))
from pprint import pprint as pp
pp(listdir('../report', True))
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -93,7 +93,6 @@ _LOCALE2WIN32 = {
'lt_LT': 'Lithuanian_Lithuania',
'lat': 'Latvian_Latvia',
'ml_IN': 'Malayalam_India',
'id_ID': 'Indonesian_indonesia',
'mi_NZ': 'Maori',
'mn': 'Cyrillic_Mongolian',
'no_NO': 'Norwegian_Norway',
@ -103,7 +102,6 @@ _LOCALE2WIN32 = {
'pt_BR': 'Portuguese_Brazil',
'ro_RO': 'Romanian_Romania',
'ru_RU': 'Russian_Russia',
'mi_NZ': 'Maori',
'sr_CS': 'Serbian (Cyrillic)_Serbia and Montenegro',
'sk_SK': 'Slovak_Slovakia',
'sl_SI': 'Slovenian_Slovenia',
@ -131,7 +129,6 @@ _LOCALE2WIN32 = {
'sv_SE': 'Swedish_Sweden',
'ta_IN': 'English_Australia',
'th_TH': 'Thai_Thailand',
'mi_NZ': 'Maori',
'tr_TR': 'Turkish_Turkey',
'uk_UA': 'Ukrainian_Ukraine',
'vi_VN': 'Vietnamese_Viet Nam',
@ -275,7 +272,7 @@ class TinyPoFile(object):
def __iter__(self):
self.buffer.seek(0)
self.lines = self._get_lines()
self.lines_count = len(self.lines);
self.lines_count = len(self.lines)
self.first = True
self.extra_lines= []
@ -291,7 +288,7 @@ class TinyPoFile(object):
return lines
def cur_line(self):
return (self.lines_count - len(self.lines))
return self.lines_count - len(self.lines)
def next(self):
trans_type = name = res_id = source = trad = None
@ -304,7 +301,7 @@ class TinyPoFile(object):
targets = []
line = None
fuzzy = False
while (not line):
while not line:
if 0 == len(self.lines):
raise StopIteration()
line = self.lines.pop(0).strip()
@ -864,7 +861,7 @@ def trans_generate(lang, modules, cr):
frelativepath = fabsolutepath[len(path):]
display_path = "addons%s" % frelativepath
module = get_module_from_path(fabsolutepath, mod_paths=mod_paths)
if (('all' in modules) or (module in modules)) and module in installed_modules:
if ('all' in modules or module in modules) and module in installed_modules:
return module, fabsolutepath, frelativepath, display_path
return None, None, None, None

View File

@ -126,7 +126,7 @@ def _execute(cr, workitem, activity, ident, stack):
_state_set(cr, workitem, activity, 'running', ident)
if activity.get('action', False):
id_new = wkf_expr.execute(cr, ident, workitem, activity)
if not (id_new):
if not id_new:
cr.execute('delete from wkf_workitem where id=%s', (workitem['id'],))
return False
assert type(id_new)==type(1) or type(id_new)==type(1L), 'Wrong return value: '+str(id_new)+' '+str(type(id_new))

View File

@ -62,7 +62,7 @@ def py2exe_options():
"skip_archive": 1,
"optimize": 2,
"dist_dir": 'dist',
"packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "docutils", "email", "encodings", "imaplib", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "pytz", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber", "vobject", "xml", "xml.dom", "yaml", ],
"packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "docutils", "email", "encodings", "imaplib", "Jinja2", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "pytz", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber", "vobject", "xml", "xml.dom", "yaml", ],
"excludes" : ["Tkconstants","Tkinter","tcl"],
}
}
@ -106,7 +106,8 @@ setuptools.setup(
'docutils',
'feedparser',
'gdata',
'lxml < 3', # windows binary http://www.lfd.uci.edu/~gohlke/pythonlibs/
'Jinja2',
'lxml', # windows binary http://www.lfd.uci.edu/~gohlke/pythonlibs/
'mako',
'mock',
'PIL', # windows binary http://www.lfd.uci.edu/~gohlke/pythonlibs/