[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-docutils,
python-feedparser, python-feedparser,
python-gdata, python-gdata,
python-jinja2,
python-ldap, python-ldap,
python-libxslt1, python-libxslt1,
python-lxml, 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'). 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 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``. .. 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 Workflow transition rules
+++++++++++++++++++++++++ +++++++++++++++++++++++++

View File

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

View File

@ -27,5 +27,15 @@ OpenERP Server API
api_core.rst api_core.rst
api_models.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 # OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). # 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 # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # 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', 'res/ir_property_view.xml',
'security/base_security.xml', 'security/base_security.xml',
'security/ir.model.access.csv', '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': [ 'demo': [
'base_demo.xml', 'base_demo.xml',

View File

@ -149,7 +149,6 @@ CREATE TABLE res_users (
active boolean default True, active boolean default True,
login varchar(64) NOT NULL UNIQUE, login varchar(64) NOT NULL UNIQUE,
password varchar(64) default null, password varchar(64) default null,
lang varchar(64) default '',
-- No FK references below, will be added later by ORM -- No FK references below, will be added later by ORM
-- (when the destination rows exist) -- (when the destination rows exist)
company_id int, company_id int,
@ -316,13 +315,29 @@ CREATE TABLE ir_module_module_dependency (
primary key(id) primary key(id)
); );
CREATE TABLE res_company ( CREATE TABLE res_partner (
id serial NOT NULL, id serial NOT NULL,
name character varying(64) not null, name character varying(128),
parent_id integer references res_company on delete set null, lang varchar(64),
company_id int,
primary key(id) 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 ( CREATE TABLE res_lang (
id serial PRIMARY KEY, id serial PRIMARY KEY,
name VARCHAR(64) NOT NULL UNIQUE, 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, module integer NOT NULL references ir_module_module on delete restrict,
model integer NOT NULL references ir_model on delete restrict, model integer NOT NULL references ir_model on delete restrict,
name character varying(128) NOT NULL name character varying(128) NOT NULL
); );
--------------------------------- ---------------------------------
-- Users -- 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 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 ('user_root','base','res.users',True,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 res_currency (id, name) VALUES (1, 'EUR');
insert into ir_model_data (name,module,model,noupdate,res_id) values ('user_admin','base','res.users',True,1); 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_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}"> <record id="main_partner" model="res.partner" context="{'default_is_company': True}">
<field name="name">Your Company</field> <field name="name">Your Company</field>
<field name="company_id" eval="None"/> <field name="company_id" eval="None"/>
<field name="image" eval="False"/>
<field name="customer" eval="False"/> <field name="customer" eval="False"/>
<field name="is_company" eval="True"/> <field name="is_company" eval="True"/>
<field name="street"></field> <field name="street"></field>

View File

@ -7,6 +7,74 @@
<field name="customer" eval="False"/> <field name="customer" eval="False"/>
<field name="email">demo@example.com</field> <field name="email">demo@example.com</field>
</record> </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"> <record id="user_demo" model="res.users">
<field name="partner_id" ref="base.partner_demo"/> <field name="partner_id" ref="base.partner_demo"/>
<field name="login">demo</field> <field name="login">demo</field>
@ -14,7 +82,7 @@
<field name="signature">-- <field name="signature">--
Mr Demo</field> Mr Demo</field>
<field name="company_id" ref="main_company"/> <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 <field name="image">/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEP
ERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4e ERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4e
Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCACEAIQDASIA Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCACEAIQDASIA

View File

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

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-server\n" "Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\n" "POT-Creation-Date: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-08-20 15:47+0000\n" "PO-Revision-Date: 2012-12-17 20:41+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n" "Last-Translator: David Bowers <sales@skitzotek.com>\n"
"Language-Team: English (United Kingdom) <en_GB@li.org>\n" "Language-Team: English (United Kingdom) <en_GB@li.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 05:02+0000\n" "X-Launchpad-Export-Date: 2012-12-18 04:58+0000\n"
"X-Generator: Launchpad (build 16335)\n" "X-Generator: Launchpad (build 16372)\n"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_account_check_writing #: 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 " "The second argument of the many2many field %s must be a SQL table !You used "
"%s, which is not a valid SQL table name." "%s, which is not a valid SQL table name."
msgstr "" 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." "%s, which is not a valid SQL table name."
#. module: base #. module: base
@ -101,7 +101,7 @@ msgstr ""
msgid "" msgid ""
"Model name on which the method to be called is located, e.g. 'res.partner'." "Model name on which the method to be called is located, e.g. 'res.partner'."
msgstr "" 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 #. module: base
#: view:ir.module.module:0 #: view:ir.module.module:0
@ -123,6 +123,17 @@ msgid ""
" * Product Attributes\n" " * Product Attributes\n"
" " " "
msgstr "" 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 #. module: base
#: field:ir.actions.client,params:0 #: field:ir.actions.client,params:0
@ -226,6 +237,35 @@ msgid ""
"* Planned Revenue by Stage and User (graph)\n" "* Planned Revenue by Stage and User (graph)\n"
"* Opportunities by Stage (graph)\n" "* Opportunities by Stage (graph)\n"
msgstr "" 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 #. module: base
#: code:addons/base/ir/ir_model.py:397 #: code:addons/base/ir/ir_model.py:397
@ -235,7 +275,7 @@ msgid ""
"them through Python code, preferably through a custom addon!" "them through Python code, preferably through a custom addon!"
msgstr "" msgstr ""
"Properties of base fields cannot be altered in this manner! Please modify " "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 #. module: base
#: code:addons/osv.py:130 #: code:addons/osv.py:130
@ -318,6 +358,7 @@ msgid ""
"The internal user that is in charge of communicating with this contact if " "The internal user that is in charge of communicating with this contact if "
"any." "any."
msgstr "" msgstr ""
"The internal user who is in charge of communicating with this contact if any."
#. module: base #. module: base
#: view:res.partner:0 #: view:res.partner:0
@ -625,6 +666,19 @@ msgid ""
"* Use emails to automatically confirm and send acknowledgements for any " "* Use emails to automatically confirm and send acknowledgements for any "
"event registration\n" "event registration\n"
msgstr "" 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 #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
@ -860,7 +914,7 @@ msgstr "Eritrea"
#. module: base #. module: base
#: sql_constraint:res.company:0 #: sql_constraint:res.company:0
msgid "The company name must be unique !" msgid "The company name must be unique !"
msgstr "The company name must be unique !" msgstr "The company name must be unique!"
#. module: base #. module: base
#: model:ir.ui.menu,name:base.menu_base_action_rule_admin #: 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 " "image, with aspect ratio preserved. Use this field anywhere a small image is "
"required." "required."
msgstr "" 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 #. module: base
#: help:ir.actions.server,mobile:0 #: help:ir.actions.server,mobile:0
@ -892,7 +949,7 @@ msgid ""
"invoice, then `object.invoice_address_id.mobile` is the field which gives " "invoice, then `object.invoice_address_id.mobile` is the field which gives "
"the correct mobile number" "the correct mobile number"
msgstr "" 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 " "invoice, then `object.invoice_address_id.mobile` is the field which gives "
"the correct mobile number" "the correct mobile number"
@ -988,8 +1045,6 @@ msgid ""
"Provide the field name that the record id refers to for the write operation. " "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." "If it is empty it will refer to the active id of the object."
msgstr "" 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 #. module: base
#: help:ir.actions.report.xml,report_type:0 #: help:ir.actions.report.xml,report_type:0
@ -1089,6 +1144,13 @@ msgid ""
"actions(Sign in/Sign out) performed by them.\n" "actions(Sign in/Sign out) performed by them.\n"
" " " "
msgstr "" 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 #. module: base
#: model:res.country,name:base.nu #: model:res.country,name:base.nu
@ -1148,7 +1210,7 @@ msgid ""
msgstr "" msgstr ""
"Expression containing a value specification. \n" "Expression containing a value specification. \n"
"When Formula type is selected, this field may be a Python expression that " "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 " "If Value type is selected, the value will be used directly without "
"evaluation." "evaluation."
@ -1234,7 +1296,7 @@ msgstr "Guam (USA)"
#. module: base #. module: base
#: sql_constraint:res.country:0 #: sql_constraint:res.country:0
msgid "The name of the country must be unique !" 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 #. module: base
#: field:ir.module.module,installed_version:0 #: 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 " "decimal number [00,53]. All days in a new year preceding the first Monday "
"are considered to be in week 0." "are considered to be in week 0."
msgstr "" msgstr ""
"%W - Week number of the year (Monday as the first day of the week) as a " "%W - Week number of the year (Monday being the first day of the week) as an "
"decimal number [00,53]. All days in a new year preceding the first Monday " "integer [00,53]. All days in a new year preceding the first Monday are "
"are considered to be in week 0." "considered to be in week 0."
#. module: base #. module: base
#: code:addons/base/module/wizard/base_language_install.py:53 #: 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 " "'%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" "used to refer to other modules data, as in module.reference_id"
msgstr "" msgstr ""
"'%s' contains too many dots. XML ids should not contain dots ! These are " "'%s' contains too many dots. XML ids should not contain dots! These are used "
"used to refer to other modules data, as in module.reference_id" "to refer to other modules' data, as in module.reference_id"
#. module: base #. module: base
#: model:ir.module.module,summary:base.module_sale #: model:ir.module.module,summary:base.module_sale
@ -1872,8 +1934,8 @@ msgid ""
"simplified payment mode encoding, automatic picking lists generation and " "simplified payment mode encoding, automatic picking lists generation and "
"more." "more."
msgstr "" msgstr ""
"Get the most out of your points of sales with fast sale encoding, simplified " "Get the most out of your points of sale with fast sale encoding, simplified "
"payment mode encoding, automatic picking lists generation and more." "payment mode encoding, automatic pick list generation and more."
#. module: base #. module: base
#: code:addons/base/ir/ir_fields.py:165 #: code:addons/base/ir/ir_fields.py:165
@ -2021,6 +2083,14 @@ msgid ""
"with the effect of creating, editing and deleting either ways.\n" "with the effect of creating, editing and deleting either ways.\n"
" " " "
msgstr "" 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 #. module: base
#: model:ir.model,name:base.model_ir_model_access #: 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 " "* *Before Delivery*: A Draft invoice is created and must be paid before "
"delivery\n" "delivery\n"
msgstr "" 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 #. module: base
#: field:ir.ui.menu,complete_name:0 #: 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 " "decimal number [00,53]. All days in a new year preceding the first Sunday "
"are considered to be in week 0." "are considered to be in week 0."
msgstr "" msgstr ""
"%U - Week number of the year (Sunday as the first day of the week) as a " "%U - Week number of the year (Sunday being the first day of the week) as an "
"decimal number [00,53]. All days in a new year preceding the first Sunday " "integer [00,53]. All days in a new year preceding the first Sunday are "
"are considered to be in week 0." "considered to be in week 0."
#. module: base #. module: base
#: view:base.language.export:0 #: view:base.language.export:0
@ -2316,6 +2405,28 @@ msgid ""
"* Maximal difference between timesheet and attendances\n" "* Maximal difference between timesheet and attendances\n"
" " " "
msgstr "" 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 #. module: base
#: code:addons/base/ir/ir_fields.py:342 #: code:addons/base/ir/ir_fields.py:342
@ -2371,7 +2482,7 @@ msgstr "Belize"
#. module: base #. module: base
#: help:ir.actions.report.xml,header:0 #: help:ir.actions.report.xml,header:0
msgid "Add or not the corporate RML header" 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 #. module: base
#: model:res.country,name:base.ge #: model:res.country,name:base.ge
@ -2410,6 +2521,32 @@ msgid ""
"\n" "\n"
" " " "
msgstr "" 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 #. module: base
#: model:res.country,name:base.pl #: 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 = " "order in Object, and you can have loop on the sales order line. Expression = "
"`object.order_line`." "`object.order_line`."
msgstr "" msgstr ""
"Enter the field/expression that will return the list. E.g. select the sale " "Enter the field/expression that will return the list. E.g. selecting the "
"order in Object, and you can have loop on the sales order line. Expression = " "sale order in Object, you can loop on the sales order line: Expression = "
"`object.order_line`." "`object.order_line`."
#. module: base #. module: base
@ -2546,6 +2683,27 @@ msgid ""
"Print product labels with barcode.\n" "Print product labels with barcode.\n"
" " " "
msgstr "" 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 #. module: base
#: model:ir.module.module,description:base.module_account_analytic_default #: model:ir.module.module,description:base.module_account_analytic_default
@ -2563,6 +2721,18 @@ msgid ""
" * Date\n" " * Date\n"
" " " "
msgstr "" 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 #. module: base
#: field:res.company,rml_header1:0 #: field:res.company,rml_header1:0
@ -2887,6 +3057,29 @@ msgid ""
"* Purchase Analysis\n" "* Purchase Analysis\n"
" " " "
msgstr "" 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 #. module: base
#: model:ir.model,name:base.model_ir_actions_act_window_close #: model:ir.model,name:base.model_ir_actions_act_window_close
@ -3016,6 +3209,15 @@ msgid ""
" * ``base_stage``: stage management\n" " * ``base_stage``: stage management\n"
" " " "
msgstr "" 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 #. module: base
#: model:ir.module.module,shortdesc:base.module_web_linkedin #: 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 " "For more details about translating OpenERP in your language, please refer to "
"the" "the"
msgstr "" msgstr ""
"For more details about translating OpenERP into your language, please refer "
"to the"
#. module: base #. module: base
#: field:res.partner,image:0 #: field:res.partner,image:0
@ -3563,19 +3767,11 @@ msgid ""
"Canadian accounting charts and localizations.\n" "Canadian accounting charts and localizations.\n"
" " " "
msgstr "" 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 #. module: base
#: view:base.module.import:0 #: view:base.module.import:0
msgid "Select module package to import (.zip file):" 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 #. module: base
#: view:ir.filters:0 #: view:ir.filters:0
@ -3674,6 +3870,14 @@ msgid ""
"easily\n" "easily\n"
"keep track and order all your purchase orders.\n" "keep track and order all your purchase orders.\n"
msgstr "" 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 #. module: base
#: help:ir.mail_server,smtp_host:0 #: 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 #: code:addons/orm.py:4213
#, python-format #, python-format
msgid "Recursivity Detected." msgid "Recursivity Detected."
msgstr "Recursivity detected." msgstr "Recursion detected."
#. module: base #. module: base
#: code:addons/base/module/module.py:345 #: code:addons/base/module/module.py:345
#, python-format #, python-format
msgid "Recursion error in modules dependencies !" msgid "Recursion error in modules dependencies !"
msgstr "Recursion error in modules dependencies !" msgstr "Recursion error in modules dependencies!"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_analytic_user_function #: 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 #. module: base
#: constraint:res.partner.category:0 #: constraint:res.partner.category:0
msgid "Error ! You can not create recursive categories." 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 #. module: base
#: view:res.lang:0 #: view:res.lang:0

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n" "Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\n" "POT-Creation-Date: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-12-11 00:59+0000\n" "PO-Revision-Date: 2012-12-13 16:14+0000\n"
"Last-Translator: Santi (Pexego) <santiago@pexego.es>\n" "Last-Translator: Roberto Lizana (trey.es) <Unknown>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-12 04:38+0000\n" "X-Launchpad-Export-Date: 2012-12-14 05:35+0000\n"
"X-Generator: Launchpad (build 16361)\n" "X-Generator: Launchpad (build 16369)\n"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_account_check_writing #: 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 " "Database ID of record to open in form view, when ``view_mode`` is set to "
"'form' only" "'form' only"
msgstr "" 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 #. module: base
#: field:res.partner.address,name:0 #: field:res.partner.address,name:0
@ -871,6 +873,11 @@ msgid ""
"This module provides the Integration of the LinkedIn with OpenERP.\n" "This module provides the Integration of the LinkedIn with OpenERP.\n"
" " " "
msgstr "" msgstr ""
"\n"
"Módulo web de LinkedIn para OpenERP.\n"
"=================================\n"
"Este módulo provee integración de LinkedIn con OpenERP.\n"
" "
#. module: base #. module: base
#: help:ir.actions.act_window,src_model:0 #: help:ir.actions.act_window,src_model:0
@ -918,7 +925,7 @@ msgstr "Rumanía - Contabilidad"
#. module: base #. module: base
#: model:ir.model,name:base.model_res_config_settings #: model:ir.model,name:base.model_res_config_settings
msgid "res.config.settings" msgid "res.config.settings"
msgstr "" msgstr "Parámetros de configuración"
#. module: base #. module: base
#: help:res.partner,image_small:0 #: help:res.partner,image_small:0
@ -1073,6 +1080,7 @@ msgstr "Zimbabwe"
msgid "" msgid ""
"Type of the constraint: `f` for a foreign key, `u` for other constraints." "Type of the constraint: `f` for a foreign key, `u` for other constraints."
msgstr "" msgstr ""
"Tipo de restricción: 'f' para un clave ajena, 'u' para otras restricciones."
#. module: base #. module: base
#: view:ir.actions.report.xml:0 #: view:ir.actions.report.xml:0
@ -1214,7 +1222,7 @@ msgstr "Principado de Andorra"
#. module: base #. module: base
#: field:ir.rule,perm_read:0 #: field:ir.rule,perm_read:0
msgid "Apply for Read" msgid "Apply for Read"
msgstr "" msgstr "Aplicar para lectura"
#. module: base #. module: base
#: model:res.country,name:base.mn #: model:res.country,name:base.mn
@ -1244,7 +1252,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:727 #: code:addons/base/ir/ir_model.py:727
#, python-format #, python-format
msgid "Document model" msgid "Document model"
msgstr "" msgstr "Modelo de documento"
#. module: base #. module: base
#: view:res.lang:0 #: 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" "Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\n" "POT-Creation-Date: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-08-20 15:46+0000\n" "PO-Revision-Date: 2012-12-17 19:42+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n" "Last-Translator: Ahti Hinnov <sipelgas@gmail.com>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 04:55+0000\n" "X-Launchpad-Export-Date: 2012-12-18 04:57+0000\n"
"X-Generator: Launchpad (build 16335)\n" "X-Generator: Launchpad (build 16372)\n"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_account_check_writing #: model:ir.module.module,description:base.module_account_check_writing
@ -11604,7 +11604,7 @@ msgstr "Aruande tüüp"
#: view:res.country.state:0 #: view:res.country.state:0
#: field:res.partner,state_id:0 #: field:res.partner,state_id:0
msgid "State" msgid "State"
msgstr "Olek" msgstr "Maakond"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: 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" "Project-Id-Version: OpenERP Server 6.0.0-rc1\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\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" "Last-Translator: gobi <Unknown>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 04:58+0000\n" "X-Launchpad-Export-Date: 2012-12-18 04:58+0000\n"
"X-Generator: Launchpad (build 16335)\n" "X-Generator: Launchpad (build 16372)\n"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_account_check_writing #: model:ir.module.module,description:base.module_account_check_writing
@ -357,6 +357,10 @@ msgid ""
"\n" "\n"
" " " "
msgstr "" msgstr ""
"\n"
"p\n"
"\n"
" "
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_sale #: model:ir.module.module,shortdesc:base.module_sale
@ -614,7 +618,7 @@ msgstr "Харьцааны Нэр"
#. module: base #. module: base
#: view:ir.rule:0 #: view:ir.rule:0
msgid "Create Access Right" msgid "Create Access Right"
msgstr "" msgstr "Хандах Эрх Үүсгэх"
#. module: base #. module: base
#: model:res.country,name:base.tv #: model:res.country,name:base.tv
@ -1346,7 +1350,7 @@ msgstr "Андорра, Principality of"
#. module: base #. module: base
#: field:ir.rule,perm_read:0 #: field:ir.rule,perm_read:0
msgid "Apply for Read" msgid "Apply for Read"
msgstr "" msgstr "Уншихаар Хэрэгжүүлэх"
#. module: base #. module: base
#: model:res.country,name:base.mn #: model:res.country,name:base.mn
@ -1431,7 +1435,7 @@ msgstr "Сүүлийн Хувилбар"
#. module: base #. module: base
#: view:ir.rule:0 #: view:ir.rule:0
msgid "Delete Access Right" msgid "Delete Access Right"
msgstr "" msgstr "Хандах Эрхийг Устгах"
#. module: base #. module: base
#: code:addons/base/ir/ir_mail_server.py:213 #: code:addons/base/ir/ir_mail_server.py:213
@ -1486,7 +1490,7 @@ msgstr "Дэмжигчид"
#. module: base #. module: base
#: field:ir.rule,perm_unlink:0 #: field:ir.rule,perm_unlink:0
msgid "Apply for Delete" msgid "Apply for Delete"
msgstr "" msgstr "Устгахаар Хэрэгжүүлэх"
#. module: base #. module: base
#: selection:ir.property,type:0 #: selection:ir.property,type:0
@ -1561,6 +1565,9 @@ msgid ""
" for uploading to OpenERP's translation " " for uploading to OpenERP's translation "
"platform," "platform,"
msgstr "" msgstr ""
"TGZ формат: Энэ нь шахагдсан архив бөгөөд PO файлуудыг агуулсан\n"
" шууд OpenERP-н орчуулгын хөрсрүү хуулахад "
"тохиромжтой файл юм."
#. module: base #. module: base
#: view:res.lang:0 #: view:res.lang:0
@ -1587,7 +1594,7 @@ msgstr "Тест"
#. module: base #. module: base
#: field:ir.actions.report.xml,attachment:0 #: field:ir.actions.report.xml,attachment:0
msgid "Save as Attachment Prefix" msgid "Save as Attachment Prefix"
msgstr "" msgstr "Хавсралтыг нэрлэж хадгалах угтвар"
#. module: base #. module: base
#: field:ir.ui.view_sc,res_id:0 #: field:ir.ui.view_sc,res_id:0
@ -1624,7 +1631,7 @@ msgstr "Гаити"
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_fr_hr_payroll #: model:ir.module.module,shortdesc:base.module_l10n_fr_hr_payroll
msgid "French Payroll" msgid "French Payroll"
msgstr "" msgstr "Фран Цалин"
#. module: base #. module: base
#: view:ir.ui.view:0 #: view:ir.ui.view:0
@ -1698,6 +1705,33 @@ msgid ""
"Also implements IETF RFC 5785 for services discovery on a http server,\n" "Also implements IETF RFC 5785 for services discovery on a http server,\n"
"which needs explicit configuration in openerp-server.conf too.\n" "which needs explicit configuration in openerp-server.conf too.\n"
msgstr "" 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 #. module: base
#: model:ir.module.category,name:base.module_category_purchase_management #: model:ir.module.category,name:base.module_category_purchase_management
@ -1745,6 +1779,12 @@ msgid ""
"=============\n" "=============\n"
" " " "
msgstr "" msgstr ""
"\n"
"Энэ модуль нь хэрэв гомдол, порталь суулгагдсан байгаа бол гомдол меню болон "
"боломжийг портальд нэмдэг.\n"
"============================================================================="
"=============\n"
" "
#. module: base #. module: base
#: model:ir.actions.act_window,help:base.action_res_partner_bank_account_form #: 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.category,name:base.module_category_social_network
#: model:ir.module.module,shortdesc:base.module_mail #: model:ir.module.module,shortdesc:base.module_mail
msgid "Social Network" msgid "Social Network"
msgstr "" msgstr "Нийгмийн Сүлжээ"
#. module: base #. module: base
#: view:res.lang:0 #: view:res.lang:0
@ -1832,6 +1872,28 @@ msgid ""
"in their pockets, this module is essential.\n" "in their pockets, this module is essential.\n"
" " " "
msgstr "" msgstr ""
"\n"
"Энэ модуль нь үдийн цайг менеж хийх модуль.\n"
"================================\n"
"\n"
"Компаниуд нь ажилчиддаа орчин, нөхцлийг таатай болгох үүднээс олон "
"нийлүүлэгчээс хачиртай талх, пицца гэх мэтийг захиалах боломжийг санал "
"болгодог.\n"
"\n"
"Гэхдээ олон тооны ажилтан, нийлүүлэгч нар байгаа тохиолдолд зөв удирдлага "
"шаардлагатай болдог.\n"
"\n"
"\n"
"\"Үдийн цайны Захиалга\" модуль нь энэ менежментийг хялбар болгож ажилчидад "
"илүү өргөн багаж, хэрэглэгээг санал болгодог.\n"
"\n"
"Цаашлаад ажилчны тохиргоо дээр үндэслэн сануулга, хоол хурдан захиалах "
"боломж зэрэгийг санал болгодогоороо хоол болон нийлүүлэгчийн менежментийг "
"бүрэн гүйцэд болгодог.\n"
"\n"
"Ажилчид заавал задгай мөнгө кармалж явах заваан ажлаас ажилчдаа чөлөөлж "
"ажилчдынхаа цагийг хэмнэхэд энэ модуль нь туйлын чухал.\n"
" "
#. module: base #. module: base
#: view:wizard.ir.model.menu.create:0 #: view:wizard.ir.model.menu.create:0
@ -1871,7 +1933,7 @@ msgstr ""
#. module: base #. module: base
#: help:res.partner,website:0 #: help:res.partner,website:0
msgid "Website of Partner or Company" msgid "Website of Partner or Company"
msgstr "" msgstr "Харилцагч эсвэл Компаний веб сайт"
#. module: base #. module: base
#: help:base.language.install,overwrite:0 #: help:base.language.install,overwrite:0
@ -1916,7 +1978,7 @@ msgstr ""
#. module: base #. module: base
#: model:ir.module.module,summary:base.module_sale #: model:ir.module.module,summary:base.module_sale
msgid "Quotations, Sale Orders, Invoicing" msgid "Quotations, Sale Orders, Invoicing"
msgstr "" msgstr "Үнийн санал, Борлуулалтын Захиалга, Нэхэмжлэл"
#. module: base #. module: base
#: field:res.users,login:0 #: field:res.users,login:0
@ -1935,7 +1997,7 @@ msgstr ""
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_portal_project_issue #: model:ir.module.module,shortdesc:base.module_portal_project_issue
msgid "Portal Issue" msgid "Portal Issue"
msgstr "" msgstr "Портал Асуудал"
#. module: base #. module: base
#: model:ir.ui.menu,name:base.menu_tools #: model:ir.ui.menu,name:base.menu_tools
@ -1955,11 +2017,15 @@ msgid ""
"Launch Manually Once: after having been launched manually, it sets " "Launch Manually Once: after having been launched manually, it sets "
"automatically to Done." "automatically to Done."
msgstr "" msgstr ""
"Гараар: Гараар ажилуулна.\n"
"Автомат: Системийн тохиргоо өөрчлөгдөх бүрт автомат ажиллана.\n"
"Гараар нэг удаа: гараар ажилуулсан дараа автоматаар Хийгдсэн болж \n"
"тохируулагдана."
#. module: base #. module: base
#: field:res.partner,image_small:0 #: field:res.partner,image_small:0
msgid "Small-sized image" msgid "Small-sized image"
msgstr "" msgstr "Жижиг-хэмжээт зураг"
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_stock #: 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 " "It assigns manager and user access rights to the Administrator and only user "
"rights to the Demo user. \n" "rights to the Demo user. \n"
msgstr "" msgstr ""
"\n"
"Санхүүгийн Хандах Эрх.\n"
"=========================\n"
"\n"
"Энэ модуль нь санхүүгийн журнал, дансны мод гэх мэт бүх боломж руу хандах \n"
"хандалтыг удирдах боломжийг олгодог.\n"
"\n"
"Энэ нь менежер, хэрэглэгч хандалтын эрхийг Администраторт олгож Demo \n"
"хэрэглэгчид хэрэглэгч эрхийг олгодог. \n"
#. module: base #. module: base
#: field:ir.attachment,res_id:0 #: field:ir.attachment,res_id:0
@ -2066,6 +2141,8 @@ msgstr ""
#, python-format #, python-format
msgid "Unknown value '%s' for boolean field '%%(field)s', assuming '%s'" msgid "Unknown value '%s' for boolean field '%%(field)s', assuming '%s'"
msgstr "" msgstr ""
"'%s' гэсэн утга boolean '%%(field)s' талбарт мэдэгдэхгүй утга, '%s' гэж үзэж "
"байна"
#. module: base #. module: base
#: model:res.country,name:base.nl #: model:res.country,name:base.nl
@ -2075,12 +2152,12 @@ msgstr "Нидерланд"
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_portal_event #: model:ir.module.module,shortdesc:base.module_portal_event
msgid "Portal Event" msgid "Portal Event"
msgstr "" msgstr "Порталь Үйл явдал"
#. module: base #. module: base
#: selection:ir.translation,state:0 #: selection:ir.translation,state:0
msgid "Translation in Progress" msgid "Translation in Progress"
msgstr "" msgstr "Орчуулга Хийгдэж байна"
#. module: base #. module: base
#: model:ir.model,name:base.model_ir_rule #: model:ir.model,name:base.model_ir_rule
@ -2095,7 +2172,7 @@ msgstr "Өдөр"
#. module: base #. module: base
#: model:ir.module.module,summary:base.module_fleet #: model:ir.module.module,summary:base.module_fleet
msgid "Vehicle, leasing, insurances, costs" msgid "Vehicle, leasing, insurances, costs"
msgstr "" msgstr "Машин, лизинг, даатгал, өртөгүүд"
#. module: base #. module: base
#: view:ir.model.access:0 #: view:ir.model.access:0
@ -2123,6 +2200,23 @@ msgid ""
"synchronization with other companies.\n" "synchronization with other companies.\n"
" " " "
msgstr "" msgstr ""
"\n"
"Энэ модуль нь ерөнхиий тохиолдолд хуваалцах боломжийг таны OpenERP өгөгдлийн "
"\n"
"баазад олгодог багаж юм.\n"
"========================================================================\n"
"\n"
"Энэ нь 'хуваалцах' даруулыг нэмдэг бөгөөд OpenERP-н дуртай өгөгдлийг хамт \n"
"ажиллагч, захиалагч, найз нартайгаа хуваалцах боломжийг вебэд олгодог.\n"
"\n"
"Систем нь шинэ хэрэглэгч болон группыг автоматаар үүсгэдэг. Зохистой хандах "
"\n"
"дүрэмийг ir.rules-д автоматаар нэмж зөвхөн хуваалцсан өгөгдөл рүү хандах \n"
"хандалтын хяналтаар хангаддаг.\n"
"\n"
"Энэ нь хамтран ажиллах, мэдлэгээ хуваалцах, бусад компанитай мэдээллээ \n"
"ижилтгэх зэрэгт маш зохимжтой.\n"
" "
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_process #: 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 " "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." "people will not see it when encoding a purchase order."
msgstr "" msgstr ""
"Хэрэв холбогч нь нийлүүлэгч бол үүнийг тэмдэглэнэ. Хэрэв тэмдэглээгүй бол "
"худалдан авалтын хүмүүст худалдан авалтын захиалга шивэх үед харагдахгүй."
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_hr_evaluation #: model:ir.module.module,shortdesc:base.module_hr_evaluation
@ -2183,6 +2279,7 @@ msgstr "БЗ-д даалгавар үүсгэх"
#, python-format #, python-format
msgid "This column contains module data and cannot be removed!" msgid "This column contains module data and cannot be removed!"
msgstr "" msgstr ""
"Энэ багана нь модулийн өгөгдлийг хадгалж байгаа тул устгагдах боломжгүй!"
#. module: base #. module: base
#: field:ir.attachment,res_model:0 #: field:ir.attachment,res_model:0
@ -2207,6 +2304,15 @@ msgid ""
"with the effect of creating, editing and deleting either ways.\n" "with the effect of creating, editing and deleting either ways.\n"
" " " "
msgstr "" msgstr ""
"\n"
"Төслийн даалгаврыг ажлын цагийн хуваарьтай ижилтгэх.\n"
"====================================================================\n"
"\n"
"Энэ модуль нь Төслийн Менежмент модуль дахь даалгавруудыг Цагийн хуваарийн\n"
"ажлууд руу тодорхой огноонд тодорхой хэрэглэгчид шилжүүлдэг. Мөн цагийн \n"
"хуваариас нөгөө чиглэлд үүсгэх, засах, устгах\n"
"хоёр чиглэлд хийх боломжтой.\n"
" "
#. module: base #. module: base
#: model:ir.model,name:base.model_ir_model_access #: model:ir.model,name:base.model_ir_model_access
@ -2226,6 +2332,13 @@ msgid ""
" templates to target objects.\n" " templates to target objects.\n"
" " " "
msgstr "" msgstr ""
"\n"
" * Дансны Мод, Татвар, Татварын Код, Журналь, Дансны Үлгэр, Шинжилгээний "
"Дансны Мод, Шинжилгээний Журналиудад олон хэлийг нэмдэг.\n"
" * Тохируулах харилцах нь дараахыг өөрчилдөг.\n"
" - Үлгэрээс авагдсан Дансны Модт, Татвар, Татварын Код, Мөчлөг зэрэгт "
"орчуулгыг хуулна.\n"
" "
#. module: base #. module: base
#: field:workflow.transition,act_from:0 #: field:workflow.transition,act_from:0
@ -2317,6 +2430,25 @@ msgid ""
"* *Before Delivery*: A Draft invoice is created and must be paid before " "* *Before Delivery*: A Draft invoice is created and must be paid before "
"delivery\n" "delivery\n"
msgstr "" msgstr ""
"\n"
"Борлуулалтын үнийн санал, захиалгыг менеж хийх модуль\n"
"==================================\n"
"\n"
"Энэ модуль нь борлуулалт болон агуулахын модулийн хооронд холбох үүрэгтэй.\n"
"\n"
"Тохиргоо\n"
"-----------\n"
"* Хүргэлт: Хүргэлтийн сонголт буюу хэсэгчилсэн эсвэл нэг мөсөн\n"
"* Нэхэмжлэл: Нэхэмжлэл хэрхэн төлөгдөхийг сонгоно\n"
"* Инкотерм: Олон улсын худалдааны нөхцөл\n"
"\n"
"Нэхэмжлэх уян хатан аргуудыг сонгох боломжтой:\n"
"\n"
"* *Шаардалтаар*: Борлуулалтын захиалгаас дуртай үедээ гараар нэхэмжлэл "
"үүсгэх\n"
"* *Хүргэх захиалгаар*: Хүргэх захиалгаар нэхэмжлэл үүсгэх\n"
"* *Хүргэлтээс өмнө*: Ноорог нэхэмжлэл үүсгэгдэж хүргэхээс өмнө төлөгдсөн "
"байх ёстой\n"
#. module: base #. module: base
#: field:ir.ui.menu,complete_name:0 #: field:ir.ui.menu,complete_name:0
@ -2347,7 +2479,7 @@ msgstr ""
#. module: base #. module: base
#: view:base.language.export:0 #: view:base.language.export:0
msgid "PO(T) format: you should edit it with a PO editor such as" msgid "PO(T) format: you should edit it with a PO editor such as"
msgstr "" msgstr "PO(T) формат: PO текст засварлагчаар засварлах нь зохимжтой"
#. module: base #. module: base
#: model:ir.ui.menu,name:base.menu_administration #: model:ir.ui.menu,name:base.menu_administration
@ -2371,7 +2503,7 @@ msgstr "Үүсгэх / Бичих / Хувилах"
#. module: base #. module: base
#: view:ir.sequence:0 #: view:ir.sequence:0
msgid "Second: %(sec)s" msgid "Second: %(sec)s"
msgstr "" msgstr "Секунд: %(sec)s"
#. module: base #. module: base
#: field:ir.actions.act_window,view_mode:0 #: field:ir.actions.act_window,view_mode:0
@ -2436,7 +2568,7 @@ msgstr "Багамийн арлууд"
#. module: base #. module: base
#: field:ir.rule,perm_create:0 #: field:ir.rule,perm_create:0
msgid "Apply for Create" msgid "Apply for Create"
msgstr "" msgstr "Үүсгэхээр Хэрэгжүүлэх"
#. module: base #. module: base
#: model:ir.module.category,name:base.module_category_tools #: 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 " "Appears by default on the top right corner of your printed documents (report "
"header)." "header)."
msgstr "" msgstr ""
"Хэвлэгдсэн баримтын баруун дээд (тайлангийн толгой) оройд анхны байдлаараа "
"байрладаг."
#. module: base #. module: base
#: field:base.module.update,update:0 #: field:base.module.update,update:0
@ -2501,6 +2635,27 @@ msgid ""
"* Maximal difference between timesheet and attendances\n" "* Maximal difference between timesheet and attendances\n"
" " " "
msgstr "" msgstr ""
"\n"
"Цаг бүртгэл болон ирцийг хялбараар хөтлөж, шалгадаг\n"
"=====================================================\n"
"\n"
"Энэ аппликэйшн нь ирц (Нэвтрэх/Гарах), цаг бүртгэлийг бүртгэх ажлыг "
"гүйцэтгэх нэмэлт цонхтой байдаг. Цаг бүртгэлийн мөрүүдийг ажилчид өдөр бүр "
"хөтлөнө. Тодорхойлогсдон мөчлөгийн төгсгөлд ажилчин өөрийн цагийн хуудсыг "
"шалгах бөгөөд менежер нь цааш баталдаг. Мөчлөг нь компаний тохиргооны "
"маягтад тодорхойлогдсон байдаг сараа, долооногоор тааруулах боломжтой. \n"
"\n"
"Цаг бүртгэлийн шалгалтын бүрэн ажлын урсгал:\n"
"---------------------------------------------\n"
"* Ноорог хуудас\n"
"* Мөчлөгийн төгсгөлд ажилнчин цагийн хуудсыг магадлаж батлана\n"
"* Төслийн менежер шалгана\n"
"\n"
"Шалгалт нь компаний тохиргоонд тохируулах боломжтой:\n"
"------------------------------------------------\n"
"* Мөчлөгийн хэмжээ (Өдөрөөр, Долооогоор, Сараар)\n"
"* Цагийн хуудас ирцийн зөвшөөрөгдөх хамгийн их ялгаа\n"
" "
#. module: base #. module: base
#: code:addons/base/ir/ir_fields.py:342 #: code:addons/base/ir/ir_fields.py:342
@ -2508,6 +2663,8 @@ msgstr ""
msgid "" msgid ""
"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'" "No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'"
msgstr "" msgstr ""
"%(field_type)s талбарт тохирох '%(value)s' гэсэн утга '%%(field)s' талбарт "
"алга"
#. module: base #. module: base
#: model:ir.actions.act_window,help:base.action_ui_view #: 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 " "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" "hierarchical tree view, or 'form' for a regular list view"
msgstr "" msgstr ""
"Харагдацын төрөл: Мөчир төрөл нь мөчир төрлөөр харахад хэрэглэгдэх 'tree' "
"утга эсвэл 'form' утгаар энгийн жагсаалт харагдацыг тохируулдаг."
#. module: base #. module: base
#: sql_constraint:ir.ui.view_sc:0 #: sql_constraint:ir.ui.view_sc:0
@ -2730,6 +2889,26 @@ msgid ""
"Print product labels with barcode.\n" "Print product labels with barcode.\n"
" " " "
msgstr "" msgstr ""
"\n"
"Энэ модуль нь OpenERP-д үнийн хүснэгт болон барааг менеж хийх модуль юм.\n"
"========================================================================\n"
"\n"
"Бараа нь хувилбарууд, ялгаатай үнийн аргууд, нийлүүлэгчийн мэдээлэл, "
"захиалуулах, хадгалуулах, ялгаатай хэмжих нэгжүүд, савлалт, үзүүлэлтүүд гэх "
"мэт олон зүйлийг дэмждэг.\n"
"\n"
"Үнийн хүснэгт нь дараах зүйлсийг дэмждэг:\n"
" * Олон түвшний хөнгөлөлт (бараагаар, ангилалаар, тоо ширхэгээр)\n"
" * Ялгаатай шалгууруудаар үнэ бодогдох\n"
" * Өөр үнийн хүснэгт,\n"
" * Өртөг үнэ,\n"
" * Суурь үнэ,\n"
" * Нийлүүлэгчийн үнэ, …\n"
"\n"
"Үнийн хүснэгтийн бараагаар болон/эсвэл харилцагчаарх тохиргоо.\n"
"\n"
"Барааны шошгыг зураасан кодтой хэвлэх.\n"
" "
#. module: base #. module: base
#: model:ir.module.module,description:base.module_account_analytic_default #: model:ir.module.module,description:base.module_account_analytic_default
@ -2747,11 +2926,22 @@ msgid ""
" * Date\n" " * Date\n"
" " " "
msgstr "" msgstr ""
"\n"
"Шинжилгээний дансдад анхны утгыг тохируулна.\n"
"Нөхцөл үндэслэн шинжилгээний дансыг автомат сонгох боломжийг олгоно:\n"
"=====================================================================\n"
"\n"
" * Бараа\n"
" * Харилцагч\n"
" * Хэрэглэгч\n"
" * Компани\n"
" * Огноо\n"
" "
#. module: base #. module: base
#: field:res.company,rml_header1:0 #: field:res.company,rml_header1:0
msgid "Company Slogan" msgid "Company Slogan"
msgstr "" msgstr "Компаний уриа"
#. module: base #. module: base
#: model:res.country,name:base.bb #: model:res.country,name:base.bb
@ -2775,7 +2965,7 @@ msgstr ""
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_auth_oauth_signup #: model:ir.module.module,shortdesc:base.module_auth_oauth_signup
msgid "Signup with OAuth2 Authentication" msgid "Signup with OAuth2 Authentication"
msgstr "" msgstr "OAuth2 эрхийн хяналтаар бүртгүүлэх"
#. module: base #. module: base
#: selection:ir.model,state:0 #: selection:ir.model,state:0
@ -2802,7 +2992,7 @@ msgstr "Грек / Ελληνικά"
#. module: base #. module: base
#: field:res.company,custom_footer:0 #: field:res.company,custom_footer:0
msgid "Custom Footer" msgid "Custom Footer"
msgstr "" msgstr "Өөриймшүүлсэн Хөл"
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_sale_crm #: model:ir.module.module,shortdesc:base.module_sale_crm
@ -2870,7 +3060,7 @@ msgstr "Хурдан холбоосын нэр"
#. module: base #. module: base
#: field:res.partner,contact_address:0 #: field:res.partner,contact_address:0
msgid "Complete Address" msgid "Complete Address"
msgstr "" msgstr "Бүтэн Хаяг"
#. module: base #. module: base
#: help:ir.actions.act_window,limit:0 #: help:ir.actions.act_window,limit:0
@ -2930,6 +3120,39 @@ msgid ""
"* Monthly Turnover (Graph)\n" "* Monthly Turnover (Graph)\n"
" " " "
msgstr "" 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 #. module: base
#: field:ir.actions.act_window,res_id:0 #: field:ir.actions.act_window,res_id:0
@ -2942,7 +3165,7 @@ msgstr "Бичлэгийн ID"
#. module: base #. module: base
#: view:ir.filters:0 #: view:ir.filters:0
msgid "My Filters" msgid "My Filters"
msgstr "" msgstr "Миний Шүүлтүүрүүд"
#. module: base #. module: base
#: field:ir.actions.server,email:0 #: field:ir.actions.server,email:0
@ -2956,12 +3179,15 @@ msgid ""
"Module to attach a google document to any model.\n" "Module to attach a google document to any model.\n"
"================================================\n" "================================================\n"
msgstr "" msgstr ""
"\n"
"Google баримтыг хавсаргадаг модуль.\n"
"================================================\n"
#. module: base #. module: base
#: code:addons/base/ir/ir_fields.py:334 #: code:addons/base/ir/ir_fields.py:334
#, python-format #, python-format
msgid "Found multiple matches for field '%%(field)s' (%d matches)" msgid "Found multiple matches for field '%%(field)s' (%d matches)"
msgstr "" msgstr "'%%(field)s' талбарын хувьд олон олдоц байна (%d олдоцууд)"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
@ -2995,7 +3221,7 @@ msgstr "Клиент рүү харах таагийн хамт илгээгдс
#. module: base #. module: base
#: model:ir.module.module,summary:base.module_contacts #: model:ir.module.module,summary:base.module_contacts
msgid "Contacts, People and Companies" msgid "Contacts, People and Companies"
msgstr "" msgstr "Холбогч, Хүмүүс, Компаниуд"
#. module: base #. module: base
#: model:res.country,name:base.tt #: model:res.country,name:base.tt

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n" "Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\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" "Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-12 04:38+0000\n" "X-Launchpad-Export-Date: 2012-12-18 04:58+0000\n"
"X-Generator: Launchpad (build 16361)\n" "X-Generator: Launchpad (build 16372)\n"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_account_check_writing #: model:ir.module.module,description:base.module_account_check_writing
@ -1591,7 +1591,7 @@ msgstr ""
#. module: base #. module: base
#: model:res.country,name:base.mf #: model:res.country,name:base.mf
msgid "Saint Martin (French part)" msgid "Saint Martin (French part)"
msgstr "" msgstr "Saint-Martin (część francuska)"
#. module: base #. module: base
#: model:ir.model,name:base.model_ir_exports #: model:ir.model,name:base.model_ir_exports
@ -1623,7 +1623,7 @@ msgstr "Konfiguracja stopki raportów"
#. module: base #. module: base
#: field:ir.translation,comments:0 #: field:ir.translation,comments:0
msgid "Translation comments" msgid "Translation comments"
msgstr "" msgstr "Komentarze do tłumaczenia"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_lunch #: model:ir.module.module,description:base.module_lunch
@ -1895,7 +1895,7 @@ msgstr ""
#. module: base #. module: base
#: selection:ir.translation,state:0 #: selection:ir.translation,state:0
msgid "Translation in Progress" msgid "Translation in Progress"
msgstr "" msgstr "Tłumaczenie w toku"
#. module: base #. module: base
#: model:ir.model,name:base.model_ir_rule #: 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.marketing_menu
#: model:ir.ui.menu,name:base.menu_report_marketing #: model:ir.ui.menu,name:base.menu_report_marketing
msgid "Marketing" msgid "Marketing"
msgstr "" msgstr "Marketing"
#. module: base #. module: base
#: view:res.partner.bank:0 #: view:res.partner.bank:0
@ -4489,7 +4489,7 @@ msgstr ""
#: model:ir.actions.act_window,name:base.action_view_base_language_install #: model:ir.actions.act_window,name:base.action_view_base_language_install
#: model:ir.ui.menu,name:base.menu_view_base_language_install #: model:ir.ui.menu,name:base.menu_view_base_language_install
msgid "Load a Translation" msgid "Load a Translation"
msgstr "" msgstr "Pobierz tłumaczenie"
#. module: base #. module: base
#: field:ir.module.module,latest_version:0 #: field:ir.module.module,latest_version:0
@ -11768,7 +11768,7 @@ msgstr ""
#. module: base #. module: base
#: selection:res.request,state:0 #: selection:res.request,state:0
msgid "waiting" msgid "waiting"
msgstr "" msgstr "oczekiwanie"
#. module: base #. module: base
#: model:ir.model,name:base.model_workflow_triggers #: model:ir.model,name:base.model_workflow_triggers
@ -14342,7 +14342,7 @@ msgstr "Prawo"
#: field:res.partner,vat:0 #: field:res.partner,vat:0
#, python-format #, python-format
msgid "TIN" msgid "TIN"
msgstr "" msgstr "NIP"
#. module: base #. module: base
#: model:res.country,name:base.aw #: model:res.country,name:base.aw

View File

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

View File

@ -7,15 +7,15 @@ msgstr ""
"Project-Id-Version: pt_BR\n" "Project-Id-Version: pt_BR\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\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 " "Last-Translator: Fábio Martinelli - http://zupy.com.br "
"<webmaster@guaru.net>\n" "<webmaster@guaru.net>\n"
"Language-Team: <pt@li.org>\n" "Language-Team: <pt@li.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-12 04:39+0000\n" "X-Launchpad-Export-Date: 2012-12-17 04:44+0000\n"
"X-Generator: Launchpad (build 16361)\n" "X-Generator: Launchpad (build 16372)\n"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_account_check_writing #: model:ir.module.module,description:base.module_account_check_writing
@ -26,8 +26,8 @@ msgid ""
" " " "
msgstr "" msgstr ""
"\n" "\n"
"Módulo para Verificar Escrita e Impressão.\n" "Módulo para Criar e Imprimir Cheques.\n"
"========================================\n" "=====================================\n"
" " " "
#. module: base #. module: base
@ -93,7 +93,7 @@ msgstr ""
#. module: base #. module: base
#: model:ir.module.module,summary:base.module_point_of_sale #: model:ir.module.module,summary:base.module_point_of_sale
msgid "Touchscreen Interface for Shops" msgid "Touchscreen Interface for Shops"
msgstr "Interface Touchscreen para lojas" msgstr "Interface Toque na Tela para Lojas"
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll #: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll
@ -159,7 +159,7 @@ msgstr ""
#. module: base #. module: base
#: help:res.partner,employee:0 #: help:res.partner,employee:0
msgid "Check this box if this contact is an Employee." 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 #. module: base
#: help:ir.model.fields,domain:0 #: help:ir.model.fields,domain:0
@ -6594,7 +6594,7 @@ msgstr "Cancelar Entradas de Diário"
#. module: base #. module: base
#: field:res.partner,tz_offset:0 #: field:res.partner,tz_offset:0
msgid "Timezone offset" msgid "Timezone offset"
msgstr "" msgstr "Deslocamento de Fuso Horário"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_marketing_campaign #: model:ir.module.module,description:base.module_marketing_campaign
@ -7938,7 +7938,7 @@ msgstr "Ref. Visão de Pesquisa"
#. module: base #. module: base
#: help:res.users,partner_id:0 #: help:res.users,partner_id:0
msgid "Partner-related data of the user" msgid "Partner-related data of the user"
msgstr "" msgstr "Dados do usuário relacionado ao Parceiro"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_crm_todo #: 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 #. module: base
#: model:ir.module.module,shortdesc:base.module_pad_project #: model:ir.module.module,shortdesc:base.module_pad_project
msgid "Pad on tasks" msgid "Pad on tasks"
msgstr "" msgstr "Blocos nas Tarefas"
#. module: base #. module: base
#: model:ir.model,name:base.model_base_update_translations #: model:ir.model,name:base.model_base_update_translations
@ -9563,6 +9563,18 @@ msgid ""
"Thank you in advance for your cooperation.\n" "Thank you in advance for your cooperation.\n"
"Best Regards," "Best Regards,"
msgstr "" 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 #. module: base
#: view:ir.module.category:0 #: view:ir.module.category:0
@ -9708,6 +9720,14 @@ msgid ""
"If set to true it allows user to cancel entries & invoices.\n" "If set to true it allows user to cancel entries & invoices.\n"
" " " "
msgstr "" 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 #. module: base
#: model:ir.module.module,shortdesc:base.module_plugin #: model:ir.module.module,shortdesc:base.module_plugin
@ -10141,7 +10161,7 @@ msgstr "Descrição dos Campos"
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_analytic_contract_hr_expense #: model:ir.module.module,shortdesc:base.module_analytic_contract_hr_expense
msgid "Contracts Management: hr_expense link" msgid "Contracts Management: hr_expense link"
msgstr "" msgstr "Gerenciamento de Contratos: link hr_expense"
#. module: base #. module: base
#: view:ir.attachment:0 #: view:ir.attachment:0
@ -10758,7 +10778,7 @@ msgstr "A fazer"
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_portal_hr_employees #: model:ir.module.module,shortdesc:base.module_portal_hr_employees
msgid "Portal HR employees" msgid "Portal HR employees"
msgstr "" msgstr "Portal RH funcionários"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
@ -11724,6 +11744,17 @@ msgid ""
"automatically new claims based on incoming emails.\n" "automatically new claims based on incoming emails.\n"
" " " "
msgstr "" 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 #. module: base
#: selection:ir.module.module,license:0 #: selection:ir.module.module,license:0
@ -13551,6 +13582,9 @@ msgid ""
"128x128px image, with aspect ratio preserved. Use this field in form views " "128x128px image, with aspect ratio preserved. Use this field in form views "
"or some kanban views." "or some kanban views."
msgstr "" 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 #. module: base
#: view:base.update.translations:0 #: view:base.update.translations:0
@ -13826,12 +13860,12 @@ msgstr "Espanha - Contabilidade(PGCE 2008)"
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_stock_no_autopicking #: model:ir.module.module,shortdesc:base.module_stock_no_autopicking
msgid "Picking Before Manufacturing" msgid "Picking Before Manufacturing"
msgstr "" msgstr "Separação antes da Produção"
#. module: base #. module: base
#: model:ir.module.module,summary:base.module_note_pad #: model:ir.module.module,summary:base.module_note_pad
msgid "Sticky memos, Collaborative" msgid "Sticky memos, Collaborative"
msgstr "" msgstr "Notas Colaborativas (post it)"
#. module: base #. module: base
#: model:res.country,name:base.wf #: model:res.country,name:base.wf
@ -14095,6 +14129,10 @@ msgid ""
"your home page.\n" "your home page.\n"
"You can track your suppliers, customers and other contacts.\n" "You can track your suppliers, customers and other contacts.\n"
msgstr "" 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 #. module: base
#: help:res.company,custom_footer:0 #: help:res.company,custom_footer:0
@ -14548,7 +14586,7 @@ msgstr "Prospectos & Oportunidades"
#. module: base #. module: base
#: model:res.country,name:base.gg #: model:res.country,name:base.gg
msgid "Guernsey" msgid "Guernsey"
msgstr "" msgstr "Guernsey"
#. module: base #. module: base
#: selection:base.language.install,lang:0 #: selection:base.language.install,lang:0
@ -15070,7 +15108,7 @@ msgstr "Relatórios Avançados"
#. module: base #. module: base
#: model:ir.module.module,summary:base.module_purchase #: model:ir.module.module,summary:base.module_purchase
msgid "Purchase Orders, Receptions, Supplier Invoices" msgid "Purchase Orders, Receptions, Supplier Invoices"
msgstr "" msgstr "Pedidos de Compra, Recepções, Faturas de Fornecedores"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_hr_payroll #: model:ir.module.module,description:base.module_hr_payroll
@ -15275,7 +15313,7 @@ msgstr "Módulos Genéricos"
#. module: base #. module: base
#: model:res.country,name:base.mk #: model:res.country,name:base.mk
msgid "Macedonia, the former Yugoslav Republic of" msgid "Macedonia, the former Yugoslav Republic of"
msgstr "" msgstr "Macedônia"
#. module: base #. module: base
#: model:res.country,name:base.rw #: model:res.country,name:base.rw
@ -15412,7 +15450,7 @@ msgstr "Holanda - Contabilidade"
#. module: base #. module: base
#: model:res.country,name:base.gs #: model:res.country,name:base.gs
msgid "South Georgia and the South Sandwich Islands" msgid "South Georgia and the South Sandwich Islands"
msgstr "" msgstr "Geórgia do Sul e Ilhas Sandwich do Sul"
#. module: base #. module: base
#: view:res.lang:0 #: view:res.lang:0
@ -15709,6 +15747,8 @@ msgid ""
"Tax Identification Number. Check the box if this contact is subjected to " "Tax Identification Number. Check the box if this contact is subjected to "
"taxes. Used by the some of the legal statements." "taxes. Used by the some of the legal statements."
msgstr "" 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 #. module: base
#: field:res.partner.bank,partner_id:0 #: field:res.partner.bank,partner_id:0
@ -15885,6 +15925,16 @@ msgid ""
" </p>\n" " </p>\n"
" " " "
msgstr "" 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 #. module: base
#: model:res.partner.category,name:base.res_partner_category_2 #: 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" "Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-03 16:01+0000\n" "POT-Creation-Date: 2012-12-03 16:01+0000\n"
"PO-Revision-Date: 2012-08-20 15:27+0000\n" "PO-Revision-Date: 2012-12-16 18:26+0000\n"
"Last-Translator: Dorin <dhongu@gmail.com>\n" "Last-Translator: Fekete Mihai <mihai@erpsystems.ro>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 04:59+0000\n" "X-Launchpad-Export-Date: 2012-12-17 04:44+0000\n"
"X-Generator: Launchpad (build 16335)\n" "X-Generator: Launchpad (build 16372)\n"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_account_check_writing #: model:ir.module.module,description:base.module_account_check_writing
@ -24,6 +24,10 @@ msgid ""
"================================================\n" "================================================\n"
" " " "
msgstr "" msgstr ""
"\n"
"Modul pentru Verifica Scrisul si Verifica Imprimarea.\n"
"================================================\n"
" "
#. module: base #. module: base
#: model:res.country,name:base.sh #: model:res.country,name:base.sh
@ -59,7 +63,7 @@ msgstr "Alcatuirea vizualizarii"
#. module: base #. module: base
#: model:ir.module.module,summary:base.module_sale_stock #: model:ir.module.module,summary:base.module_sale_stock
msgid "Quotation, Sale Orders, Delivery & Invoicing Control" msgid "Quotation, Sale Orders, Delivery & Invoicing Control"
msgstr "" msgstr "Cotatie, Ordine de vanzari, Controlul Livrarii & Facturarii"
#. module: base #. module: base
#: selection:ir.sequence,implementation:0 #: selection:ir.sequence,implementation:0
@ -88,25 +92,25 @@ msgstr ""
#. module: base #. module: base
#: model:ir.module.module,summary:base.module_point_of_sale #: model:ir.module.module,summary:base.module_point_of_sale
msgid "Touchscreen Interface for Shops" msgid "Touchscreen Interface for Shops"
msgstr "" msgstr "Interfata cu Ecran tactil pentru Magazine"
#. module: base #. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll #: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll
msgid "Indian Payroll" msgid "Indian Payroll"
msgstr "" msgstr "Stat de plata indian"
#. module: base #. module: base
#: help:ir.cron,model:0 #: help:ir.cron,model:0
msgid "" msgid ""
"Model name on which the method to be called is located, e.g. 'res.partner'." "Model name on which the method to be called is located, e.g. 'res.partner'."
msgstr "" msgstr ""
"Numele modelului unde este localizata metoda care urmeaza a fi efectuata, de " "Numele modelului unde este localizata metoda care va fi numita, de exemplu "
"exemplu 'res.partener'." "'res.partener'."
#. module: base #. module: base
#: view:ir.module.module:0 #: view:ir.module.module:0
msgid "Created Views" msgid "Created Views"
msgstr "Afisari Create" msgstr "Vizualizari Create"
#. module: base #. module: base
#: model:ir.module.module,description:base.module_product_manufacturer #: model:ir.module.module,description:base.module_product_manufacturer
@ -123,6 +127,17 @@ msgid ""
" * Product Attributes\n" " * Product Attributes\n"
" " " "
msgstr "" 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 #. module: base
#: field:ir.actions.client,params:0 #: field:ir.actions.client,params:0
@ -136,11 +151,14 @@ msgid ""
"The module adds google user in res user.\n" "The module adds google user in res user.\n"
"========================================\n" "========================================\n"
msgstr "" msgstr ""
"\n"
"Acest modul adauga utilizatorul google la utilizatorul res.\n"
"========================================\n"
#. module: base #. module: base
#: help:res.partner,employee:0 #: help:res.partner,employee:0
msgid "Check this box if this contact is an Employee." msgid "Check this box if this contact is an Employee."
msgstr "" msgstr "Bifati aceasta casuta daca acest contact este un Angajat."
#. module: base #. module: base
#: help:ir.model.fields,domain:0 #: 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 context['object'] = obj
for i in expr: for i in expr:
context['active_id'] = i.id 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': if action.state == 'object_write':
res = {} res = {}
@ -716,8 +716,6 @@ class actions_server(osv.osv):
expr = exp.value expr = exp.value
res[exp.col1.name] = expr res[exp.col1.name] = expr
obj_pool = None
res_id = False
obj_pool = self.pool.get(action.srcmodel_id.model) obj_pool = self.pool.get(action.srcmodel_id.model)
res_id = obj_pool.create(cr, uid, res) res_id = obj_pool.create(cr, uid, res)
if action.record_id: if action.record_id:
@ -736,7 +734,7 @@ class actions_server(osv.osv):
model = action.copy_object.split(',')[0] model = action.copy_object.split(',')[0]
cid = action.copy_object.split(',')[1] cid = action.copy_object.split(',')[1]
obj_pool = self.pool.get(model) 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 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) _logger.warning('Tried to poll an undefined table on database %s.', db_name)
else: else:
raise raise
except Exception, ex: except Exception:
_logger.warning('Exception in cron:', exc_info=True) _logger.warning('Exception in cron:', exc_info=True)
finally: finally:

View File

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

View File

@ -228,7 +228,7 @@ class ir_mail_server(osv.osv):
:param int port: SMTP port to connect to :param int port: SMTP port to connect to
:param user: optional username to authenticate with :param user: optional username to authenticate with
:param password: optional password 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 :param bool smtp_debug: toggle debugging of SMTP sessions (all i/o
will be output in logs) will be output in logs)
""" """

View File

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

View File

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

View File

@ -23,7 +23,7 @@ from osv import osv
class ir_needaction_mixin(osv.AbstractModel): 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 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 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: This class also offers several global services:
- ``_needaction_count``: returns the number of actions uid has to perform - ``_needaction_count``: returns the number of actions uid has to perform
''' """
_name = 'ir.needaction_mixin' _name = 'ir.needaction_mixin'
_needaction = True _needaction = True
@ -56,7 +56,7 @@ class ir_needaction_mixin(osv.AbstractModel):
# "Need action" API # "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. """ """ Get the number of actions uid has to perform. """
dom = self._needaction_domain_get(cr, uid, context=context) dom = self._needaction_domain_get(cr, uid, context=context)
if not dom: 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 = self._add_missing_default_values(cr, uid, values, context)
values['id'] = super(ir_sequence, self).create(cr, uid, values, context) values['id'] = super(ir_sequence, self).create(cr, uid, values, context)
if values['implementation'] == 'standard': 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'] return values['id']
def unlink(self, cr, uid, ids, context=None): 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)) """ % (self._parent_table, self._table_name, self._parent_table, find_expr))
if self._debug: 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] c1 = cr.fetchone()[0]
cr.execute('SELECT COUNT(*) FROM ONLY %s AS irt, %s AS ti WHERE %s' % \ cr.execute('SELECT COUNT(*) FROM ONLY %s AS irt, %s AS ti WHERE %s' % \
(self._parent_table, self._table_name, find_expr)) (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): def _get_ids(self, cr, uid, name, tt, lang, ids):
translations = dict.fromkeys(ids, False) translations = dict.fromkeys(ids, False)
if ids: if ids:
cr.execute('select res_id,value ' \ cr.execute('select res_id,value '
'from ir_translation ' \ 'from ir_translation '
'where lang=%s ' \ 'where lang=%s '
'and type=%s ' \ 'and type=%s '
'and name=%s ' \ 'and name=%s '
'and res_id IN %s', 'and res_id IN %s',
(lang,tt,name,tuple(ids))) (lang,tt,name,tuple(ids)))
for res_id, value in cr.fetchall(): 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_ids.clear_cache(self, uid, name, tt, lang, res_id)
self._get_source.clear_cache(self, uid, name, tt, lang) self._get_source.clear_cache(self, uid, name, tt, lang)
cr.execute('delete from ir_translation ' \ cr.execute('delete from ir_translation '
'where lang=%s ' \ 'where lang=%s '
'and type=%s ' \ 'and type=%s '
'and name=%s ' \ 'and name=%s '
'and res_id IN %s', 'and res_id IN %s',
(lang,tt,name,tuple(ids),)) (lang,tt,name,tuple(ids),))
for id in ids: for id in ids:

View File

@ -44,9 +44,8 @@ class ir_ui_menu(osv.osv):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.cache_lock = threading.RLock() self.cache_lock = threading.RLock()
self._cache = {} 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') self.pool.get('ir.model.access').register_cache_clearing_method(self._name, 'clear_cache')
return r
def clear_cache(self): def clear_cache(self):
with self.cache_lock: with self.cache_lock:
@ -66,7 +65,7 @@ class ir_ui_menu(osv.osv):
modelaccess = self.pool.get('ir.model.access') modelaccess = self.pool.get('ir.model.access')
user_groups = set(self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['groups_id'])['groups_id']) user_groups = set(self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['groups_id'])['groups_id'])
result = [] 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) # 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)) key = (cr.dbname, menu.id, tuple(user_groups))
if key in self._cache: if key in self._cache:
@ -144,7 +143,7 @@ class ir_ui_menu(osv.osv):
return res return res
def _get_full_name(self, cr, uid, ids, name=None, args=None, context=None): def _get_full_name(self, cr, uid, ids, name=None, args=None, context=None):
if context == None: if context is None:
context = {} context = {}
res = {} res = {}
for elmt in self.browse(cr, uid, ids, context=context): for elmt in self.browse(cr, uid, ids, context=context):
@ -168,9 +167,22 @@ class ir_ui_menu(osv.osv):
self.clear_cache() self.clear_cache()
return super(ir_ui_menu, self).write(*args, **kwargs) 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() self.clear_cache()
return super(ir_ui_menu, self).unlink(*args, **kwargs) return result
def copy(self, cr, uid, id, default=None, context=None): def copy(self, cr, uid, id, default=None, context=None):
ir_values_obj = self.pool.get('ir.values') ir_values_obj = self.pool.get('ir.values')
@ -182,7 +194,7 @@ class ir_ui_menu(osv.osv):
next_num=int(concat[0])+1 next_num=int(concat[0])+1
datas['name']=rex.sub(('(%d)'%next_num),datas['name']) datas['name']=rex.sub(('(%d)'%next_num),datas['name'])
else: else:
datas['name']=datas['name']+'(1)' datas['name'] += '(1)'
self.write(cr,uid,[res],{'name':datas['name']}) self.write(cr,uid,[res],{'name':datas['name']})
ids = ir_values_obj.search(cr, uid, [ ids = ir_values_obj.search(cr, uid, [
('model', '=', 'ir.ui.menu'), ('model', '=', 'ir.ui.menu'),
@ -307,7 +319,9 @@ class ir_ui_menu(osv.osv):
'name': fields.char('Menu', size=64, required=True, translate=True), 'name': fields.char('Menu', size=64, required=True, translate=True),
'sequence': fields.integer('Sequence'), 'sequence': fields.integer('Sequence'),
'child_id': fields.one2many('ir.ui.menu', 'parent_id', 'Child IDs'), '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', '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. "\ '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."), "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, 'sequence': 10,
} }
_order = "sequence,id" _order = "sequence,id"
_parent_store = True
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -254,7 +254,7 @@ class view(osv.osv):
if label: if label:
for lbl in eval(label): for lbl in eval(label):
if t.has_key(tools.ustr(lbl)) and tools.ustr(t[lbl])=='False': if t.has_key(tools.ustr(lbl)) and tools.ustr(t[lbl])=='False':
label_string = label_string + ' ' label_string += ' '
else: else:
label_string = label_string + " " + tools.ustr(t[lbl]) label_string = label_string + " " + tools.ustr(t[lbl])
labels[str(t['id'])] = (a['id'],label_string) 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""" ORDER BY v.user_id, u.company_id"""
params = ('default', model, uid, uid) params = ('default', model, uid, uid)
if condition: if condition:
query = query % 'AND v.key2 = %s' query %= 'AND v.key2 = %s'
params += (condition[:200],) params += (condition[:200],)
else: else:
query = query % 'AND v.key2 is NULL' query %= 'AND v.key2 is NULL'
cr.execute(query, params) cr.execute(query, params)
# keep only the highest priority default for each field # keep only the highest priority default for each field
@ -417,7 +417,7 @@ class ir_values(osv.osv):
continue continue
# keep only the first action registered for each action name # keep only the first action registered for each action name
results[action['name']] = (action['id'], action['name'], action_def) results[action['name']] = (action['id'], action['name'], action_def)
except except_orm, e: except except_orm:
continue continue
return sorted(results.values()) 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: for t in transitions:
if not t['act_to'] in activities: if not t['act_to'] in activities:
continue continue
args = {} args = {
args['label'] = str(t['condition']).replace(' or ', '\\nor ').replace(' and ', '\\nand ') 'label': str(t['condition']).replace(' or ', '\\nor ')
.replace(' and ','\\nand ')
}
if t['signal']: if t['signal']:
args['label'] += '\\n'+str(t['signal']) args['label'] += '\\n'+str(t['signal'])
args['style'] = 'bold' 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_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]) 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)) 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) 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] 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) 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() stop = cr.fetchall()
if (stop): if stop:
stop = (stop[0][1], dict(stop)) stop = (stop[0][1], dict(stop))
else: else:
stop = ("stop",{}) stop = ("stop",{})
return ((start,{}),stop) return (start, {}), stop
def graph_instance_get(cr, graph, inst_id, nested=False): def graph_instance_get(cr, graph, inst_id, nested=False):
workitems = {}
cr.execute('select wkf_id from wkf_instance where id=%s', (inst_id,)) cr.execute('select wkf_id from wkf_instance where id=%s', (inst_id,))
inst = cr.fetchall() inst = cr.fetchall()
@ -169,7 +170,7 @@ showpage'''
inst_id = inst_id[0] inst_id = inst_id[0]
graph_instance_get(cr, graph, inst_id, data.get('nested', False)) graph_instance_get(cr, graph, inst_id, data.get('nested', False))
ps_string = graph.create(prog='dot', format='ps') ps_string = graph.create(prog='dot', format='ps')
except Exception, e: except Exception:
_logger.exception('Exception in call:') _logger.exception('Exception in call:')
# string is in PS, like the success message would have been # string is in PS, like the success message would have been
ps_string = '''%PS-Adobe-3.0 ps_string = '''%PS-Adobe-3.0
@ -206,13 +207,13 @@ class report_graph(report.interface.report_int):
def result(self): def result(self):
if self.obj.is_done(): if self.obj.is_done():
return (True, self.obj.get(), 'pdf') return True, self.obj.get(), 'pdf'
else: else:
return (False, False, False) return False, False, False
def create(self, cr, uid, ids, data, context=None): def create(self, cr, uid, ids, data, context=None):
self.obj = report_graph_instance(cr, uid, ids, data) 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') 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"> <template pageSize="(595.0,842.0)" title="Test" author="Martin Simon" allowSplitting="20">
<pageTemplate id="first"> <pageTemplate id="first">
<frame id="first" x1="42.0" y1="42.0" width="511" height="758"/> <frame id="first" x1="42.0" y1="42.0" width="511" height="758"/>
<header> <header>
<pageGraphics> <pageGraphics>
<setFont name="Helvetica-Bold" size="9"/> <setFont name="Helvetica-Bold" size="9"/>
<drawString x="1.0cm" y="28.1cm">[[ company.name ]]</drawString> <drawString x="1.0cm" y="28.1cm">[[ company.name ]]</drawString>
<drawRightString x="20cm" y="28.1cm"> Reference Guide </drawRightString> <drawRightString x="20cm" y="28.1cm"> Reference Guide </drawRightString>
<lineMode width="0.7"/> <lineMode width="0.7"/>
<stroke color="black"/> <stroke color="black"/>
<lines>1cm 28cm 20cm 28cm</lines> <lines>1cm 28cm 20cm 28cm</lines>
</pageGraphics> </pageGraphics>
</header> </header>
</pageTemplate> </pageTemplate>
</template> </template>
@ -236,7 +236,7 @@
<tr> <tr>
<td> <td>
<para style="terp_default_9">[[ repeatIn(objdoc2(object.model) or [], 'sline') ]]</para> <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> </td>
</tr> </tr>
</blockTable> </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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################## ##############################################################################
from osv import osv
from osv import fields
import os import os
import tools
import openerp import openerp
from openerp import SUPERUSER_ID 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.translate import _
from tools.safe_eval import safe_eval as eval 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) part_obj.create(cr, uid, {name: value or False, 'parent_id': company.partner_id.id}, context=context)
return True 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 = { _columns = {
'name': fields.related('partner_id', 'name', string='Company Name', size=128, required=True, store=True, type='char'), '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), '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), '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."), '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': 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_id': fields.many2one('res.currency', 'Currency', required=True),
'currency_ids': fields.one2many('res.currency', 'company_id', 'Currency'), 'currency_ids': fields.one2many('res.currency', 'company_id', 'Currency'),
'user_ids': fields.many2many('res.users', 'res_company_users_rel', 'cid', 'user_id', 'Accepted Users'), '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: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -21,10 +21,10 @@
<form string="Company" version="7.0"> <form string="Company" version="7.0">
<sheet> <sheet>
<div> <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>
<div class="oe_right oe_button_box" name="button_box"> <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>
<div class="oe_title"> <div class="oe_title">
<label for="name" class="oe_edit_only"/> <label for="name" class="oe_edit_only"/>

View File

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

View File

@ -1186,7 +1186,7 @@
<record id="us" model="res.country"> <record id="us" model="res.country">
<field name="name">United States</field> <field name="name">United States</field>
<field name="code">us</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"/> <field name="currency_id" ref="USD"/>
</record> </record>
<record id="uy" model="res.country"> <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) res = super(res_currency, self).read(cr, user, ids, fields, context, load)
currency_rate_obj = self.pool.get('res.currency.rate') currency_rate_obj = self.pool.get('res.currency.rate')
values = res values = res
if not isinstance(values, (list)): if not isinstance(values, list):
values = [values] values = [values]
for r in values: for r in values:
if r.__contains__('rate_ids'): if r.__contains__('rate_ids'):
@ -217,7 +217,7 @@ class res_currency(osv.osv):
if round: if round:
return self.round(cr, uid, to_currency, from_amount * rate) return self.round(cr, uid, to_currency, from_amount * rate)
else: else:
return (from_amount * rate) return from_amount * rate
res_currency() 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'] thousands_sep = lang_obj.thousands_sep or conv[monetary and 'mon_thousands_sep' or 'thousands_sep']
decimal_point = lang_obj.decimal_point decimal_point = lang_obj.decimal_point
grouping = lang_obj.grouping 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): def write(self, cr, uid, ids, vals, context=None):
for lang_id in ids : for lang_id in ids :
@ -231,7 +231,7 @@ lang()
def original_group(s, grouping, thousands_sep=''): def original_group(s, grouping, thousands_sep=''):
if not grouping: if not grouping:
return (s, 0) return s, 0
result = "" result = ""
seps = 0 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'), 'bank_ids': fields.one2many('res.partner.bank', 'partner_id', 'Banks'),
'website': fields.char('Website', size=64, help="Website of Partner or Company"), 'website': fields.char('Website', size=64, help="Website of Partner or Company"),
'comment': fields.text('Notes'), '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'), 'category_id': fields.many2many('res.partner.category', id1='partner_id', id2='category_id', string='Tags'),
'credit_limit': fields.float(string='Credit Limit'), 'credit_limit': fields.float(string='Credit Limit'),
'ean13': fields.char('EAN13', size=13), 'ean13': fields.char('EAN13', size=13),
@ -321,7 +317,7 @@ class res_partner(osv.osv, format_address):
if default is None: if default is None:
default = {} default = {}
name = self.read(cr, uid, [id], ['name'], context)[0]['name'] 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) return super(res_partner, self).copy(cr, uid, id, default, context)
def onchange_type(self, cr, uid, ids, is_company, context=None): 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): 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) res = super(res_partner, self).view_header_get(cr, uid, view_id, view_type, context)
if res: return res if res: return res
if (not context.get('category_id', False)): if not context.get('category_id', False):
return False return False
return _('Partners: ')+self.pool.get('res.partner.category').browse(cr, uid, context['category_id'], context).name 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 The purpose of this function is to build and return an address formatted accordingly to the
standards of the country where it belongs. 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 :returns: the address formatted in a display that fit its country habits (or the default ones
if not country is specified) if not country is specified)
:rtype: string :rtype: string
@ -576,55 +572,4 @@ class res_partner(osv.osv, format_address):
address_format = '%(company_name)s\n' + address_format address_format = '%(company_name)s\n' + address_format
return address_format % args 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: # 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()) 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')) 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()) ids2 = map(lambda x:x[0], cr.fetchall())
return (ids, ids2) return ids, ids2
_columns = { _columns = {
'create_date': fields.datetime('Created Date', readonly=True), 'create_date': fields.datetime('Created Date', readonly=True),

View File

@ -142,7 +142,7 @@ class res_users(osv.osv):
'id': fields.integer('ID'), 'id': fields.integer('ID'),
'login_date': fields.date('Latest connection', select=1), 'login_date': fields.date('Latest connection', select=1),
'partner_id': fields.many2one('res.partner', required=True, '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'), help='Partner-related data of the user'),
'login': fields.char('Login', size=64, required=True, 'login': fields.char('Login', size=64, required=True,
help="Used to log into the system"), 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) # 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'] 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 # 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 read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
def override_password(o): def override_password(o):
@ -303,6 +303,7 @@ class res_users(osv.osv):
for id in ids: for id in ids:
if id in self._uid_cache[db]: if id in self._uid_cache[db]:
del self._uid_cache[db][id] del self._uid_cache[db][id]
self.context_get.clear_cache(self, cr)
return res return res
@ -337,6 +338,7 @@ class res_users(osv.osv):
default['login'] = _("%s (copy)") % user2copy['login'] default['login'] = _("%s (copy)") % user2copy['login']
return super(res_users, self).copy(cr, uid, id, default, context) return super(res_users, self).copy(cr, uid, id, default, context)
@tools.ormcache(skiparg=2)
def context_get(self, cr, uid, context=None): def context_get(self, cr, uid, context=None):
user = self.browse(cr, SUPERUSER_ID, uid, context) user = self.browse(cr, SUPERUSER_ID, uid, context)
result = {} 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 = [ checks = [
test_base, test_base,
test_expression, test_expression,
test_search, test_search,
test_ir_values, 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 pickle
import base64 import base64
import socket import socket
import string
admin_passwd = 'admin' admin_passwd = 'admin'
waittime = 10 waittime = 10
@ -67,10 +68,10 @@ def execute(connector, method, *args):
except socket.error,e: except socket.error,e:
if e.args[0] == 111: if e.args[0] == 111:
if wait_count > wait_limit: 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() clean()
sys.exit(1) sys.exit(1)
print 'Please wait %d sec to start server....'%(waittime) print 'Please wait %d sec to start server....' % waittime
wait_count += 1 wait_count += 1
time.sleep(waittime) time.sleep(waittime)
res = execute(connector, method, *args) 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', '')) 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','')) test_detail[test] = (score,msg,detail.get('detail',''))
html += "</ul>" html += "</ul>"
html += "%s"%(detail_html) html += "%s"% detail_html
html += "</div></body></html>" html += "</div></body></html>"
if not os.path.isdir(quality_logs): if not os.path.isdir(quality_logs):
os.mkdir(quality_logs) os.mkdir(quality_logs)
@ -305,13 +306,11 @@ options = {
'port' : opt.port or 8069, 'port' : opt.port or 8069,
'netport':opt.netport or 8070, 'netport':opt.netport or 8070,
'database': opt.db_name or 'terp', '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', 'login' : opt.login or 'admin',
'pwd' : opt.pwd or '', 'pwd' : opt.pwd or '',
'extra-addons':opt.extra_addons 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 # Hint:i18n-import=purchase:ar_AR.po+sale:fr_FR.po,nl_BE.po
if opt.translate_in: if opt.translate_in:
translate = opt.translate_in translate = opt.translate_in

View File

@ -94,10 +94,8 @@ def setup_pid_file():
def preload_registry(dbname): def preload_registry(dbname):
""" Preload a registry, and start the cron.""" """ Preload a registry, and start the cron."""
try: try:
db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=openerp.tools.config['init'] or openerp.tools.config['update'], pooljobs=False) 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)
# jobs will start to be processed later, when openerp.cron.start_master_thread() is called by openerp.service.start_services()
registry.schedule_cron_jobs()
except Exception: except Exception:
_logger.exception('Failed to initialize database `%s`.', dbname) _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) # some defaults (also taking care of pure ASCII)
for charset in ['utf8','latin1']: 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 yield charset
from locale import getpreferredencoding from locale import getpreferredencoding
@ -129,7 +129,7 @@ def ustr(value, hint_encoding='utf-8', errors='strict'):
:param: value: the value to convert :param: value: the value to convert
:param: hint_encoding: an optional encoding that was detecte :param: hint_encoding: an optional encoding that was detecte
upstream and should be tried first to decode ``value``. 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 built-in to indicate how illegal character values should be
treated when converting a string: 'strict', 'ignore' or 'replace' treated when converting a string: 'strict', 'ignore' or 'replace'
(see ``unicode()`` constructor). (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) migrations = openerp.modules.migration.MigrationManager(cr, graph)
_logger.debug('loading %d packages...', len(graph)) _logger.debug('loading %d packages...', len(graph))
# get db timestamp # Query manual fields for all models at once and save them on the registry
cr.execute("select (now() at time zone 'UTC')::timestamp") # so the initialization code for each model does not have to do it
dt_before_load = cr.fetchone()[0] # 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 # register, instantiate and initialize models for each modules
for index, package in enumerate(graph): 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) load_openerp_module(package.name)
models = pool.load(cr, package) models = pool.load(cr, package)
loaded_modules.append(package.name) loaded_modules.append(package.name)
if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'): if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
init_module_models(cr, package.name, models) 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) delattr(package, kind)
cr.commit() 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() 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()]) incorrect_names = mod_names.difference([x['name'] for x in cr.dictfetchall()])
_logger.warning('invalid module names, ignored: %s', ", ".join(incorrect_names)) _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 """Loads modules marked with ``states``, adding them to ``graph`` and
``loaded_modules`` and returns a list of installed/upgraded modules.""" ``loaded_modules`` and returns a list of installed/upgraded modules."""
processed_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] module_list = [name for (name,) in cr.fetchall() if name not in graph]
graph.add_modules(cr, module_list, force) graph.add_modules(cr, module_list, force)
_logger.debug('Updating graph with %d more modules', len(module_list)) _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) processed_modules.extend(processed)
loaded_modules.extend(loaded) loaded_modules.extend(loaded)
if not processed: break 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 # processed_modules: for cleanup step after install
# loaded_modules: to avoid double loading # loaded_modules: to avoid double loading
report = pool._assertion_report 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']: if tools.config['load_language']:
for lang in tools.config['load_language'].split(','): 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 # be dropped in STEP 6 later, before restarting the loading
# process. # process.
states_to_load = ['installed', 'to upgrade', 'to remove'] 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) processed_modules.extend(processed)
if update_module: if update_module:
states_to_load = ['to install'] 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) processed_modules.extend(processed)
# load custom models # load custom models

View File

@ -50,6 +50,7 @@ class Registry(object):
self._init = True self._init = True
self._init_parent = {} self._init_parent = {}
self._assertion_report = assertion_report.assertion_report() self._assertion_report = assertion_report.assertion_report()
self.fields_by_model = None
# modules fully loaded (maintained during init phase by `loading` module) # modules fully loaded (maintained during init phase by `loading` module)
self._init_modules = set() self._init_modules = set()
@ -109,15 +110,16 @@ class Registry(object):
and registers them in the registry. and registers them in the registry.
""" """
models_to_load = [] # need to preserve loading order
res = []
# Instantiate registered classes (via the MetaModel automatic discovery # Instantiate registered classes (via the MetaModel automatic discovery
# or via explicit constructor call), and add them to the pool. # or via explicit constructor call), and add them to the pool.
for cls in openerp.osv.orm.MetaModel.module_to_models.get(module.name, []): for cls in openerp.osv.orm.MetaModel.module_to_models.get(module.name, []):
res.append(cls.create_instance(self, cr)) # models register themselves in self.models
model = cls.create_instance(self, cr)
return res 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): def schedule_cron_jobs(self):
""" Make the cron thread care about this registry/database jobs. """ 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')] - src_model='res_users', join_tables=[(res.partner, 'parent_id')]
alias = ('res_users__parent_id', '"res_partner" as "res_users__parent_id"') alias = ('res_users__parent_id', '"res_partner" as "res_users__parent_id"')
:param model src_model: model source of the alias :param model src_table_alias: model source of the alias
:param list join_tables: list of tuples :param list joined_tables: list of tuples
(dst_model, link_field) (dst_model, link_field)
:return tuple: (table_alias, alias statement for from clause with quotes added) :return tuple: (table_alias, alias statement for from clause with quotes added)
""" """
alias = src_table_alias alias = src_table_alias
if not joined_tables: if not joined_tables:
return ('%s' % alias, '%s' % _quote(alias)) return '%s' % alias, '%s' % _quote(alias)
for link in joined_tables: for link in joined_tables:
alias += '__' + link[1] alias += '__' + link[1]
assert len(alias) < 64, 'Table alias name %s is longer than the 64 characters size accepted by default in postgresql.' % (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))) return '%s' % alias, '%s as %s' % (_quote(joined_tables[-1][0]), _quote(alias))
def get_alias_from_query(from_query): def get_alias_from_query(from_query):
""" :param string from_query: is something like : """ :param string from_query: is something like :
- '"res_partner"' OR - '"res_partner"' OR
- '"res_partner" as "res_users__partner_id"'' - '"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 ') from_splitted = from_query.split(' as ')
if len(from_splitted) > 1: if len(from_splitted) > 1:
return (from_splitted[0].replace('"', ''), from_splitted[1].replace('"', '')) return from_splitted[0].replace('"', ''), from_splitted[1].replace('"', '')
else: else:
return (from_splitted[0].replace('"', ''), from_splitted[0].replace('"', '')) return from_splitted[0].replace('"', ''), from_splitted[0].replace('"', '')
def normalize_leaf(element): def normalize_leaf(element):
@ -377,7 +375,7 @@ def normalize_leaf(element):
if isinstance(right, (list, tuple)) and operator in ('=', '!='): 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),)) _logger.warning("The domain term '%s' should use the 'in' or 'not in' operator." % ((left, original, right),))
operator = 'in' if operator == '=' else 'not in' operator = 'in' if operator == '=' else 'not in'
return (left, operator, right) return left, operator, right
def is_operator(element): def is_operator(element):
@ -497,11 +495,19 @@ class ExtendedLeaf(object):
adding joins adding joins
:attr list join_context: list of join contexts. This is a list of :attr list join_context: list of join contexts. This is a list of
tuples like ``(lhs, table, lhs_col, col, link)`` tuples like ``(lhs, table, lhs_col, col, link)``
:param obj lhs: source (left hand) model
:param obj model: destination (right hand) model where
:param string lhs_col: source model column for join condition
:param string col: destination model column for join condition lhs
:param link: link column between source and destination model 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 that is not necessarily (but generally) a real column used
in the condition (i.e. in many2one); this link is used to in the condition (i.e. in many2one); this link is used to
compute aliases compute aliases
@ -829,7 +835,7 @@ class expression(object):
push(create_substitution_leaf(leaf, AND_OPERATOR, relational_model)) push(create_substitution_leaf(leaf, AND_OPERATOR, relational_model))
elif len(field_path) > 1 and field._auto_join: 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': elif len(field_path) > 1 and field._type == 'many2one':
right_ids = relational_model.search(cr, uid, [(field_path[1], operator, right)], context=context) 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)] 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: if operator in NEGATIVE_TERM_OPERATORS:
res_ids.append(False) # TODO this should not be appended if False was in 'right' 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 # resolve string-based m2o criterion into IDs
if isinstance(right, basestring) or \ if isinstance(right, basestring) or \
right and isinstance(right, (tuple, list)) and all(isinstance(item, basestring) for item in right): 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) query = '(%s."%s" IS %s)' % (table_alias, left, r)
params = [] params = []
elif isinstance(right, (list, tuple)): elif isinstance(right, (list, tuple)):
params = right[:] params = list(right)
check_nulls = False check_nulls = False
for i in range(len(params))[::-1]: for i in range(len(params))[::-1]:
if params[i] == False: if params[i] == False:
@ -1140,8 +1146,8 @@ class expression(object):
query = '%s."%s" IS NOT NULL' % (table_alias, left) query = '%s."%s" IS NOT NULL' % (table_alias, left)
params = [] params = []
elif (operator == '=?'): elif operator == '=?':
if (right is False or right is None): if right is False or right is None:
# '=?' is a short-circuit that makes the term TRUE if right is None or False # '=?' is a short-circuit that makes the term TRUE if right is None or False
query = 'TRUE' query = 'TRUE'
params = [] params = []
@ -1187,7 +1193,7 @@ class expression(object):
if isinstance(params, basestring): if isinstance(params, basestring):
params = [params] params = [params]
return (query, params) return query, params
def to_sql(self): def to_sql(self):
stack = [] stack = []
@ -1213,6 +1219,6 @@ class expression(object):
if joins: if joins:
query = '(%s) AND %s' % (joins, query) 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: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -668,7 +668,7 @@ class many2many(_column):
col1 = '%s_id' % source_model._table col1 = '%s_id' % source_model._table
if not col2: if not col2:
col2 = '%s_id' % dest_model._table 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): def _get_query_and_where_params(self, cr, model, ids, values, where_params):
""" Extracted from ``get`` to facilitate fine-tuning of the generated """ Extracted from ``get`` to facilitate fine-tuning of the generated
@ -1304,7 +1304,7 @@ class sparse(function):
def __init__(self, serialization_field, **kwargs): def __init__(self, serialization_field, **kwargs):
self.serialization_field = serialization_field 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): def __str__(self):
return '%s(%s, %s, %s, %s, %s)' % ( 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) self.parent_model, self.parent_column, self.original_parent)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # 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() new_data[field_name] = browse_null()
elif field_column._type in ('one2many', 'many2many') and len(result_line[field_name]): 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) 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 result_line[field_name]:
if isinstance(result_line[field_name], browse_record): if isinstance(result_line[field_name], browse_record):
new_data[field_name] = result_line[field_name] new_data[field_name] = result_line[field_name]
@ -865,10 +865,6 @@ class BaseModel(object):
parent_names = [parent_names] parent_names = [parent_names]
else: else:
name = cls._name 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: if not name:
raise TypeError('_name is mandatory in case of multiple inheritance') raise TypeError('_name is mandatory in case of multiple inheritance')
@ -1018,45 +1014,50 @@ class BaseModel(object):
# Load manual fields # Load manual fields
cr.execute("SELECT id FROM ir_model_fields WHERE name=%s AND model=%s", ('state', 'ir.model.fields')) # Check the query is already done for all modules of if we need to
if cr.fetchone(): # 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')) cr.execute('SELECT * FROM ir_model_fields WHERE model=%s AND state=%s', (self._name, 'manual'))
for field in cr.dictfetchall(): manual_fields = cr.dictfetchall()
if field['name'] in self._columns: for field in manual_fields:
continue if field['name'] in self._columns:
attrs = { continue
'string': field['field_description'], attrs = {
'required': bool(field['required']), 'string': field['field_description'],
'readonly': bool(field['readonly']), 'required': bool(field['required']),
'domain': eval(field['domain']) if field['domain'] else None, 'readonly': bool(field['readonly']),
'size': field['size'], 'domain': eval(field['domain']) if field['domain'] else None,
'ondelete': field['on_delete'], 'size': field['size'],
'translate': (field['translate']), 'ondelete': field['on_delete'],
'manual': True, 'translate': (field['translate']),
#'select': int(field['select_level']) '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_check()
self._inherits_reload() self._inherits_reload()
if not self._sequence: if not self._sequence:
@ -1741,7 +1742,7 @@ class BaseModel(object):
views = {} views = {}
xml = "<form>" xml = "<form>"
for f in node: for f in node:
if f.tag in ('field'): if f.tag == 'field':
xml += etree.tostring(f, encoding="utf-8") xml += etree.tostring(f, encoding="utf-8")
xml += "</form>" xml += "</form>"
new_xml = etree.fromstring(encode(xml)) new_xml = etree.fromstring(encode(xml))
@ -2010,7 +2011,7 @@ class BaseModel(object):
view = etree.Element('calendar', string=self._description) view = etree.Element('calendar', string=self._description)
etree.SubElement(view, 'field', self._rec_name_fallback(cr, user, context)) 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 date_found = False
for dt in ['date', 'date_start', 'x_date', 'x_date_start']: for dt in ['date', 'date_start', 'x_date', 'x_date_start']:
if dt in self._columns: if dt in self._columns:
@ -2031,7 +2032,7 @@ class BaseModel(object):
self._columns, 'date_delay'): self._columns, 'date_delay'):
raise except_orm( raise except_orm(
_('Invalid Object Architecture!'), _('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 return view
@ -2411,7 +2412,7 @@ class BaseModel(object):
:rtype: tuple :rtype: tuple
:return: the :meth:`~.name_get` pair value for the newly-created record. :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] 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 # 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 groupby = group_by
for r in cr.dictfetchall(): for r in cr.dictfetchall():
for fld, val in r.items(): for fld, val in r.items():
if val == None: r[fld] = False if val is None: r[fld] = False
alldata[r['id']] = r alldata[r['id']] = r
del r['id'] del r['id']
@ -2889,15 +2890,15 @@ class BaseModel(object):
# usually because they could block deletion due to the FKs. # usually because they could block deletion due to the FKs.
# So unless stated otherwise we default them to ondelete=cascade. # So unless stated otherwise we default them to ondelete=cascade.
ondelete = ondelete or 'cascade' ondelete = ondelete or 'cascade'
self._foreign_keys.append((self._table, source_field, dest_model._table, ondelete or 'set null')) fk_def = (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._foreign_keys.add(fk_def)
self._table, source_field, dest_model._table, ondelete) _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 # unchecked version: for custom cases, such as m2m relationships
def _m2o_add_foreign_key_unchecked(self, source_table, source_field, dest_model, ondelete): 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')) fk_def = (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", self._foreign_keys.add(fk_def)
source_table, source_field, dest_model._table, ondelete) _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): def _drop_constraint(self, cr, source_table, constraint_name):
cr.execute("ALTER TABLE %s DROP CONSTRAINT %s" % (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 cons, = constraints
if cons['ondelete_rule'] != POSTGRES_CONFDELTYPES.get((ondelete or 'set null').upper(), 'a')\ if cons['ondelete_rule'] != POSTGRES_CONFDELTYPES.get((ondelete or 'set null').upper(), 'a')\
or cons['foreign_table'] != dest_model._table: or cons['foreign_table'] != dest_model._table:
# Wrong FK: drop it and recreate
_schema.debug("Table '%s': dropping obsolete FK constraint: '%s'", _schema.debug("Table '%s': dropping obsolete FK constraint: '%s'",
source_table, cons['constraint_name']) source_table, cons['constraint_name'])
self._drop_constraint(cr, 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:
# else it's all good, nothing to do! # it's all good, nothing to do!
return
else: else:
# Multiple FKs found for the same field, drop them all, and re-create # Multiple FKs found for the same field, drop them all, and re-create
for cons in constraints: for cons in constraints:
_schema.debug("Table '%s': dropping duplicate FK constraints: '%s'", _schema.debug("Table '%s': dropping duplicate FK constraints: '%s'",
source_table, cons['constraint_name']) source_table, cons['constraint_name'])
self._drop_constraint(cr, 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). _auto_end).
""" """
self._foreign_keys = [] self._foreign_keys = set()
raise_on_invalid_object_name(self._name) raise_on_invalid_object_name(self._name)
if context is None: if context is None:
context = {} context = {}
@ -3097,7 +3102,7 @@ class BaseModel(object):
else: else:
default = self._defaults[k] default = self._defaults[k]
if (default is not None): if default is not None:
ss = self._columns[k]._symbol_set ss = self._columns[k]._symbol_set
query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (self._table, k, ss[0], k) query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (self._table, k, ss[0], k)
cr.execute(query, (ss[1](default),)) cr.execute(query, (ss[1](default),))
@ -3176,7 +3181,7 @@ class BaseModel(object):
# and add constraints if needed # and add constraints if needed
if isinstance(f, fields.many2one): if isinstance(f, fields.many2one):
if not self.pool.get(f._obj): 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) dest_model = self.pool.get(f._obj)
ref = dest_model._table ref = dest_model._table
# ir_actions is inherited so foreign key doesn't work on it # 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: 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)', _logger.error('parent_right column on object %s must be indexed! Add select=1 to the field definition)',
self._table) self._table)
if self._columns[self._parent_name].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'", _logger.error("The column %s on object %s must be set as ondelete='cascade' or 'restrict'",
self._parent_name, self._name) self._parent_name, self._name)
cr.commit() cr.commit()
@ -3303,7 +3308,7 @@ class BaseModel(object):
# TODO the condition could use fields_get_keys(). # TODO the condition could use fields_get_keys().
if f._fields_id not in other._columns.keys(): if f._fields_id not in other._columns.keys():
if f._fields_id not in other._inherit_fields.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): def _m2m_raise_or_create_relation(self, cr, f):
m2m_tbl, col1, col2 = f._sql_names(self) 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,)) cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s", (m2m_tbl,))
if not cr.dictfetchall(): if not cr.dictfetchall():
if not self.pool.get(f._obj): 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) dest_model = self.pool.get(f._obj)
ref = dest_model._table 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)) 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) _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, self._columns[field_name] = fields.many2one(table, string="Automatically created field to link to parent %s" % table,
required=True, ondelete="cascade") required=True, ondelete="cascade")
elif not self._columns[field_name].required or self._columns[field_name].ondelete.lower() != "cascade": 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", forcing it.', field_name, self._name) _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].required = True
self._columns[field_name].ondelete = "cascade" self._columns[field_name].ondelete = "cascade"
@ -3485,7 +3490,7 @@ class BaseModel(object):
:param cr: database cursor :param cr: database cursor
:param user: current user id :param user: current user id
:param fields: list of fields :param allfields: list of fields
:param context: context arguments, like lang, time zone :param context: context arguments, like lang, time zone
:return: dictionary of field dictionaries, each one describing a field of the business object :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 :raise AccessError: * if user has no create/write rights on the requested object
@ -3536,6 +3541,37 @@ class BaseModel(object):
return res 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'): def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
""" Read records with given ids with the given fields """ Read records with given ids with the given fields
@ -3561,8 +3597,7 @@ class BaseModel(object):
if not context: if not context:
context = {} context = {}
self.check_access_rights(cr, user, 'read') self.check_access_rights(cr, user, 'read')
if not fields: fields = self.check_field_access_rights(cr, user, 'read', fields)
fields = list(set(self._columns.keys() + self._inherit_fields.keys()))
if isinstance(ids, (int, long)): if isinstance(ids, (int, long)):
select = [ids] select = [ids]
else: else:
@ -3584,7 +3619,7 @@ class BaseModel(object):
context = {} context = {}
if not ids: if not ids:
return [] return []
if fields_to_read == None: if fields_to_read is None:
fields_to_read = self._columns.keys() fields_to_read = self._columns.keys()
# Construct a clause for the security rules. # Construct a clause for the security rules.
@ -3628,15 +3663,16 @@ class BaseModel(object):
else: else:
res = map(lambda x: {'id': x}, ids) res = map(lambda x: {'id': x}, ids)
for f in fields_pre: if context.get('lang'):
if f == self.CONCURRENCY_CHECK_FIELD: for f in fields_pre:
continue if f == self.CONCURRENCY_CHECK_FIELD:
if self._columns[f].translate: continue
ids = [x['id'] for x in res] if self._columns[f].translate:
#TODO: optimize out of this loop ids = [x['id'] for x in res]
res_trans = self.pool.get('ir.translation')._get_ids(cr, user, self._name+','+f, 'model', context.get('lang', False) or 'en_US', ids) #TODO: optimize out of this loop
for r in res: res_trans = self.pool.get('ir.translation')._get_ids(cr, user, self._name+','+f, 'model', context['lang'], ids)
r[f] = res_trans.get(r['id'], False) or r[f] for r in res:
r[f] = res_trans.get(r['id'], False) or r[f]
for table in self._inherits: for table in self._inherits:
col = self._inherits[table] col = self._inherits[table]
@ -4018,6 +4054,7 @@ class BaseModel(object):
""" """
readonly = None readonly = None
self.check_field_access_rights(cr, user, 'write', vals.keys())
for field in vals.copy(): for field in vals.copy():
fobj = None fobj = None
if field in self._columns: if field in self._columns:
@ -4672,7 +4709,7 @@ class BaseModel(object):
new_tables = [] new_tables = []
for table in added_tables: for table in added_tables:
# table is just a table name -> switch to the full alias # 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)) 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 # table is already a full statement -> replace reference to the table to its alias, is correct with the way aliases are generated
else: else:
@ -4838,7 +4875,7 @@ class BaseModel(object):
Copy given record's data with all its fields values Copy given record's data with all its fields values
:param cr: database cursor :param cr: database cursor
:param user: current user id :param uid: current user id
:param id: id of the record to copy :param id: id of the record to copy
:param default: field values to override in the original values of the copied record :param default: field values to override in the original values of the copied record
:type default: dictionary :type default: dictionary
@ -4997,7 +5034,7 @@ class BaseModel(object):
""" """
if type(ids) in (int, long): if type(ids) in (int, long):
ids = [ids] 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),)) cr.execute(query + "WHERE ID IN %s", (tuple(ids),))
return [x[0] for x in cr.fetchall()] 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 = add_joins_for_table(table_alias, query_from)
query_from += ',' query_from += ','
query_from = query_from[:-1] # drop last comma 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): def __str__(self):
return '<osv.Query: "SELECT ... FROM %s WHERE %s" with params: %r>' % self.get_sql() 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: else:
# Process group_by data first # Process group_by data first
key = [] 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(): if fields[group_by][0] in levels.keys():
key.append(fields[group_by][0]) key.append(fields[group_by][0])
for l in levels.keys(): 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']) 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'] model_name = self.pool.get('ir.model').read(cr, uid, [report['model_id'][0]], ['model'], context=context)[0]['model']
fct = {} fct = {
fct['id'] = lambda x : x 'id': lambda x: x,
fct['gety'] = lambda x: x.split('-')[0] 'gety': lambda x: x.split('-')[0],
fct['in'] = lambda x: x.split(',') 'in': lambda x: x.split(',')
}
new_fields = [] new_fields = []
new_cond = [] new_cond = []
for f in fields: for f in fields:
@ -212,7 +213,7 @@ class report_custom(report_int):
new_res = [] new_res = []
prev = None prev = None
if groupby != None: if groupby is not None:
res_dic = {} res_dic = {}
for line in results: for line in results:
if not line[groupby] and prev in res_dic: 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) res = self._create_bars(cr,uid, ids, report, fields, results2, context)
elif report['type']=='line': elif report['type']=='line':
res = self._create_lines(cr,uid, ids, report, fields, results2, context) 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): def _create_tree(self, uid, ids, report, fields, level, results, context):
pageSize=common.pageSize.get(report['print_format'], [210.0,297.0]) 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', col.attrib.update(para='yes',
tree='yes', tree='yes',
space=str(3*shift)+'mm') space=str(3*shift)+'mm')
if line[f] != None: if line[f] is not None:
col.text = prefix+str(line[f]) or '' col.text = prefix+str(line[f]) or ''
else: else:
col.text = '/' col.text = '/'
@ -350,15 +351,17 @@ class report_custom(report_int):
x_axis = axis.X(label = fields[0]['name'], format="/a-30{}%s"), 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:])))) y_axis = axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:]))))
process_date = {} process_date = {
process_date['D'] = lambda x : reduce(lambda xx,yy : xx+'-'+yy,x.split('-')[1:3]) 'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]),
process_date['M'] = lambda x : x.split('-')[1] 'M': lambda x: x.split('-')[1],
process_date['Y'] = lambda x : x.split('-')[0] 'Y': lambda x: x.split('-')[0]
}
order_date = {} order_date = {
order_date['D'] = lambda x : time.mktime((2005,int(x.split('-')[0]), int(x.split('-')[1]),0,0,0,0,0,0)) '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 'M': lambda x: x,
order_date['Y'] = lambda x : x 'Y': lambda x: x
}
abscissa = [] abscissa = []
@ -381,7 +384,7 @@ class report_custom(report_int):
# plots are usually displayed year by year # plots are usually displayed year by year
# so we do so if the first field is a date # so we do so if the first field is a date
data_by_year = {} data_by_year = {}
if date_idx != None: if date_idx is not None:
for r in results: for r in results:
key = process_date['Y'](r[date_idx]) key = process_date['Y'](r[date_idx])
if key not in data_by_year: if key not in data_by_year:
@ -447,15 +450,17 @@ class report_custom(report_int):
can.show(80,380,'/16/H'+report['title']) can.show(80,380,'/16/H'+report['title'])
process_date = {} process_date = {
process_date['D'] = lambda x : reduce(lambda xx,yy : xx+'-'+yy,x.split('-')[1:3]) 'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]),
process_date['M'] = lambda x : x.split('-')[1] 'M': lambda x: x.split('-')[1],
process_date['Y'] = lambda x : x.split('-')[0] 'Y': lambda x: x.split('-')[0]
}
order_date = {} order_date = {
order_date['D'] = lambda x : time.mktime((2005,int(x.split('-')[0]), int(x.split('-')[1]),0,0,0,0,0,0)) '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 'M': lambda x: x,
order_date['Y'] = lambda x : x 'Y': lambda x: x
}
ar = area.T(size=(350,350), ar = area.T(size=(350,350),
x_axis = axis.X(label = fields[0]['name'], format="/a-30{}%s"), 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 # plot are usually displayed year by year
# so we do so if the first field is a date # so we do so if the first field is a date
data_by_year = {} data_by_year = {}
if date_idx != None: if date_idx is not None:
for r in results: for r in results:
key = process_date['Y'](r[date_idx]) key = process_date['Y'](r[date_idx])
if key not in data_by_year: if key not in data_by_year:
@ -602,7 +607,7 @@ class report_custom(report_int):
node_line = etree.SubElement(lines, 'row') node_line = etree.SubElement(lines, 'row')
for f in range(len(fields)): for f in range(len(fields)):
col = etree.SubElement(node_line, 'col', tree='no') col = etree.SubElement(node_line, 'col', tree='no')
if line[f] != None: if line[f] is not None:
col.text = line[f] or '' col.text = line[f] or ''
else: else:
col.text = '/' col.text = '/'

View File

@ -52,7 +52,7 @@ def _1000_to_text(chiffre):
d2 = chiffre/100 d2 = chiffre/100
if d2>0 and d: if d2>0 and d:
return centaine[d2]+' '+d return centaine[d2]+' '+d
elif d2>1 and not(d): elif d2>1 and not d:
return centaine[d2]+'s' return centaine[d2]+'s'
else: else:
return centaine[d2] or d 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): def create(self, cr, uid, ids, datas, context=None):
return False 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): 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): def __init__(self, name, table, tmpl, xsl):
super(report_rml, self).__init__(name) super(report_rml, self).__init__(name)
self.table = table self.table = table
@ -85,7 +84,7 @@ class report_rml(report_int):
xml = tools.ustr(xml).encode('utf8') xml = tools.ustr(xml).encode('utf8')
report_type = datas.get('report_type', 'pdf') report_type = datas.get('report_type', 'pdf')
if report_type == 'raw': if report_type == 'raw':
return (xml,report_type) return xml, report_type
rml = self.create_rml(cr, xml, uid, context) rml = self.create_rml(cr, xml, uid, context)
pool = pooler.get_pool(cr.dbname) pool = pooler.get_pool(cr.dbname)
ir_actions_report_xml_obj = pool.get('ir.actions.report.xml') 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' 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] create_doc = self.generators[report_type]
pdf = create_doc(rml, title=self.title) 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): def create_xml(self, cr, uid, ids, datas, context=None):
if not context: if not context:
@ -244,10 +243,10 @@ class report_rml(report_int):
return obj.get() return obj.get()
def _get_path(self): def _get_path(self):
ret = [] return [
ret.append(self.tmpl.replace(os.path.sep, '/').rsplit('/',1)[0]) # Same dir as the report rml self.tmpl.replace(os.path.sep, '/').rsplit('/', 1)[0],
ret.append('addons') 'addons',
ret.append(tools.config['root_path']) tools.config['root_path']
return ret ]
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # 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']) fields_order = self._parse_string(result['arch'])
rows = model.read(cr, uid, datas['ids'], result['fields'].keys() ) rows = model.read(cr, uid, datas['ids'], result['fields'].keys() )
self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model._description) 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=''): 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 precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
line[f]=round(line[f],precision) line[f]=round(line[f],precision)
col = etree.SubElement(node_line, 'col', tree='no') 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 '') col.text = tools.ustr(line[f] or '')
else: else:
col.text = '/' 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_new += [elem for elem in rows if elem['id'] == id]
rows = rows_new rows = rows_new
res = self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model_desc) 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=''): 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)): for i in range(0, len(fields_order)):
temp.append(0) temp.append(0)
tsum.append(0) tsum.append(0)
ince = -1; ince = -1
for f in fields_order: for f in fields_order:
s = 0 s = 0
ince += 1 ince += 1
@ -230,14 +230,14 @@ class report_printscreen_list(report_int):
col.text = line[f] = 'Undefined' col.text = line[f] = 'Undefined'
col.set('tree', 'undefined') col.set('tree', 'undefined')
if line[f] != None: if line[f] is not None:
col.text = tools.ustr(line[f] or '') col.text = tools.ustr(line[f] or '')
if float_flag: if float_flag:
col.set('tree','float') col.set('tree','float')
if line.get('__no_leaf') and temp[count] == 1 and f != 'id' and not line['__context']['group_by']: 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]) tsum[count] = float(tsum[count]) + float(line[f])
if not line.get('__group') and f != 'id' and temp[count] == 1: 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: else:
col.text = '/' col.text = '/'
@ -245,7 +245,7 @@ class report_printscreen_list(report_int):
for f in range(0, len(fields_order)): for f in range(0, len(fields_order)):
col = etree.SubElement(node_line, 'col', para='group', tree='no') col = etree.SubElement(node_line, 'col', para='group', tree='no')
col.set('tree', 'float') col.set('tree', 'float')
if tsum[f] != None: if tsum[f] is not None:
if tsum[f] != 0.0: if tsum[f] != 0.0:
digits = fields[fields_order[f]].get('digits', (16, 2)) digits = fields[fields_order[f]].get('digits', (16, 2))
prec = '%%.%sf' % (digits[1], ) prec = '%%.%sf' % (digits[1], )

View File

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

View File

@ -81,7 +81,7 @@ def readObject(stream, pdf):
return NumberObject.readFromStream(stream) return NumberObject.readFromStream(stream)
peek = stream.read(20) peek = stream.read(20)
stream.seek(-len(peek), 1) # reset to start 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) return IndirectObject.readFromStream(stream, pdf)
else: else:
return NumberObject.readFromStream(stream) return NumberObject.readFromStream(stream)
@ -169,7 +169,7 @@ class IndirectObject(PdfObject):
def __eq__(self, other): def __eq__(self, other):
return ( return (
other != None and other is not None and
isinstance(other, IndirectObject) and isinstance(other, IndirectObject) and
self.idnum == other.idnum and self.idnum == other.idnum and
self.generation == other.generation 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. # return None if no metadata was found on the document root.
def getXmpMetadata(self): def getXmpMetadata(self):
metadata = self.get("/Metadata", None) metadata = self.get("/Metadata", None)
if metadata == None: if metadata is None:
return None return None
metadata = metadata.getObject() metadata = metadata.getObject()
import xmp import xmp

View File

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

View File

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

View File

@ -66,7 +66,7 @@ class XmpInformation(PdfObject):
for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"): for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
if desc.getAttributeNS(RDF_NAMESPACE, "about") == aboutUri: if desc.getAttributeNS(RDF_NAMESPACE, "about") == aboutUri:
attr = desc.getAttributeNodeNS(namespace, name) attr = desc.getAttributeNodeNS(namespace, name)
if attr != None: if attr is not None:
yield attr yield attr
for element in desc.getElementsByTagNameNS(namespace, name): for element in desc.getElementsByTagNameNS(namespace, name):
yield element yield element
@ -187,7 +187,7 @@ class XmpInformation(PdfObject):
else: else:
value = self._getText(element) value = self._getText(element)
break break
if value != None: if value is not None:
value = converter(value) value = converter(value)
ns_cache = self.cache.setdefault(namespace, {}) ns_cache = self.cache.setdefault(namespace, {})
ns_cache[name] = value ns_cache[name] = value
@ -353,5 +353,5 @@ class XmpInformation(PdfObject):
custom_properties = property(custom_properties) 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) list_story.append(story_text)
del f del f
if template.data: if template.data:
tag = '''<img src = '%s' width=80 height=72/>'''%(template.data) tag = '''<img src = '%s' width=80 height=72/>'''% template.data
else: else:
tag = '' tag = ''
self.result +=''' 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])') 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): def get(col_str):
if col_str == None: if col_str is None:
col_str = '' col_str = ''
global allcols global allcols
if col_str in allcols.keys(): if col_str in allcols.keys():
return allcols[col_str] return allcols[col_str]
res = regex_t.search(col_str, 0) res = regex_t.search(col_str, 0)
if res: 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) res = regex_h.search(col_str, 0)
if res: if res:
return tuple([ float(int(res.group(i),16))/255 for i in range(1,4)]) 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 key=self._pageCounter
if not self.pages.get(key,False): if not self.pages.get(key,False):
while not self.pages.get(key,False): while not self.pages.get(key,False):
key = key + 1 key += 1
self.setFont("Helvetica", 8) self.setFont("Helvetica", 8)
self.drawRightString((self._pagesize[0]-30), (self._pagesize[1]-40), self.drawRightString((self._pagesize[0]-30), (self._pagesize[1]-40),
" %(this)i / %(total)i" % { " %(this)i / %(total)i" % {
@ -123,7 +123,7 @@ class PageCount(platypus.Flowable):
self.story_count = story_count self.story_count = story_count
def draw(self): 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.setFont("Helvetica", utils.unit_get(str(8)))
self.canv.drawString(0, 0, str(self.canv.getPageNumber())) self.canv.drawString(0, 0, str(self.canv.getPageNumber()))
self.canv.endForm() self.canv.endForm()
@ -268,18 +268,18 @@ class _rml_doc(object):
if fontname not in pdfmetrics._fonts: if fontname not in pdfmetrics._fonts:
pdfmetrics.registerFont(TTFont(fontname, filename)) pdfmetrics.registerFont(TTFont(fontname, filename))
if (mode == 'all'): if mode == 'all':
addMapping(face, 0, 0, fontname) #normal addMapping(face, 0, 0, fontname) #normal
addMapping(face, 0, 1, fontname) #italic addMapping(face, 0, 1, fontname) #italic
addMapping(face, 1, 0, fontname) #bold addMapping(face, 1, 0, fontname) #bold
addMapping(face, 1, 1, fontname) #italic and bold addMapping(face, 1, 1, fontname) #italic and bold
elif (mode== 'normal') or (mode == 'regular'): elif (mode== 'normal') or (mode == 'regular'):
addMapping(face, 0, 0, fontname) #normal addMapping(face, 0, 0, fontname) #normal
elif (mode == 'italic'): elif mode == 'italic':
addMapping(face, 0, 1, fontname) #italic addMapping(face, 0, 1, fontname) #italic
elif (mode == 'bold'): elif mode == 'bold':
addMapping(face, 1, 0, fontname) #bold addMapping(face, 1, 0, fontname) #bold
elif (mode == 'bolditalic'): elif mode == 'bolditalic':
addMapping(face, 1, 1, fontname) #italic and bold addMapping(face, 1, 1, fontname) #italic and bold
def _textual_image(self, node): def _textual_image(self, node):
@ -602,7 +602,7 @@ class _rml_Illustration(platypus.flowables.Flowable):
self.height = utils.unit_get(node.get('height')) self.height = utils.unit_get(node.get('height'))
self.self2 = self2 self.self2 = self2
def wrap(self, *args): def wrap(self, *args):
return (self.width, self.height) return self.width, self.height
def draw(self): 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 = _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) drw.render(self.canv, None)
@ -890,7 +890,7 @@ class TinyDocTemplate(platypus.BaseDocTemplate):
self.canv._storyCount = 0 self.canv._storyCount = 0
def ___handle_pageBegin(self): def ___handle_pageBegin(self):
self.page = self.page + 1 self.page += 1
self.pageTemplate.beforeDrawPage(self.canv,self) self.pageTemplate.beforeDrawPage(self.canv,self)
self.pageTemplate.checkPageSize(self.canv,self) self.pageTemplate.checkPageSize(self.canv,self)
self.pageTemplate.onPage(self.canv,self) self.pageTemplate.onPage(self.canv,self)

View File

@ -29,7 +29,8 @@ import utils
Font_size= 10.0 Font_size= 10.0
def verbose(text): def verbose(text):
sys.stderr.write(text+"\n"); sys.stderr.write(text+"\n")
class textbox(object): class textbox(object):
"""A box containing plain text. """A box containing plain text.
@ -107,11 +108,11 @@ class textbox(object):
def haplines(self,arr,offset,cc= ''): def haplines(self,arr,offset,cc= ''):
""" Horizontaly append lines """ Horizontaly append lines
""" """
while (len(self.lines) < len(arr)): while len(self.lines) < len(arr):
self.lines.append("") self.lines.append("")
for i in range(len(self.lines)): for i in range(len(self.lines)):
while (len(self.lines[i]) < offset): while len(self.lines[i]) < offset:
self.lines[i] += " " self.lines[i] += " "
for i in range(len(arr)): for i in range(len(arr)):
self.lines[i] += cc +arr[i] self.lines[i] += cc +arr[i]
@ -220,7 +221,7 @@ class _flowable(object):
def rec_render(self,node): def rec_render(self,node):
""" Recursive render: fill outarr with text of current 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: if node.tag in self._tags:
self._tags[node.tag](node) self._tags[node.tag](node)
else: else:
@ -255,12 +256,10 @@ class _rml_tmpl_frame(_rml_tmpl_tag):
self.posx = posx self.posx = posx
def tag_start(self): def tag_start(self):
return "frame start" 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): def tag_end(self):
return True return True
def tag_stop(self): def tag_stop(self):
return "frame stop" return "frame stop"
return '</td></tr></table><br/>'
def tag_mergeable(self): def tag_mergeable(self):
return False return False
@ -282,24 +281,7 @@ class _rml_tmpl_draw_string(_rml_tmpl_tag):
def tag_start(self): def tag_start(self):
return "draw string \"%s\" @(%d,%d)..\n" %("txt",self.posx,self.posy) 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): def merge(self, ds):
self.pos+=ds.pos self.pos+=ds.pos
@ -316,10 +298,6 @@ class _rml_tmpl_draw_lines(_rml_tmpl_tag):
def tag_start(self): def tag_start(self):
return "draw lines..\n" 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): class _rml_stylesheet(object):
def __init__(self, stylesheet, doc): def __init__(self, stylesheet, doc):
@ -456,11 +434,6 @@ class _rml_template(object):
def end(self): def end(self):
return "template end\n" return "template end\n"
result = ''
while not self.loop:
result += self.frame_start()
result += self.frame_stop()
return result
class _rml_doc(object): class _rml_doc(object):
def __init__(self, node, localcontext=None, images=None, path='.', title=None): 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) raise NotImplementedError(_('Unknown report type: %s') % report_type)
fnct_ret = fnct(cr, uid, ids, data, report_xml, context) fnct_ret = fnct(cr, uid, ids, data, report_xml, context)
if not fnct_ret: if not fnct_ret:
return (False,False) return False, False
return fnct_ret return fnct_ret
def create_source_odt(self, cr, uid, ids, data, report_xml, context=None): 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) logo = base64.decodestring(rml_parser.logo)
create_doc = self.generators[report_xml.report_type] create_doc = self.generators[report_xml.report_type]
pdf = create_doc(etree.tostring(processed_rml),rml_parser.localcontext,logo,title.encode('utf8')) 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): def create_single_odt(self, cr, uid, ids, data, report_xml, context=None):
if not context: if not context:
@ -644,7 +644,7 @@ class report_sxw(report_rml, preprocess.report):
sxw_z.close() sxw_z.close()
final_op = sxw_io.getvalue() final_op = sxw_io.getvalue()
sxw_io.close() 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): def create_single_html2html(self, cr, uid, ids, data, report_xml, context=None):
if not context: if not context:
@ -666,7 +666,7 @@ class report_sxw(report_rml, preprocess.report):
create_doc = self.generators['html2html'] create_doc = self.generators['html2html']
html = etree.tostring(create_doc(html_dom, html_parser.localcontext)) 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): def create_single_mako2html(self, cr, uid, ids, data, report_xml, context=None):
mako_html = report_xml.report_rml_content 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') html_parser.set_context(objs, data, ids, 'html')
create_doc = self.generators['makohtml2html'] create_doc = self.generators['makohtml2html']
html = create_doc(mako_html,html_parser.localcontext) html = create_doc(mako_html,html_parser.localcontext)
return (html,'html') return html,'html'
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

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

View File

@ -172,13 +172,13 @@ class db(netsvc.ExportService):
def exp_get_progress(self, id): def exp_get_progress(self, id):
if self.actions[id]['thread'].isAlive(): if self.actions[id]['thread'].isAlive():
# return openerp.modules.init_progress[db_name] # 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: else:
clean = self.actions[id]['clean'] clean = self.actions[id]['clean']
if clean: if clean:
users = self.actions[id]['users'] users = self.actions[id]['users']
self.actions.pop(id) self.actions.pop(id)
return (1.0, users) return 1.0, users
else: else:
e = self.actions[id]['exception'] # TODO this seems wrong: actions[id]['traceback'] is set, but not 'exception'. e = self.actions[id]['exception'] # TODO this seems wrong: actions[id]['traceback'] is set, but not 'exception'.
self.actions.pop(id) self.actions.pop(id)
@ -543,7 +543,7 @@ GNU Public Licence.
if os.name == 'posix': if os.name == 'posix':
if platform.system() == 'Linux': if platform.system() == 'Linux':
lsbinfo = os.popen('lsb_release -a').read() lsbinfo = os.popen('lsb_release -a').read()
environment += '%s'%(lsbinfo) environment += '%s'% lsbinfo
else: else:
environment += 'Your System is not lsb compliant\n' environment += 'Your System is not lsb compliant\n'
environment += 'Operating System Release : %s\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 Sometimes, like in special DAV folders, the OPTIONS may contain
extra keywords, perhaps also dependant on the request url. extra keywords, perhaps also dependant on the request url.
@param the options already. MUST be copied before being altered :param opts: MUST be copied before being altered
@return the updated options. :returns: the updated options.
""" """
return opts return opts

View File

@ -74,8 +74,8 @@ import threading
from inspect import currentframe from inspect import currentframe
import re import re
re_from = re.compile('.* from "?([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]+)"? .*$'); re_into = re.compile('.* into "?([a-zA-Z_0-9]+)"? .*$')
sql_counter = 0 sql_counter = 0
@ -226,11 +226,11 @@ class Cursor(object):
params = params or None params = params or None
res = self._obj.execute(query, params) res = self._obj.execute(query, params)
except psycopg2.ProgrammingError, pe: 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) _logger.error("Programming error: %s, in query %s", pe, query)
raise raise
except Exception: 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) _logger.exception("bad query: %s", self._obj.query or query)
raise raise
@ -357,11 +357,6 @@ class Cursor(object):
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self._obj, 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): class PsycoConnection(psycopg2.extensions.connection):
pass pass
@ -521,8 +516,8 @@ def db_connect(db_name):
return Connection(_Pool, db_name) return Connection(_Pool, db_name)
def close_db(db_name): def close_db(db_name):
global _Pool
""" You might want to call openerp.modules.registry.RegistryManager.delete(db_name) along this function.""" """ You might want to call openerp.modules.registry.RegistryManager.delete(db_name) along this function."""
global _Pool
if _Pool: if _Pool:
_Pool.close_all(dsn(db_name)) _Pool.close_all(dsn(db_name))
ct = currentThread() 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. 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, \ from . import test_expression, test_mail, test_ir_sequence, test_orm, \
test_fields, test_basecase, \ test_fields, test_basecase, \
test_view_validation, test_uninstall, test_misc, test_db_cursor, \ test_view_validation, test_uninstall, test_misc, test_db_cursor, \
@ -20,6 +21,7 @@ fast_suite = [
] ]
checks = [ checks = [
test_acl,
test_expression, test_expression,
test_mail, test_mail,
test_db_cursor, test_db_cursor,

View File

@ -1,6 +1,9 @@
import unittest2 import unittest2
from lxml import etree from lxml import etree
import openerp
from openerp.tools.misc import mute_logger
import common import common
# test group that demo user should not have # 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.tech_group.write({'users': [(3, self.demo_uid)]})
self.res_currency._columns['rate'].groups = False self.res_currency._columns['rate'].groups = False
@mute_logger('openerp.osv.orm')
def test_field_crud_restriction(self): def test_field_crud_restriction(self):
"Read/Write RPC access to restricted field should be forbidden" "Read/Write RPC access to restricted field should be forbidden"
# Verify the test environment first # Verify the test environment first
@ -65,12 +69,10 @@ class TestACL(common.TransactionCase):
# Now restrict access to the field and check it's forbidden # Now restrict access to the field and check it's forbidden
self.res_partner._columns['bank_ids'].groups = GROUP_TECHNICAL_FEATURES self.res_partner._columns['bank_ids'].groups = GROUP_TECHNICAL_FEATURES
# FIXME TODO: enable next tests when access rights checks per field are implemented with self.assertRaises(openerp.osv.orm.except_orm):
# from openerp.osv.orm import except_orm self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids'])
# with self.assertRaises(except_orm): with self.assertRaises(openerp.osv.orm.except_orm):
# self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids']) self.res_partner.write(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': []})
# Add the restricted group, and check that it works again # Add the restricted group, and check that it works again
self.tech_group.write({'users': [(4, self.demo_uid)]}) self.tech_group.write({'users': [(4, self.demo_uid)]})
@ -86,4 +88,4 @@ class TestACL(common.TransactionCase):
if __name__ == '__main__': if __name__ == '__main__':
unittest2.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): def test_1_single_related(self):
""" test a related field with a single indirection like fields.related('foo') """ """ test a related field with a single indirection like fields.related('foo') """
# add a related field test_related_company_id on res.partner # 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_columns = self.partner._columns
old_all_columns = self.partner._all_columns
self.partner._columns = dict(old_columns) self.partner._columns = dict(old_columns)
self.partner._all_columns = dict(old_all_columns)
self.partner._columns.update({ self.partner._columns.update({
'single_related_company_id': fields.related('company_id', type='many2one', obj='res.company'), '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') self.do_test_company_field('single_related_company_id')
# restore res.partner fields # restore res.partner fields
self.partner._columns = old_columns self.partner._columns = old_columns
self.partner._all_columns = old_all_columns
def test_2_related_related(self): def test_2_related_related(self):
""" test a related field referring to a related field """ """ test a related field referring to a related field """
# add a related field on a related field on res.partner # 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_columns = self.partner._columns
old_all_columns = self.partner._all_columns
self.partner._columns = dict(old_columns) self.partner._columns = dict(old_columns)
self.partner._all_columns = dict(old_all_columns)
self.partner._columns.update({ self.partner._columns.update({
'single_related_company_id': fields.related('company_id', type='many2one', obj='res.company'), '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'), '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') self.do_test_company_field('related_related_company_id')
# restore res.partner fields # restore res.partner fields
self.partner._columns = old_columns self.partner._columns = old_columns
self.partner._all_columns = old_all_columns
def test_3_read_write(self): def test_3_read_write(self):
""" write on a related field """ """ write on a related field """

View File

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

View File

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

View File

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

View File

@ -352,7 +352,7 @@ class configmanager(object):
# Check if the config file exists (-c used, but not -s) # 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), 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, "\ "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 # place/search the config file on Win32 near the server installation
# (../etc from the server) # (../etc from the server)

View File

@ -662,7 +662,7 @@ form: module.record_id""" % (xml_id,)
if rec.get('action') and pid: if rec.get('action') and pid:
action = "ir.actions.%s,%d" % (a_type, a_id) 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) 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): def _assert_equals(self, f1, f2, prec=4):
return not round(f1 - f2, prec) return not round(f1 - f2, prec)

View File

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

View File

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

View File

@ -23,7 +23,7 @@ import io
import StringIO import StringIO
from PIL import Image from PIL import Image
from PIL import ImageEnhance from PIL import ImageEnhance, ImageOps
from random import random from random import random
# ---------------------------------------- # ----------------------------------------
@ -64,7 +64,6 @@ def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', file
return False return False
if size == (None, None): if size == (None, None):
return base64_source return base64_source
image_stream = io.BytesIO(base64_source.decode(encoding)) image_stream = io.BytesIO(base64_source.decode(encoding))
image = Image.open(image_stream) 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 # 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]: if avoid_if_small and image.size[0] <= size[0] and image.size[1] <= size[1]:
return base64_source return base64_source
# create a thumbnail: will resize and keep ratios, then sharpen for better looking result
image.thumbnail(size, Image.ANTIALIAS) if image.size <> size:
sharpener = ImageEnhance.Sharpness(image.convert('RGBA')) # If you need faster thumbnails you may use use Image.NEAREST
image = sharpener.enhance(2.0) image = ImageOps.fit(image, size, Image.ANTIALIAS)
# 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
background_stream = StringIO.StringIO() background_stream = StringIO.StringIO()
background.save(background_stream, filetype) image.save(background_stream, filetype)
return background_stream.getvalue().encode(encoding) return background_stream.getvalue().encode(encoding)
def image_resize_image_big(base64_source, size=(1204, 1204), encoding='base64', filetype='PNG', avoid_if_small=True): 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_dict[small_name] = image_resize_image_small(base64_source, avoid_if_small=avoid_resize_small)
return return_dict 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() @synchronized()
def __iter__(self): def __iter__(self):
cur = self.first cur = self.first
while cur != None: while cur is not None:
cur2 = cur.next cur2 = cur.next
yield cur.me[1] yield cur.me[1]
cur = cur2 cur = cur2
@ -89,7 +89,7 @@ class LRU(object):
@synchronized() @synchronized()
def iteritems(self): def iteritems(self):
cur = self.first cur = self.first
while cur != None: while cur is not None:
cur2 = cur.next cur2 = cur.next
yield cur.me yield cur.me
cur = cur2 cur = cur2

View File

@ -92,7 +92,7 @@ def exec_pg_command_pipe(name, *args):
pop = subprocess.Popen((prog,) + args, bufsize= -1, pop = subprocess.Popen((prog,) + args, bufsize= -1,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
close_fds=(os.name=="posix")) close_fds=(os.name=="posix"))
return (pop.stdin, pop.stdout) return pop.stdin, pop.stdout
def exec_command_pipe(name, *args): def exec_command_pipe(name, *args):
prog = find_in_path(name) prog = find_in_path(name)
@ -103,7 +103,7 @@ def exec_command_pipe(name, *args):
pop = subprocess.Popen((prog,) + args, bufsize= -1, pop = subprocess.Popen((prog,) + args, bufsize= -1,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
close_fds=(os.name=="posix")) close_fds=(os.name=="posix"))
return (pop.stdin, pop.stdout) return pop.stdin, pop.stdout
#---------------------------------------------------------- #----------------------------------------------------------
# File paths # File paths
@ -181,7 +181,7 @@ def _fileopen(path, mode, basedir, pathinfo, basename=None):
if os.path.isfile(name): if os.path.isfile(name):
fo = open(name, mode) fo = open(name, mode)
if pathinfo: if pathinfo:
return (fo, name) return fo, name
return fo return fo
# Support for loading modules in zipped form. # Support for loading modules in zipped form.
@ -208,7 +208,7 @@ def _fileopen(path, mode, basedir, pathinfo, basename=None):
os.sep, '/'))) os.sep, '/')))
fo.seek(0) fo.seek(0)
if pathinfo: if pathinfo:
return (fo, name) return fo, name
return fo return fo
except Exception: except Exception:
pass pass
@ -561,8 +561,8 @@ def human_size(sz):
sz=len(sz) sz=len(sz)
s, i = float(sz), 0 s, i = float(sz), 0
while s >= 1024 and i < len(units)-1: while s >= 1024 and i < len(units)-1:
s = s / 1024 s /= 1024
i = i + 1 i += 1
return "%0.2f %s" % (s, units[i]) return "%0.2f %s" % (s, units[i])
def logged(f): 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. @return the standard name of the current win32 timezone, or False if it cannot be found.
""" """
res = False res = False
if (sys.platform == "win32"): if sys.platform == "win32":
try: try:
import _winreg import _winreg
hklm = _winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE) hklm = _winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE)
@ -756,7 +756,7 @@ def detect_server_timezone():
(time.tzname[0], 'time.tzname'), (time.tzname[0], 'time.tzname'),
(os.environ.get('TZ',False),'TZ environment variable'), ] (os.environ.get('TZ',False),'TZ environment variable'), ]
# Option 4: OS-specific: /etc/timezone on Unix # Option 4: OS-specific: /etc/timezone on Unix
if (os.path.exists("/etc/timezone")): if os.path.exists("/etc/timezone"):
tz_value = False tz_value = False
try: try:
f = open("/etc/timezone") f = open("/etc/timezone")
@ -767,7 +767,7 @@ def detect_server_timezone():
f.close() f.close()
sources.append((tz_value,"/etc/timezone file")) sources.append((tz_value,"/etc/timezone file"))
# Option 5: timezone info from registry on Win32 # Option 5: timezone info from registry on Win32
if (sys.platform == "win32"): if sys.platform == "win32":
# Timezone info is stored in windows registry. # Timezone info is stored in windows registry.
# However this is not likely to work very well as the standard name # 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. # 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 from os.path import join as opj
def listdir(dir, recursive=False): def listdir(dir, recursive=False):
"""Allow to recursively get the file listing""" """Allow to recursively get the file listing"""
dir = os.path.normpath(dir) dir = os.path.normpath(dir)
if not recursive: if not recursive:
return os.listdir(dir) return os.listdir(dir)
res = [] res = []
for root, dirs, files in walksymlinks(dir): for root, dirs, files in walksymlinks(dir):
root = root[len(dir)+1:] root = root[len(dir)+1:]
res.extend([opj(root, f) for f in files]) res.extend([opj(root, f) for f in files])
return res return res
def walksymlinks(top, topdown=True, onerror=None): def walksymlinks(top, topdown=True, onerror=None):
""" """
@ -58,7 +58,7 @@ def walksymlinks(top, topdown=True, onerror=None):
if __name__ == '__main__': if __name__ == '__main__':
from pprint import pprint as pp from pprint import pprint as pp
pp(listdir('../report', True)) pp(listdir('../report', True))
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -93,7 +93,6 @@ _LOCALE2WIN32 = {
'lt_LT': 'Lithuanian_Lithuania', 'lt_LT': 'Lithuanian_Lithuania',
'lat': 'Latvian_Latvia', 'lat': 'Latvian_Latvia',
'ml_IN': 'Malayalam_India', 'ml_IN': 'Malayalam_India',
'id_ID': 'Indonesian_indonesia',
'mi_NZ': 'Maori', 'mi_NZ': 'Maori',
'mn': 'Cyrillic_Mongolian', 'mn': 'Cyrillic_Mongolian',
'no_NO': 'Norwegian_Norway', 'no_NO': 'Norwegian_Norway',
@ -103,7 +102,6 @@ _LOCALE2WIN32 = {
'pt_BR': 'Portuguese_Brazil', 'pt_BR': 'Portuguese_Brazil',
'ro_RO': 'Romanian_Romania', 'ro_RO': 'Romanian_Romania',
'ru_RU': 'Russian_Russia', 'ru_RU': 'Russian_Russia',
'mi_NZ': 'Maori',
'sr_CS': 'Serbian (Cyrillic)_Serbia and Montenegro', 'sr_CS': 'Serbian (Cyrillic)_Serbia and Montenegro',
'sk_SK': 'Slovak_Slovakia', 'sk_SK': 'Slovak_Slovakia',
'sl_SI': 'Slovenian_Slovenia', 'sl_SI': 'Slovenian_Slovenia',
@ -131,7 +129,6 @@ _LOCALE2WIN32 = {
'sv_SE': 'Swedish_Sweden', 'sv_SE': 'Swedish_Sweden',
'ta_IN': 'English_Australia', 'ta_IN': 'English_Australia',
'th_TH': 'Thai_Thailand', 'th_TH': 'Thai_Thailand',
'mi_NZ': 'Maori',
'tr_TR': 'Turkish_Turkey', 'tr_TR': 'Turkish_Turkey',
'uk_UA': 'Ukrainian_Ukraine', 'uk_UA': 'Ukrainian_Ukraine',
'vi_VN': 'Vietnamese_Viet Nam', 'vi_VN': 'Vietnamese_Viet Nam',
@ -275,7 +272,7 @@ class TinyPoFile(object):
def __iter__(self): def __iter__(self):
self.buffer.seek(0) self.buffer.seek(0)
self.lines = self._get_lines() self.lines = self._get_lines()
self.lines_count = len(self.lines); self.lines_count = len(self.lines)
self.first = True self.first = True
self.extra_lines= [] self.extra_lines= []
@ -291,7 +288,7 @@ class TinyPoFile(object):
return lines return lines
def cur_line(self): def cur_line(self):
return (self.lines_count - len(self.lines)) return self.lines_count - len(self.lines)
def next(self): def next(self):
trans_type = name = res_id = source = trad = None trans_type = name = res_id = source = trad = None
@ -304,7 +301,7 @@ class TinyPoFile(object):
targets = [] targets = []
line = None line = None
fuzzy = False fuzzy = False
while (not line): while not line:
if 0 == len(self.lines): if 0 == len(self.lines):
raise StopIteration() raise StopIteration()
line = self.lines.pop(0).strip() line = self.lines.pop(0).strip()
@ -864,7 +861,7 @@ def trans_generate(lang, modules, cr):
frelativepath = fabsolutepath[len(path):] frelativepath = fabsolutepath[len(path):]
display_path = "addons%s" % frelativepath display_path = "addons%s" % frelativepath
module = get_module_from_path(fabsolutepath, mod_paths=mod_paths) 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 module, fabsolutepath, frelativepath, display_path
return None, None, None, None 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) _state_set(cr, workitem, activity, 'running', ident)
if activity.get('action', False): if activity.get('action', False):
id_new = wkf_expr.execute(cr, ident, workitem, activity) 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'],)) cr.execute('delete from wkf_workitem where id=%s', (workitem['id'],))
return False return False
assert type(id_new)==type(1) or type(id_new)==type(1L), 'Wrong return value: '+str(id_new)+' '+str(type(id_new)) 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, "skip_archive": 1,
"optimize": 2, "optimize": 2,
"dist_dir": 'dist', "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"], "excludes" : ["Tkconstants","Tkinter","tcl"],
} }
} }
@ -106,7 +106,8 @@ setuptools.setup(
'docutils', 'docutils',
'feedparser', 'feedparser',
'gdata', 'gdata',
'lxml < 3', # windows binary http://www.lfd.uci.edu/~gohlke/pythonlibs/ 'Jinja2',
'lxml', # windows binary http://www.lfd.uci.edu/~gohlke/pythonlibs/
'mako', 'mako',
'mock', 'mock',
'PIL', # windows binary http://www.lfd.uci.edu/~gohlke/pythonlibs/ 'PIL', # windows binary http://www.lfd.uci.edu/~gohlke/pythonlibs/