Merge with latest.

bzr revid: tta@openerp.com-20120911102453-f875d277ytnlsama
This commit is contained in:
Tejas Tank
2012-09-11 15:54:53 +05:30
148 changed files with 19967 additions and 2684 deletions
+1
View File
@@ -16,6 +16,7 @@ Depends:
python,
postgresql-client,
python-dateutil,
python-docutils,
python-feedparser,
python-gdata,
python-ldap,
+1 -2
View File
@@ -30,7 +30,6 @@ GNU Public Licence.
(c) 2003-TODAY, Fabien Pinckaers - OpenERP SA
"""
import imp
import logging
import os
import signal
@@ -203,7 +202,7 @@ def quit_on_signals():
try:
while quit_signals_received == 0:
time.sleep(60)
except KeyboardInterrupt, e:
except KeyboardInterrupt:
pass
if config['pidfile']:
+2
View File
@@ -35,6 +35,8 @@ The kernel of OpenERP, needed for all installation.
'depends': [],
'data': [
'base_data.xml',
'currency_data.xml',
'country_data.xml',
'security/base_security.xml',
'base_menu.xml',
'res/res_security.xml',
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -1,10 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="partner_demo" model="res.partner">
<field name="name">Demo User</field>
<field name="company_id" ref="main_company"/>
<field name="customer" eval="False"/>
</record>
<record id="user_demo" model="res.users">
<field name="partner_id" ref="base.partner_demo"/>
<field name="login">demo</field>
<field name="password">demo</field>
<field name="name">Demo User</field>
<field name="signature">Mr Demo</field>
<field name="company_id" ref="main_company"/>
<field name="groups_id" eval="[(6,0,[ref('base.group_user')])]"/>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:47+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:37+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:47+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:47+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:48+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:48+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:48+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:48+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:48+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n"
"X-Generator: Launchpad (build 15901)\n"
"X-Poedit-Language: Czech\n"
#. module: base
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:48+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:49+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -12,8 +12,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:49+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n"
"X-Generator: Launchpad (build 15901)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
"X-Poedit-SourceCharset: utf-8\n"
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:52+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:54+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:54+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n"
"X-Generator: Launchpad (build 15901)\n"
"Language: \n"
#. module: base
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:54+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:49+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:48+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -9,8 +9,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:51+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n"
"X-Generator: Launchpad (build 15901)\n"
"X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n"
"X-Poedit-Language: Persian\n"
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:54+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:49+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:49+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:49+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:49+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:50+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:52+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n"
"X-Generator: Launchpad (build 15901)\n"
"Language: hr\n"
#. module: base
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:50+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:48+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:50+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:50+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:50+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:50+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:49+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:40+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:50+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:50+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:41+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:51+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:51+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:51+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:51+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:51+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+67 -3
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:48+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:39+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
@@ -921,7 +921,7 @@ msgid ""
"The module adds google contact in partner address and add google calendar "
"events details in Meeting"
msgstr ""
"Deze module voegt Google contact[ersonen in relatie adressen en voegt Google "
"Deze module voegt Google contactersonen in relatie adressen en voegt Google "
"agenda items details in OpenERP agenda."
#. module: base
@@ -942,6 +942,15 @@ msgid ""
"delete on objects and can check logs.\n"
" "
msgstr ""
"\n"
"Met deze module heeft de administrator de mogelijkheid om iedere gebruikers "
"handeling op alle objecten in het systeem te volgen.\n"
"============================================================================="
"=======================\n"
"\n"
"De administrator kan regels voor lezen, schrijven en verwijderen definiëren "
"en logs hiervan bekijken\n"
" "
#. module: base
#: model:res.partner.category,name:base.res_partner_category_4
@@ -2482,6 +2491,18 @@ msgid ""
"and categorize your interventions with a channel and a priority level.\n"
" "
msgstr ""
"\n"
"Helpdesk management.\n"
"===================\n"
"\n"
"Net als administratie en verwerking van claims is de Helpdesk en "
"ondersteuning tool, een goed instrument\n"
"om uw acties vast te leggen. Dit menu is meer aangepast aan de mondelinge "
"communicatie,\n"
"die niet noodzakelijkerwijs verband houden met een claim. Selecteer een "
"klant, voeg notities toe\n"
"en deel uw acties in.\n"
" "
#. module: base
#: sql_constraint:ir.ui.view_sc:0
@@ -2542,6 +2563,11 @@ msgid ""
"\n"
"Configure servers and trigger synchronization with its database objects.\n"
msgstr ""
"\n"
"Synchronisatie van objecten.\n"
"=======================\n"
"Configureer servers and trigger database synchronisatie van de database "
"objecten.\n"
#. module: base
#: model:res.country,name:base.mg
@@ -7548,6 +7574,14 @@ msgid ""
"that exceeds minimum amount set by configuration wizard.\n"
" "
msgstr ""
"\n"
"Dubbele controle voor inkopen, welke een minimum bedrag overstijgen.\n"
"==========================================================\n"
"\n"
"Deze module past de inkoop workflow aan, zodat inkopen, welke een \n"
"minimum bedrag overstijgen moeten worden gecontroleerd. Dit kan worden\n"
"ingesteld in de configuratie wizard.\n"
" "
#. module: base
#: field:res.currency,rounding:0
@@ -10556,6 +10590,11 @@ msgid ""
"\n"
"Adds a Claim link to the delivery order.\n"
msgstr ""
"\n"
"Maak een claim van een uitgaande levering.\n"
"===================================\n"
"\n"
"Voegt claim link toe aan een uitgaande order.\n"
#. module: base
#: view:ir.model:0
@@ -11772,6 +11811,13 @@ msgid ""
"the invoicing wizard if the delivery is to be invoiced.\n"
" "
msgstr ""
"\n"
"Factuur wizard bij levering.\n"
"======================\n"
"\n"
"Deze module start de factuur wizard, direct na het verzamelen van een\n"
"inkomende of uitgaande levering en deze levering moet worden gefactureerd.\n"
" "
#. module: base
#: code:addons/orm.py:1388
@@ -13330,6 +13376,13 @@ msgid ""
"marketing_campaign.\n"
" "
msgstr ""
"\n"
"Demo data voor de module marketing_campaign.\n"
"========================================\n"
"\n"
"maakt demo data aan, zoals leads, campagnes en segmenten voor de module "
"marketing_campaign.\n"
" "
#. module: base
#: selection:ir.actions.act_window.view,view_mode:0
@@ -13962,6 +14015,17 @@ msgid ""
"\n"
"Used, for example, in food industries."
msgstr ""
"\n"
"Traceer verschillende datums van producten and productie partijen.\n"
"=======================================================\n"
"\n"
"de volgende datums kunnen worden getraceerd:\n"
" - THT datum\n"
" - Te gebruiken voor datum\n"
" - verwijder datum\n"
" - waarschuwing datum\n"
"\n"
"Wordt bijvoorbeeld gebruikt in de voedingsmiddelen industrie."
#. module: base
#: field:ir.exports.line,export_id:0
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:54+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:51+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:42+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:51+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:52+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+32 -26
View File
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:44+0000\n"
"PO-Revision-Date: 2012-08-20 15:45+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"PO-Revision-Date: 2012-09-10 14:37+0000\n"
"Last-Translator: Chertykov Denis <chertykov@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:52+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-11 04:50+0000\n"
"X-Generator: Launchpad (build 15924)\n"
#. module: base
#: model:res.country,name:base.sh
@@ -604,7 +604,7 @@ msgstr "Испанский (VE) / Español (VE)"
#. module: base
#: model:ir.module.module,shortdesc:base.module_hr_timesheet_invoice
msgid "Invoice on Timesheets"
msgstr ""
msgstr "Счет по затратам времени"
#. module: base
#: view:base.module.upgrade:0
@@ -1269,7 +1269,7 @@ msgstr "Порт SMTP"
#. module: base
#: model:ir.module.module,shortdesc:base.module_import_sugarcrm
msgid "SugarCRM Import"
msgstr ""
msgstr "Импорт SugarCRM"
#. module: base
#: view:res.lang:0
@@ -1374,7 +1374,7 @@ msgstr "Система управления документами"
#. module: base
#: model:ir.module.module,shortdesc:base.module_crm_claim
msgid "Claims Management"
msgstr ""
msgstr "Управление претензиями"
#. module: base
#: model:ir.ui.menu,name:base.menu_purchase_root
@@ -1749,6 +1749,12 @@ msgid ""
" Apply Different Category for the product.\n"
" "
msgstr ""
"\n"
" Базовый модуль управления ланчами\n"
"\n"
" Отслеживание заказов, движения средств, кассы, продукции.\n"
" Возможность разнесения продукции по категориям.\n"
" "
#. module: base
#: model:res.country,name:base.kg
@@ -1862,7 +1868,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_html_view
msgid "Html View"
msgstr ""
msgstr "Просмотр HTML"
#. module: base
#: field:res.currency,position:0
@@ -2533,7 +2539,7 @@ msgstr "Идеи"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_crm
msgid "Opportunity to Quotation"
msgstr ""
msgstr "Предложение в Запрос цен"
#. module: base
#: model:ir.module.module,description:base.module_sale_analytic_plans
@@ -2767,7 +2773,7 @@ msgstr "Словения"
#. module: base
#: help:res.currency,name:0
msgid "Currency Code (ISO 4217)"
msgstr ""
msgstr "Код валюты (ISO 4217)"
#. module: base
#: model:ir.actions.act_window,name:base.res_log_act_window
@@ -3267,7 +3273,7 @@ msgstr "Режим SMTP-over-SSL недоступен"
#. module: base
#: model:ir.module.module,shortdesc:base.module_survey
msgid "Survey"
msgstr ""
msgstr "Опрос"
#. module: base
#: view:base.language.import:0
@@ -3315,7 +3321,7 @@ msgstr "Уругвай"
#. module: base
#: model:ir.module.module,shortdesc:base.module_fetchmail_crm
msgid "eMail Gateway for Leads"
msgstr ""
msgstr "Шлюз эл.почты для кандидатов"
#. module: base
#: selection:base.language.install,lang:0
@@ -3530,7 +3536,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_report_webkit
msgid "Webkit Report Engine"
msgstr ""
msgstr "Инструмент создания отчетов Webkit"
#. module: base
#: selection:publisher_warranty.contract,state:0
@@ -3557,7 +3563,7 @@ msgstr "Майотта"
#. module: base
#: model:ir.module.module,shortdesc:base.module_crm_todo
msgid "Tasks on CRM"
msgstr ""
msgstr "Задачи по CRM"
#. module: base
#: model:ir.module.category,name:base.module_category_generic_modules_accounting
@@ -3683,12 +3689,12 @@ msgstr "Обнаружена рекурсия."
#. module: base
#: model:ir.module.module,shortdesc:base.module_report_webkit_sample
msgid "Webkit Report Samples"
msgstr ""
msgstr "Примеры отчетов Webkit"
#. module: base
#: model:ir.module.module,shortdesc:base.module_point_of_sale
msgid "Point Of Sale"
msgstr ""
msgstr "Точка продажи"
#. module: base
#: code:addons/base/module/module.py:302
@@ -3812,7 +3818,7 @@ msgstr "Проверка кода Ean"
#. module: base
#: field:res.partner,vat:0
msgid "VAT"
msgstr "ИНН"
msgstr "НДС"
#. module: base
#: field:res.users,new_password:0
@@ -3945,7 +3951,7 @@ msgstr "Поддержка iCal"
#. module: base
#: model:ir.module.module,shortdesc:base.module_fetchmail
msgid "Email Gateway"
msgstr ""
msgstr "Шлюз эл.почты"
#. module: base
#: code:addons/base/ir/ir_mail_server.py:439
@@ -4069,7 +4075,7 @@ msgstr "Португалия"
#. module: base
#: model:ir.module.module,shortdesc:base.module_share
msgid "Share any Document"
msgstr ""
msgstr "Совместный доступ r любым документам"
#. module: base
#: field:ir.module.module,certificate:0
@@ -4407,7 +4413,7 @@ msgstr "Код должен быть уникальным"
#. module: base
#: model:ir.module.module,shortdesc:base.module_hr_expense
msgid "Expenses Management"
msgstr ""
msgstr "Управление расходами"
#. module: base
#: view:workflow.activity:0
@@ -4418,7 +4424,7 @@ msgstr "Входящие переходы"
#. module: base
#: field:ir.values,value_unpickle:0
msgid "Default value or action reference"
msgstr ""
msgstr "Значение по умолчанию или ссылка на действие"
#. module: base
#: model:res.country,name:base.sr
@@ -4558,7 +4564,7 @@ msgstr "Экваториальная Гвинея"
#. module: base
#: model:ir.module.module,shortdesc:base.module_warning
msgid "Warning Messages and Alerts"
msgstr ""
msgstr "Предупреждающие сообщения и оповещения"
#. module: base
#: view:base.module.import:0
@@ -4870,7 +4876,7 @@ msgstr "Договор уже зарегистрирован в системе."
#: model:ir.actions.act_window,name:base.action_res_partner_bank_type_form
#: model:ir.ui.menu,name:base.menu_action_res_partner_bank_typeform
msgid "Bank Account Types"
msgstr ""
msgstr "Типы банковского счета"
#. module: base
#: help:ir.sequence,suffix:0
@@ -4880,7 +4886,7 @@ msgstr "Суффикс записи для нумерации"
#. module: base
#: help:ir.mail_server,smtp_user:0
msgid "Optional username for SMTP authentication"
msgstr ""
msgstr "Необязательное имя пользователя для аутентификации SMTP"
#. module: base
#: model:ir.model,name:base.model_ir_actions_actions
@@ -4935,7 +4941,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_web_chat
msgid "Web Chat"
msgstr ""
msgstr "Веб-чат"
#. module: base
#: field:res.company,rml_footer2:0
@@ -4966,7 +4972,7 @@ msgstr "Права доступа"
#: code:addons/base/ir/ir_model.py:311
#, python-format
msgid "Changing the storing system for field \"%s\" is not allowed."
msgstr ""
msgstr "Изменение системы хранения для поля \"%s\" не допускается."
#. module: base
#: help:res.partner.bank,company_id:0
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:52+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:52+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:47+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:38+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:52+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:43+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:54+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:52+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:54+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:46+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:53+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:44+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+2 -2
View File
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-28 05:54+0000\n"
"X-Generator: Launchpad (build 15864)\n"
"X-Launchpad-Export-Date: 2012-09-05 04:45+0000\n"
"X-Generator: Launchpad (build 15901)\n"
#. module: base
#: model:res.country,name:base.sh
+18 -30
View File
@@ -556,29 +556,6 @@
<menuitem action="ir_action_wizard" id="menu_ir_action_wizard" parent="base.next_id_6"/>
<!-- Needaction mechanism -->
<record model="ir.ui.view" id="view_ir_needaction_users_rel_tree">
<field name="name">ir.needaction_users_rel.tree</field>
<field name="model">ir.needaction_users_rel</field>
<field name="arch" type="xml">
<tree string="Subscription">
<field name="user_id"/>
<field name="res_model"/>
<field name="res_id"/>
</tree>
</field>
</record>
<record id="action_view_needaction_users_rel" model="ir.actions.act_window">
<field name="name">Need action relationships</field>
<field name="res_model">ir.needaction_users_rel</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="menu_needaction_users_rel" name="Need actions" parent="base.menu_users" sequence="20" action="action_view_needaction_users_rel" groups="base.group_no_one"/>
<!-- View -->
<record id="view_view_form" model="ir.ui.view">
<field name="name">ir.ui.view</field>
@@ -599,8 +576,15 @@
<field name="xml_id"/>
</group>
</group>
<field name="arch"/>
</sheet>
<notebook>
<page string="Architecture">
<field name="arch"/>
</page>
<page string="Groups">
<field name="groups_id"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
@@ -1173,6 +1157,7 @@
<filter icon="terp-gdu-smart-failing"
string="Untranslated"
domain="['|',('value', '=', False),('value','=','')]"/>
<field name="name" operator="="/>
<field name="lang"/>
<field name="src"/>
<field name="value"/>
@@ -1185,6 +1170,9 @@
<field name="model">ir.translation</field>
<field name="arch" type="xml">
<form string="Translations" version="7.0">
<header>
<field name="state" widget="statusbar" nolabel="1"/>
</header>
<sheet>
<group>
<group>
@@ -1210,12 +1198,12 @@
<field name="name">Translations</field>
<field name="model">ir.translation</field>
<field name="arch" type="xml">
<tree string="Translations">
<field name="src"/>
<tree string="Translations" editable="bottom">
<field name="src" readonly="True"/>
<field name="value"/>
<field name="name"/>
<field name="lang"/>
<field name="type"/>
<field name="name" readonly="True"/>
<field name="lang" readonly="True"/>
<field name="type" readonly="True"/>
</tree>
</field>
</record>
+13 -7
View File
@@ -35,6 +35,7 @@ from tools.config import config
from tools.safe_eval import safe_eval as eval
from tools.translate import _
from socket import gethostname
from openerp import SUPERUSER_ID
_logger = logging.getLogger(__name__)
@@ -43,7 +44,7 @@ class actions(osv.osv):
_table = 'ir_actions'
_order = 'name'
_columns = {
'name': fields.char('Action Name', required=True, size=64),
'name': fields.char('Name', size=64, required=True),
'type': fields.char('Action Type', required=True, size=32,readonly=True),
'usage': fields.char('Action Usage', size=32),
}
@@ -271,7 +272,7 @@ class act_window(osv.osv):
:return: A read() view of the ir.actions.act_window
"""
dataobj = self.pool.get('ir.model.data')
data_id = dataobj._get_id (cr, 1, module, xml_id)
data_id = dataobj._get_id (cr, SUPERUSER_ID, module, xml_id)
res_id = dataobj.browse(cr, uid, data_id, context).res_id
return self.read(cr, uid, res_id, [], context)
@@ -860,11 +861,10 @@ class act_client(osv.osv):
_order = 'name'
def _get_params(self, cr, uid, ids, field_name, arg, context):
return dict([
((record.id, ast.literal_eval(record.params_store))
if record.params_store else (record.id, False))
for record in self.browse(cr, uid, ids, context=context)
])
result = {}
for record in self.browse(cr, uid, ids, context=context):
result[record.id] = record.params_store and eval(record.params_store, {'uid': uid}) or False
return result
def _set_params(self, cr, uid, id, field_name, field_value, arg, context):
if isinstance(field_value, dict):
@@ -873,10 +873,15 @@ class act_client(osv.osv):
self.write(cr, uid, id, {'params_store': field_value}, context=context)
_columns = {
'name': fields.char('Action Name', required=True, size=64, translate=True),
'tag': fields.char('Client action tag', size=64, required=True,
help="An arbitrary string, interpreted by the client"
" according to its own needs and wishes. There "
"is no central tag repository across clients."),
'res_model': fields.char('Destination Model', size=64,
help="Optional model, mostly used for needactions."),
'context': fields.char('Context Value', size=250, required=True,
help="Context dictionary as Python expression, empty by default (Default: {})"),
'params': fields.function(_get_params, fnct_inv=_set_params,
type='binary',
string="Supplementary arguments",
@@ -886,6 +891,7 @@ class act_client(osv.osv):
}
_defaults = {
'type': 'ir.actions.client',
'context': '{}',
}
act_client()
@@ -26,6 +26,7 @@ from osv import osv,fields
import uuid
import datetime
from tools import misc, config
from openerp import SUPERUSER_ID
"""
A dictionary holding some configuration parameters to be initialized when the database is created.
@@ -55,9 +56,9 @@ class ir_config_parameter(osv.osv):
Initializes the parameters listed in _default_parameters.
"""
for key, func in _default_parameters.iteritems():
ids = self.search(cr, 1, [('key','=',key)])
ids = self.search(cr, SUPERUSER_ID, [('key','=',key)])
if not ids:
self.set_param(cr, 1, key, func())
self.set_param(cr, SUPERUSER_ID, key, func())
def get_param(self, cr, uid, key, default=False, context=None):
"""Retrieve the value for a given key.
+29 -164
View File
@@ -19,180 +19,45 @@
#
##############################################################################
import openerp.pooler as pooler
from operator import itemgetter
from osv import osv, fields
from tools.translate import _
from osv import osv
class ir_needaction_users_rel(osv.Model):
''' ir_needaction_users_rel holds data related to the needaction
mechanism inside OpenERP. A row in this model is characterized
by:
- res_model: model of the record requiring an action
- res_id: ID of the record requiring an action
- user_id: foreign key to the res.users table, to the user that has to
perform the action
This model can be seen as a many2many, linking (res_model, res_id) to users
(those whose attention is required on the record). '''
_name = 'ir.needaction_users_rel'
_description = 'Needaction relationship table'
_rec_name = 'id'
_order = 'id desc'
_columns = {
'res_model': fields.char('Related Document Model', size=128,
select=1, required=True),
'res_id': fields.integer('Related Document ID',
select=1, required=True),
'user_id': fields.many2one('res.users', string='Related User',
ondelete='cascade', select=1, required=True),
}
def _get_users(self, cr, uid, res_ids, res_model, context=None):
"""Given res_ids of res_model, get user_ids present in table"""
rel_ids = self.search(cr, uid, [('res_model', '=', res_model), ('res_id', 'in', res_ids)], context=context)
return list(set(map(itemgetter('user_id'), self.read(cr, uid, rel_ids, ['user_id'], context=context))))
def create_users(self, cr, uid, res_ids, res_model, user_ids, context=None):
"""Given res_ids of res_model, add user_ids to the relationship table"""
for res_id in res_ids:
for user_id in user_ids:
self.create(cr, uid, {'res_model': res_model, 'res_id': res_id, 'user_id': user_id}, context=context)
return True
def unlink_users(self, cr, uid, res_ids, res_model, context=None):
"""Given res_ids of res_model, delete all entries in the relationship table"""
to_del_ids = self.search(cr, uid, [('res_model', '=', res_model), ('res_id', 'in', res_ids)], context=context)
return self.unlink(cr, uid, to_del_ids, context=context)
def update_users(self, cr, uid, res_ids, res_model, user_ids, context=None):
"""Given res_ids of res_model, update their entries in the relationship table to user_ids"""
# read current records
cur_users = self._get_users(cr, uid, res_ids, res_model, context=context)
if len(cur_users) == len(user_ids) and all(cur_user in user_ids for cur_user in cur_users):
return True
# unlink old records
self.unlink_users(cr, uid, res_ids, res_model, context=context)
# link new records
self.create_users(cr, uid, res_ids, res_model, user_ids, context=context)
return True
class ir_needaction_mixin(osv.Model):
class ir_needaction_mixin(osv.AbstractModel):
'''Mixin class for objects using the need action feature.
Need action feature can be used by objects having to be able to
signal that an action is required on a particular record. If in
the business logic an action must be performed by somebody, for
instance validation by a manager, this mechanism allows to set a
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
the business logic an action must be performed by somebody, for
instance validation by a manager, this mechanism allows to set a
list of users asked to perform an action.
This class wraps a class (ir.ir_needaction_users_rel) that
behaves like a many2many field. This class handles the low-level
considerations of updating relationships. Every change made on
the record calls a method that updates the relationships.
Objects using the 'need_action' feature should override the
``get_needaction_user_ids`` method. This methods returns a
dictionary whose keys are record ids, and values a list of user
ids, like in a many2many relationship. Therefore by defining
only one method, you can specify if an action is required by
defining the users that have to do it, in every possible
situation.
This class also offers several global services:
- ``needaction_get_record_ids``: for the current model and uid, get
all record ids that ask this user to perform an action. This
mechanism is used for instance to display the number of pending
actions in menus, such as Leads (12)
- ``needaction_get_action_count``: as ``needaction_get_record_ids``
but returns only the number of action, not the ids (performs a
search with count=True)
The ``ir_needaction_mixin`` class adds a calculated field
``needaction_pending``. This function field allows to state
whether a given record has a needaction for the current user.
This is usefull if you want to customize views according to the
needaction feature. For example, you may want to set records in
bold in a list view if the current user has an action to perform
on the record. '''
Models using the 'need_action' feature should override the
``_needaction_domain_get`` method. This method returns a
domain to filter records requiring an action for a specific user.
This class also offers several global services:
- ``_needaction_count``: returns the number of actions uid has to perform
'''
_name = 'ir.needaction_mixin'
_description = 'Need action mixin'
def get_needaction_pending(self, cr, uid, ids, name, arg, context=None):
res = {}
needaction_user_ids = self.get_needaction_user_ids(cr, uid, ids, context=context)
for id in ids:
res[id] = uid in needaction_user_ids[id]
return res
_needaction = True
def search_needaction_pending(self, cr, uid, self_again, field_name, criterion, context=None):
ids = self.needaction_get_record_ids(
cr, uid, uid, limit=1024, context=context)
return [('id', 'in', ids)]
_columns = {
'needaction_pending': fields.function(
get_needaction_pending, type='boolean',
fnct_search=search_needaction_pending,
string='Need action pending',
help="If True, this field states that users have to perform an " \
"action This field comes from the ir.needaction_mixin class."),
}
#------------------------------------------------------
# Addon API
# Addons API
#------------------------------------------------------
def get_needaction_user_ids(self, cr, uid, ids, context=None):
""" Returns the user_ids that have to perform an action
:return: dict { record_id: [user_ids], }
def _needaction_domain_get(self, cr, uid, context=None):
""" Returns the domain to filter records that require an action
:return: domain or False is no action
"""
return dict((id,list()) for id in ids)
def create(self, cr, uid, values, context=None):
rel_obj = self.pool.get('ir.needaction_users_rel')
# perform create
obj_id = super(ir_needaction_mixin, self).create(cr, uid, values, context=context)
# link user_ids
needaction_user_ids = self.get_needaction_user_ids(cr, uid, [obj_id], context=context)
rel_obj.create_users(cr, uid, [obj_id], self._name, needaction_user_ids[obj_id], context=context)
return obj_id
def write(self, cr, uid, ids, values, context=None):
rel_obj = self.pool.get('ir.needaction_users_rel')
# perform write
write_res = super(ir_needaction_mixin, self).write(cr, uid, ids, values, context=context)
# get and update user_ids
needaction_user_ids = self.get_needaction_user_ids(cr, uid, ids, context=context)
for id in ids:
rel_obj.update_users(cr, uid, [id], self._name, needaction_user_ids[id], context=context)
return write_res
def unlink(self, cr, uid, ids, context=None):
# unlink user_ids
rel_obj = self.pool.get('ir.needaction_users_rel')
rel_obj.unlink_users(cr, uid, ids, self._name, context=context)
# perform unlink
return super(ir_needaction_mixin, self).unlink(cr, uid, ids, context=context)
return False
#------------------------------------------------------
# "Need action" API
#------------------------------------------------------
def needaction_get_record_ids(self, cr, uid, user_id, limit=80, context=None):
"""Given the current model and a user_id
return the record ids that require the user to perform an
action"""
rel_obj = self.pool.get('ir.needaction_users_rel')
rel_ids = rel_obj.search(cr, uid, [('res_model', '=', self._name), ('user_id', '=', user_id)], limit=limit, context=context)
return map(itemgetter('res_id'), rel_obj.read(cr, uid, rel_ids, ['res_id'], context=context))
def needaction_get_action_count(self, cr, uid, user_id, limit=80, context=None):
"""Given the current model and a user_id
get the number of actions it has to perform"""
rel_obj = self.pool.get('ir.needaction_users_rel')
return rel_obj.search(cr, uid, [('res_model', '=', self._name), ('user_id', '=', user_id)], limit=limit, count=True, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
def _needaction_count(self, cr, uid, domain=[], context=None):
""" Get the number of actions uid has to perform. """
dom = self._needaction_domain_get(cr, uid, context=context)
if not dom:
return 0
return self.search(cr, uid, (domain or []) +dom, context=context, count=True)
+2 -2
View File
@@ -44,7 +44,7 @@ class ir_rule(osv.osv):
def _eval_context(self, cr, uid):
"""Returns a dictionary to use as evaluation context for
ir.rule domains."""
return {'user': self.pool.get('res.users').browse(cr, 1, uid),
return {'user': self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid),
'time':time}
def _domain_force_get(self, cr, uid, ids, field_name, arg, context=None):
@@ -152,7 +152,7 @@ class ir_rule(osv.osv):
# involve objects on which the real uid has no acces rights.
# This means also there is no implicit restriction (e.g. an object
# references another object the user can't see).
query = self.pool.get(model_name)._where_calc(cr, 1, dom, active_test=False)
query = self.pool.get(model_name)._where_calc(cr, SUPERUSER_ID, dom, active_test=False)
return query.where_clause, query.where_clause_params, query.tables
return [], [], ['"'+self.pool.get(model_name)._table+'"']
+2 -2
View File
@@ -210,7 +210,7 @@ class ir_sequence(openerp.osv.osv.osv):
def next_by_id(self, cr, uid, sequence_id, context=None):
""" Draw an interpolated string using the specified sequence."""
self.check_read(cr, uid)
self.check_access_rights(cr, uid, 'read')
company_ids = self.pool.get('res.company').search(cr, uid, [], order='company_id', context=context) + [False]
ids = self.search(cr, uid, ['&',('id','=', sequence_id),('company_id','in',company_ids)])
return self._next(cr, uid, ids, context)
@@ -227,7 +227,7 @@ class ir_sequence(openerp.osv.osv.osv):
sequence selection. A matching sequence for that
specific company will get higher priority.
"""
self.check_read(cr, uid)
self.check_access_rights(cr, uid, 'read')
company_ids = self.pool.get('res.company').search(cr, uid, [], order='company_id', context=context) + [False]
ids = self.search(cr, uid, ['&',('code','=', sequence_code),('company_id','in',company_ids)])
return self._next(cr, uid, ids, context)
+63 -7
View File
@@ -77,14 +77,14 @@ class ir_translation_import_cursor(object):
def push(self, ddict):
"""Feed a translation, as a dictionary, into the cursor
"""
state = "translated" if (ddict['value'] and ddict['value'] != "") else "to_translate"
self._cr.execute("INSERT INTO " + self._table_name \
+ """(name, lang, res_id, src, type,
imd_model, imd_module, imd_name, value)
VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)""",
imd_model, imd_module, imd_name, value,state)
VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
(ddict['name'], ddict['lang'], ddict.get('res_id'), ddict['src'], ddict['type'],
ddict.get('imd_model'), ddict.get('imd_module'), ddict.get('imd_name'),
ddict['value']))
ddict['value'],state))
def finish(self):
""" Transfer the data from the temp table to ir.translation
@@ -125,15 +125,16 @@ class ir_translation_import_cursor(object):
# Step 2: update existing (matching) translations
if self._overwrite:
cr.execute("""UPDATE ONLY %s AS irt
SET value = ti.value
SET value = ti.value,
state = 'translated'
FROM %s AS ti
WHERE %s AND ti.value IS NOT NULL AND ti.value != ''
""" % (self._parent_table, self._table_name, find_expr))
# Step 3: insert new translations
cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value)
SELECT name, lang, res_id, src, type, value
cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value,state)
SELECT name, lang, res_id, src, type, value,state
FROM %s AS ti
WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s);
""" % (self._parent_table, self._table_name, self._parent_table, find_expr))
@@ -167,6 +168,11 @@ class ir_translation(osv.osv):
'type': fields.selection(TRANSLATION_TYPE, string='Type', size=16, select=True),
'src': fields.text('Source'),
'value': fields.text('Translation Value'),
'state':fields.selection([('to_translate','To Translate'),('inprogress','Translation in Progress'),('translated','Translated')])
}
_defaults = {
'state':'to_translate',
}
_sql_constraints = [ ('lang_fkey_res_lang', 'FOREIGN KEY(lang) REFERENCES res_lang(code)',
@@ -301,6 +307,10 @@ class ir_translation(osv.osv):
context = {}
if isinstance(ids, (int, long)):
ids = [ids]
if vals.get('src') or ('value' in vals and not(vals.get('value'))):
result = vals.update({'state':'to_translate'})
if vals.get('value'):
result = vals.update({'state':'translated'})
result = super(ir_translation, self).write(cursor, user, ids, vals, context=context)
for trans_obj in self.read(cursor, user, ids, ['name','type','res_id','src','lang'], context=context):
self._get_source.clear_cache(self, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], trans_obj['src'])
@@ -318,6 +328,52 @@ class ir_translation(osv.osv):
result = super(ir_translation, self).unlink(cursor, user, ids, context=context)
return result
def translate_fields(self, cr, uid, model, id, field=None, context=None):
trans_model = self.pool.get(model)
domain = ['&', ('res_id', '=', id), ('name', '=like', model + ',%')]
langs_ids = self.pool.get('res.lang').search(cr, uid, [('code', '!=', 'en_US')], context=context)
langs = [lg.code for lg in self.pool.get('res.lang').browse(cr, uid, langs_ids, context=context)]
main_lang = 'en_US'
translatable_fields = []
for f, info in trans_model._all_columns.items():
if info.column.translate:
if info.parent_model:
parent_id = trans_model.read(cr, uid, [id], [info.parent_column], context=context)[0][info.parent_column][0]
translatable_fields.append({ 'name': f, 'id': parent_id, 'model': info.parent_model })
domain.insert(0, '|')
domain.extend(['&', ('res_id', '=', parent_id), ('name', '=', "%s,%s" % (info.parent_model, f))])
else:
translatable_fields.append({ 'name': f, 'id': id, 'model': model })
if len(langs):
fields = [f.get('name') for f in translatable_fields]
record = trans_model.read(cr, uid, [id], fields, context={ 'lang': main_lang })[0]
for lg in langs:
for f in translatable_fields:
# Check if record exists, else create it (at once)
sql = """INSERT INTO ir_translation (lang, src, name, type, res_id, value)
SELECT %s, %s, %s, 'model', %s, %s WHERE NOT EXISTS
(SELECT 1 FROM ir_translation WHERE lang=%s AND name=%s AND res_id=%s AND type='model');
UPDATE ir_translation SET src = %s WHERE lang=%s AND name=%s AND res_id=%s AND type='model';
"""
src = record[f['name']] or None
name = "%s,%s" % (f['model'], f['name'])
cr.execute(sql, (lg, src , name, f['id'], src, lg, name, f['id'], src, lg, name, id))
action = {
'name': 'Translate',
'res_model': 'ir.translation',
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'tree,form',
'domain': domain,
}
if field:
info = trans_model._all_columns[field]
action['context'] = {
'search_default_name': "%s,%s" % (info.parent_model or model, field)
}
return action
def _get_import_cursor(self, cr, uid, context=None):
""" Return a cursor-like object for fast inserting translations
"""
+17 -15
View File
@@ -23,11 +23,12 @@
import base64
import re
import threading
from tools.safe_eval import safe_eval as eval
import tools
import openerp.modules
from osv import fields, osv
from tools.translate import _
from openerp import SUPERUSER_ID
def one_in(setA, setB):
"""Check the presence of an element of setA in setB
@@ -59,7 +60,7 @@ class ir_ui_menu(osv.osv):
"""
with self.cache_lock:
modelaccess = self.pool.get('ir.model.access')
user_groups = set(self.pool.get('res.users').read(cr, 1, uid, ['groups_id'])['groups_id'])
user_groups = set(self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['groups_id'])['groups_id'])
result = []
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)
@@ -255,23 +256,24 @@ class ir_ui_menu(osv.osv):
return res
def _get_needaction_info(self, cr, uid, id, domain=[], context={}):
return [False, 0]
def _get_needaction(self, cr, uid, ids, field_names, args, context=None):
if context is None:
context = {}
res = {}
for menu in self.browse(cr, uid, ids, context=context):
res[menu.id] = {}
if menu.action and menu.action.type == 'ir.actions.act_window' and menu.action.res_model:
menu_needaction_res = self.pool.get(menu.action.res_model)._get_needaction_info(cr, uid, uid, domain=menu.action.domain, context=context)
else:
menu_needaction_res = [False, 0]
res[menu.id]['needaction_enabled'] = menu_needaction_res[0]
res[menu.id]['needaction_counter'] = menu_needaction_res[1]
res[menu.id] = {
'needaction_enabled': False,
'needaction_counter': False,
}
if menu.action and menu.action.type in ('ir.actions.act_window','ir.actions.client') and menu.action.res_model:
obj = self.pool.get(menu.action.res_model)
if obj._needaction:
if menu.action.type=='ir.actions.act_window':
dom = menu.action.domain and eval(menu.action.domain, {'uid': uid}) or []
else:
dom = eval(menu.action.params_store or '{}', {'uid': uid}).get('domain')
res[menu.id]['needaction_enabled'] = obj._needaction
res[menu.id]['needaction_counter'] = obj._needaction_count(cr, uid, dom, context=context)
return res
_columns = {
'name': fields.char('Menu', size=64, required=True, translate=True),
'sequence': fields.integer('Sequence'),
+10 -3
View File
@@ -78,6 +78,8 @@ class view(osv.osv):
'field_parent': fields.char('Child Field',size=64),
'xml_id': fields.function(osv.osv.get_xml_id, type='char', size=128, string="External ID",
help="ID of the view defined in xml file"),
'groups_id': fields.many2many('res.groups', 'ir_ui_view_group_rel', 'view_id', 'group_id',
string='Groups', help="If this field is empty, the view applies to all users. Otherwise, the view applies to the users of those groups only."),
}
_defaults = {
'arch': '<?xml version="1.0"?>\n<tree string="My view">\n\t<field name="name"/>\n</tree>',
@@ -167,20 +169,25 @@ class view(osv.osv):
:rtype: list of tuples
:return: [(view_arch,view_id), ...]
"""
user_groups = frozenset(self.pool.get('res.users').browse(cr, 1, uid, context).groups_id)
if self.pool._init:
# Module init currently in progress, only consider views from modules whose code was already loaded
query = """SELECT v.arch, v.id FROM ir_ui_view v LEFT JOIN ir_model_data md ON (md.model = 'ir.ui.view' AND md.res_id = v.id)
query = """SELECT v.id FROM ir_ui_view v LEFT JOIN ir_model_data md ON (md.model = 'ir.ui.view' AND md.res_id = v.id)
WHERE v.inherit_id=%s AND v.model=%s AND md.module in %s
ORDER BY priority"""
query_params = (view_id, model, tuple(self.pool._init_modules))
else:
# Modules fully loaded, consider all views
query = """SELECT v.arch, v.id FROM ir_ui_view v
query = """SELECT v.id FROM ir_ui_view v
WHERE v.inherit_id=%s AND v.model=%s
ORDER BY priority"""
query_params = (view_id, model)
cr.execute(query, query_params)
return cr.fetchall()
view_ids = [v[0] for v in cr.fetchall()]
# filter views based on user groups
return [(view.arch, view.id)
for view in self.browse(cr, 1, view_ids, context)
if not (view.groups_id and user_groups.isdisjoint(view.groups_id))]
def write(self, cr, uid, ids, vals, context=None):
if not isinstance(ids, (list, tuple)):
@@ -10,7 +10,9 @@
<field name="lang"/>
</group>
<footer>
<button name="act_cancel" special="cancel" string="Cancel" type="object"/>
<button name="act_update" string="Update" type="object" class="oe_highlight"/>
or
<button name="act_cancel" special="cancel" string="Cancel" type="object" class="oe_link"/>
</footer>
</form>
</field>
@@ -2,8 +2,7 @@
<corporate-header>
<corporation type="zoom" name="company_id">
<rml_header1 type="field" name="rml_header1"/>
<rml_footer1 type="field" name="rml_footer1"/>
<rml_footer2 type="field" name="rml_footer2"/>
<rml_footer type="field" name="rml_footer"/>
<title type="field" name="partner_id.title"/>
<name type="field" name="partner_id.name"/>
<street type="field" name="street"/>
@@ -39,8 +39,7 @@
<!--page bottom-->
<lines>1.5cm 2.2cm 19.9cm 2.2cm</lines>
<drawCentredString x="10.5cm" y="1.7cm"><xsl:value-of select="//corporate-header/corporation/rml_footer1"/></drawCentredString>
<drawCentredString x="10.5cm" y="1.25cm"><xsl:value-of select="//corporate-header/corporation/rml_footer2"/></drawCentredString>
<drawCentredString x="10.5cm" y="1.7cm"><xsl:value-of select="//corporate-header/corporation/rml_footer"/></drawCentredString>
<drawCentredString x="10.5cm" y="0.8cm">Your contact : <xsl:value-of select="//corporate-header/user/name"/></drawCentredString>
</xsl:template>
@@ -73,8 +72,7 @@
<!--page bottom-->
<lines>1.5cm 1.2cm 19.9cm 1.2cm</lines>
<drawCentredString x="10.5cm" y="1.7cm"><xsl:value-of select="//corporate-header/corporation/rml_footer1"/></drawCentredString>
<drawCentredString x="10.5cm" y="1.25cm"><xsl:value-of select="//corporate-header/corporation/rml_footer2"/></drawCentredString>
<drawCentredString x="10.5cm" y="1.7cm"><xsl:value-of select="//corporate-header/corporation/rml_footer"/></drawCentredString>
<!-- <drawCentredString x="10.5cm" y="0.8cm">Your contact : <xsl:value-of select="//corporate-header/user/name"/></drawCentredString>-->
</xsl:template>
@@ -233,8 +233,7 @@
<table:table-column table:style-name="Table1.A"/>
<table:table-row>
<table:table-cell table:style-name="Table1.A1" table:value-type="string">
<text:p text:style-name="P7">[[ company.rml_footer1 ]]</text:p>
<text:p text:style-name="P7">[[ company.rml_footer2 ]]</text:p>
<text:p text:style-name="P7">[[ company.rml_footer ]]</text:p>
<text:p text:style-name="P7">Contact : [[ user.name ]]</text:p>
</table:table-cell>
</table:table-row>
+2 -9
View File
@@ -7,15 +7,8 @@
</tr>
<tr>
<td>
% if company['rml_footer1']:
<p align = "center"><small><b>${company.rml_footer1}</b></small></br></p>
%endif
</td>
</tr>
<tr>
<td>
% if company['rml_footer2']:
<p align = "center"><small><b>${company.rml_footer2}</b></small></br></p>
% if company['rml_footer']:
<p align="center"><small><b>${company.rml_footer}</b></small></p>
%endif
</td>
</tr>
+1 -1
View File
@@ -109,7 +109,7 @@ class res_partner_bank(osv.osv):
if not context.get('address'):
return value
for address in self.pool.get('res.partner').resolve_o2m_commands_to_record_dicts(
for address in self.pool.get('res.partner').resolve_2many_commands(
cursor, user, 'address', context['address'], ['type', field], context=context):
if address.get('type') == 'default':
+4 -3
View File
@@ -91,8 +91,9 @@
<group col="4">
<field name="state"/>
<field name="acc_number"/>
<field name="company_id" on_change="onchange_company_id(company_id)" invisible="context.get('company_hide', True)" widget="selection"/>
<field name="footer" attrs="{'invisible': [('company_id','=',False)]}"/>
<field name="company_id" on_change="onchange_company_id(company_id)"
invisible="context.get('company_hide', True)" widget="selection"/>
<field name="footer" invisible="context.get('footer_hide', True)"/>
</group>
<group>
<group name="owner" string="Bank Account Owner">
@@ -128,7 +129,7 @@
<field name="acc_number"/>
<field name="bank_name"/>
<field name="company_id" invisible="context.get('company_hide', True)"/>
<field name="footer" invisible="context.get('company_hide', True)"/>
<field name="footer" invisible="context.get('footer_hide', True)"/>
<field name="partner_id"/>
</tree>
</field>
+72 -31
View File
@@ -24,6 +24,7 @@ from osv import fields
import os
import tools
import openerp
from openerp import SUPERUSER_ID
from tools.translate import _
from tools.safe_eval import safe_eval as eval
@@ -88,7 +89,6 @@ class res_company(osv.osv):
result[company.id][field] = address[field] or False
return result
def _set_address_data(self, cr, uid, company_id, name, value, arg, context=None):
""" Write the 'address' functional fields. """
company = self.browse(cr, uid, company_id, context=context)
@@ -102,18 +102,18 @@ class res_company(osv.osv):
part_obj.create(cr, uid, {name: value or False, 'parent_id': company.partner_id.id}, context=context)
return True
_columns = {
'name': fields.related('partner_id', 'name', string='Company Name', size=128, required=True, store=True, type='char'),
'parent_id': fields.many2one('res.company', 'Parent Company', select=True),
'child_ids': fields.one2many('res.company', 'parent_id', 'Child Companies'),
'partner_id': fields.many2one('res.partner', 'Partner', required=True),
'rml_header1': fields.char('Company Slogan', size=200, help="Appears by default on the top right corner of your printed documents (report header)."),
'rml_footer1': fields.char('General Information Footer', size=200),
'rml_footer2': fields.char('Bank Accounts Footer', size=250, help="Write here your bank accounts for customer payments."),
'rml_header': fields.text('RML Header', required=True),
'rml_header1': fields.char('Company Slogan', size=200, help="Appears by default on the top right corner of your printed documents (report header)."),
'rml_header2': fields.text('RML Internal Header', required=True),
'rml_header3': fields.text('RML Internal Header for Landscape Reports', required=True),
'rml_footer': fields.text('Report Footer', help="Footer text displayed at the bottom of all reports. Automatically set based on company details, "\
"but may also be customized by directly editing it."),
'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"),
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
'currency_ids': fields.one2many('res.currency', 'company_id', 'Currency'),
@@ -137,15 +137,43 @@ class res_company(osv.osv):
_sql_constraints = [
('name_uniq', 'unique (name)', 'The company name must be unique !')
]
def on_change_header(self, cr, uid, ids, phone, email, fax, website, vat, reg=False, context=None):
val = []
if phone: val.append(_('Phone: ')+phone)
if fax: val.append(_('Fax: ')+fax)
if website: val.append(_('Website: ')+website)
if vat: val.append(_('TIN: ')+vat)
if reg: val.append(_('Reg: ')+reg)
return {'value': {'rml_footer1':' | '.join(val)}}
def onchange_footer(self, cr, uid, ids, context=None):
# when touched, the footer becomes custom
return {'value': {'custom_footer': True}}
def set_auto_footer(self, cr, uid, ids, context=None):
# unset the flag 'custom_footer'; this will automatically compute the footer
return self.write(cr, uid, ids, {'custom_footer': False}, context=context)
def compute_footer(self, cr, uid, ids, context=None):
res_partner_bank = self.pool.get('res.partner.bank')
for company in self.browse(cr, uid, ids, context):
if not company.custom_footer:
# first line (notice that missing elements are filtered out before the join)
res = ' | '.join(filter(bool, [
company.phone and '%s: %s' % (_('Phone'), company.phone),
company.fax and '%s: %s' % (_('Fax'), company.fax),
company.email and '%s: %s' % (_('Email'), company.email),
company.website and '%s: %s' % (_('Website'), company.website),
company.vat and '%s: %s' % (_('TIN'), company.vat),
company.company_registry and '%s: %s' % (_('Reg'), company.company_registry),
]))
# second line: bank accounts
account_ids = [acc.id for acc in company.bank_ids if acc.footer]
account_names = res_partner_bank.name_get(cr, uid, account_ids, context=context)
if account_names:
title = _('Bank Accounts') if len(account_names) > 1 else _('Bank Account')
res += '\n%s: %s' % (title, ', '.join(name for id, name in account_names))
# update footer
self.write(cr, uid, [company.id], {'rml_footer': res}, context=context)
return True
def on_change_country(self, cr, uid, ids, country_id, context=None):
currency_id = self._get_euro(cr, uid, context=context)
if country_id:
currency_id = self.pool.get('res.country').browse(cr, uid, country_id, context=context).currency_id.id
return {'value': {'currency_id': currency_id}}
def _search(self, cr, uid, args, offset=0, limit=None, order=None,
context=None, count=False, access_rights_uid=None):
@@ -156,7 +184,7 @@ class res_company(osv.osv):
# select only the currently visible companies (according to rules,
# which are probably to allow to see the child companies) even if
# she belongs to some other companies.
user = self.pool.get('res.users').browse(cr, 1, uid, context=context)
user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
cmp_ids = list(set([user.company_id.id] + [cmp.id for cmp in user.company_ids]))
return cmp_ids
return super(res_company, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
@@ -220,17 +248,22 @@ class res_company(osv.osv):
self.cache_restart(cr)
company_id = super(res_company, self).create(cr, uid, vals, context=context)
obj_partner.write(cr, uid, partner_id, {'company_id': company_id}, context=context)
self.compute_footer(cr, uid, [company_id], context=context)
return company_id
def write(self, cr, *args, **argv):
def write(self, cr, uid, ids, values, context=None):
self.cache_restart(cr)
return super(res_company, self).write(cr, *args, **argv)
if isinstance(ids, (int, long)):
ids = [ids]
super(res_company, self).write(cr, uid, ids, values, context=context)
if 'rml_footer' not in values:
self.compute_footer(cr, uid, ids, context=context)
return True
def _get_euro(self, cr, uid, context=None):
try:
return self.pool.get('res.currency').search(cr, uid, [])[0]
except:
return False
rate_obj = self.pool.get('res.currency.rate')
rate_id = rate_obj.search(cr, uid, [('rate', '=', 1)], context=context)
return rate_id and rate_obj.browse(cr, uid, rate_id[0], context=context).currency_id.id or False
def _get_logo(self, cr, uid, ids):
return open(os.path.join( tools.config['root_path'], 'addons', 'base', 'res', 'res_company_logo.png'), 'rb') .read().encode('base64')
@@ -267,20 +300,22 @@ class res_company(osv.osv):
return self._header_a4
_header_main = """
<header>
<header>
<pageTemplate>
<frame id="first" x1="1.3cm" y1="2.5cm" height="%s" width="19.0cm"/>
<frame id="first" x1="1.3cm" y1="3.0cm" height="%s" width="19.0cm"/>
<stylesheet>
<paraStyle name="main_footer" fontName="DejaVu Sans" fontSize="8.0" alignment="CENTER"/>
</stylesheet>
<pageGraphics>
<!-- You Logo - Change X,Y,Width and Height -->
<image x="1.3cm" y="%s" height="40.0" >[[ company.logo or removeParentNode('image') ]]</image>
<setFont name="DejaVu Sans" size="8"/>
<fill color="black"/>
<stroke color="black"/>
<!-- page header -->
<lines>1.3cm %s 20cm %s</lines>
<drawRightString x="20cm" y="%s">[[ company.rml_header1 ]]</drawRightString>
<drawString x="1.3cm" y="%s">[[ company.partner_id.name ]]</drawString>
<drawString x="1.3cm" y="%s">[[ company.partner_id.street or '' ]]</drawString>
<drawString x="1.3cm" y="%s">[[ company.partner_id.city or '' ]] - [[ company.partner_id.country_id and company.partner_id.country_id.name or '']]</drawString>
@@ -290,13 +325,19 @@ class res_company(osv.osv):
<drawRightString x="7cm" y="%s">[[ company.partner_id.email or '' ]]</drawRightString>
<lines>1.3cm %s 7cm %s</lines>
<!-- left margin -->
<rotate degrees="90"/>
<fill color="grey"/>
<drawString x="2.65cm" y="-0.4cm">produced by OpenERP.com</drawString>
<fill color="black"/>
<rotate degrees="-90"/>
<!--page bottom-->
<lines>1.2cm 2.15cm 19.9cm 2.15cm</lines>
<drawCentredString x="10.5cm" y="1.7cm">[[ company.rml_footer1 ]]</drawCentredString>
<drawCentredString x="10.5cm" y="1.25cm">[[ company.rml_footer2 ]]</drawCentredString>
<drawCentredString x="10.5cm" y="0.8cm">Contact : [[ user.name ]] - Page: <pageNumber/></drawCentredString>
<lines>1.2cm 2.65cm 19.9cm 2.65cm</lines>
<place x="1.3cm" y="0cm" height="2.55cm" width="19.0cm">
<para style="main_footer">[[ company.rml_footer ]]</para>
<para style="main_footer">Contact : [[ user.name ]] - Page: <pageNumber/></para>
</place>
</pageGraphics>
</pageTemplate>
</header>"""
+23 -22
View File
@@ -31,19 +31,15 @@
<h1>
<field name="name" class="oe_inline"/>
</h1>
<label for="rml_header1" class="oe_edit_only"/>
<div>
<field name="rml_header1" placeholder="e.g. Global Business Solutions"/>
</div>
</div>
<group col="4">
<field name="partner_id" readonly="1" required="0" groups="base.group_no_one"/>
<field name="parent_id" groups="base.group_multi_company"/>
</group>
<notebook colspan="4">
<page string="General Information">
<group>
<group>
<field name="partner_id" readonly="1" required="0" groups="base.group_no_one"/>
<label for="street" string="Address"/>
<div>
<field name="street" placeholder="Street..."/>
@@ -53,32 +49,38 @@
<field name="state_id" class="oe_no_button" placeholder="State" style="width: 24%%" options='{"no_open": true}'/>
<field name="zip" placeholder="ZIP" style="width: 34%%"/>
</div>
<field name="country_id" placeholder="Country" class="oe_no_button" options='{"no_open": true}'/>
<field name="country_id" placeholder="Country" class="oe_no_button" options='{"no_open": true}' on_change="on_change_country(country_id)"/>
</div>
<label for="rml_header1"/>
<div>
<field name="rml_header1" placeholder="e.g. Global Business Solutions"/>
</div>
<field name="website" widget="url" placeholder="e.g. www.openerp.com"/>
</group>
<group>
<field name="phone" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/>
<field name="fax" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/>
<field name="email" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/>
<field name="vat" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/>
<field name="company_registry" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/>
<field name="phone"/>
<field name="fax"/>
<field name="email"/>
<field name="vat"/>
<field name="company_registry"/>
</group>
</group>
<group string="Bank Accounts">
<field name="bank_ids" colspan="4" nolabel="1"/>
<label for="rml_footer2"/>
<div name="bank_acc">
<field name="rml_footer2"/>
<!--<button name="%(bank_account_update)d" string="Set Bank Accounts" type="action" icon="gtk-go-forward" class="oe_inline"/>-->
<field name="bank_ids" nolabel="1"
context="{'default_company_id': active_id, 'footer_hide': False}"/>
</group>
<group string="Report Footer Configuration">
<field name="paper_format" on_change="onchange_paper_format(paper_format)"/>
<field name="custom_footer" invisible="1"/>
<label for="rml_footer"/>
<div>
<field name="rml_footer" on_change="onchange_footer()"/>
<button string="Set Automatic Footer" type="object" name="set_auto_footer"
attrs="{'invisible': [('custom_footer','=',False)]}" class="oe_edit_only"/>
</div>
</group>
</page>
<page string="Header/Footer" groups="base.group_no_one">
<group>
<field name="paper_format" on_change="onchange_paper_format(paper_format)"/>
<field name="rml_footer1"/>
</group>
<label for="rml_header"/>
<field name="rml_header"/>
<label for="rml_header2"/>
@@ -162,7 +164,7 @@
<field name="sequence"/>
</group>
</group>
</sheet>
</sheet>
</form>
</field>
</record>
@@ -190,4 +192,3 @@
</data>
</openerp>
+2 -1
View File
@@ -55,6 +55,7 @@ addresses belonging to this country.\n\nYou can use the python-style string pate
\n%(state_code)s: the code of the state
\n%(country_name)s: the name of the country
\n%(country_code)s: the code of the country"""),
'currency_id': fields.many2one('res.currency', 'Currency'),
}
_sql_constraints = [
('name_uniq', 'unique (name)',
@@ -63,7 +64,7 @@ addresses belonging to this country.\n\nYou can use the python-style string pate
'The code of the country must be unique !')
]
_defaults = {
'address_format': "%(company_name)s\n%(street)s\n%(street2)s\n%(city)s,%(state_code)s %(zip)s\n%(country_name)s",
'address_format': "%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s",
}
_order='name'
+10 -4
View File
@@ -22,11 +22,17 @@
<field name="model">res.country</field>
<field name="arch" type="xml">
<form string="Country" version="7.0">
<group col="4">
<field name="name"/>
<field name="code"/>
<field name="address_format" colspan="4" groups="base.group_no_one"/>
<group>
<group>
<field name="name"/>
<field name="currency_id"/>
</group>
<group>
<field name="code"/>
</group>
</group>
<label for="address_format" string="Address Format"/>
<field name="address_format" colspan="4" groups="base.group_no_one"/>
</form>
</field>
</record>
+1 -1
View File
@@ -56,7 +56,7 @@ class res_currency(osv.osv):
_columns = {
# Note: 'code' column was removed as of v6.0, the 'name' should now hold the ISO code.
'name': fields.char('Currency', size=32, required=True, help="Currency Code (ISO 4217)"),
'symbol': fields.char('Symbol', size=3, help="Currency sign, to be used when printing amounts."),
'symbol': fields.char('Symbol', size=4, help="Currency sign, to be used when printing amounts."),
'rate': fields.function(_current_rate, string='Current Rate', digits=(12,6),
help='The rate of the currency to the currency of rate 1.'),
'rate_ids': fields.one2many('res.currency.rate', 'currency_id', 'Rates'),
+77 -70
View File
@@ -21,7 +21,6 @@
import math
import openerp
import os
from osv import osv, fields
import re
import tools
@@ -59,20 +58,20 @@ class res_partner_category(osv.osv):
return super(res_partner_category, self).name_get(cr, uid, ids, context=context)
if isinstance(ids, (int, long)):
ids = [ids]
reads = self.read(cr, uid, ids, ['name','parent_id'], context=context)
reads = self.read(cr, uid, ids, ['name', 'parent_id'], context=context)
res = []
for record in reads:
name = record['name']
if record['parent_id']:
name = record['parent_id'][1]+' / '+name
name = record['parent_id'][1] + ' / ' + name
res.append((record['id'], name))
return res
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
if not args:
args=[]
args = []
if not context:
context={}
context = {}
if name:
# Be sure name_search is symetric to name_get
name = name.split(' / ')[-1]
@@ -86,23 +85,23 @@ class res_partner_category(osv.osv):
res = self.name_get(cr, uid, ids, context=context)
return dict(res)
_description='Partner Categories'
_description = 'Partner Categories'
_name = 'res.partner.category'
_columns = {
'name': fields.char('Category Name', required=True, size=64, translate=True),
'parent_id': fields.many2one('res.partner.category', 'Parent Category', select=True, ondelete='cascade'),
'complete_name': fields.function(_name_get_fnc, type="char", string='Full Name'),
'child_ids': fields.one2many('res.partner.category', 'parent_id', 'Child Categories'),
'active' : fields.boolean('Active', help="The active field allows you to hide the category without removing it."),
'parent_left' : fields.integer('Left parent', select=True),
'parent_right' : fields.integer('Right parent', select=True),
'active': fields.boolean('Active', help="The active field allows you to hide the category without removing it."),
'parent_left': fields.integer('Left parent', select=True),
'parent_right': fields.integer('Right parent', select=True),
'partner_ids': fields.many2many('res.partner', id1='category_id', id2='partner_id', string='Partners'),
}
_constraints = [
(osv.osv._check_recursion, 'Error ! You can not create recursive categories.', ['parent_id'])
]
_defaults = {
'active' : lambda *a: 1,
'active': lambda *a: 1,
}
_parent_store = True
_parent_order = 'name'
@@ -114,7 +113,7 @@ class res_partner_title(osv.osv):
_columns = {
'name': fields.char('Title', required=True, size=46, translate=True),
'shortcut': fields.char('Abbreviation', size=16, translate=True),
'domain': fields.selection([('partner','Partner'),('contact','Contact')], 'Domain', required=True, size=24)
'domain': fields.selection([('partner', 'Partner'), ('contact', 'Contact')], 'Domain', required=True, size=24)
}
_defaults = {
'domain': 'contact',
@@ -130,13 +129,13 @@ POSTAL_ADDRESS_FIELDS = ('street', 'street2', 'zip', 'city', 'state_id', 'countr
ADDRESS_FIELDS = POSTAL_ADDRESS_FIELDS + ('email', 'phone', 'fax', 'mobile', 'website', 'ref', 'lang')
class res_partner(osv.osv):
_description='Partner'
_description = 'Partner'
_name = "res.partner"
def _address_display(self, cr, uid, ids, name, args, context=None):
res={}
res = {}
for partner in self.browse(cr, uid, ids, context=context):
res[partner.id] =self._display_address(cr, uid, partner, context=context)
res[partner.id] = self._display_address(cr, uid, partner, context=context)
return res
def _get_image(self, cr, uid, ids, name, args, context=None):
@@ -144,7 +143,7 @@ class res_partner(osv.osv):
for obj in self.browse(cr, uid, ids, context=context):
result[obj.id] = tools.image_get_resized_images(obj.image)
return result
def _set_image(self, cr, uid, id, name, value, args, context=None):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
@@ -152,7 +151,7 @@ class res_partner(osv.osv):
_columns = {
'name': fields.char('Name', size=128, required=True, select=True),
'date': fields.date('Date', select=1),
'title': fields.many2one('res.partner.title','Title'),
'title': fields.many2one('res.partner.title', 'Title'),
'parent_id': fields.many2one('res.partner', 'Owned by'),
'child_ids': fields.one2many('res.partner', 'parent_id', 'Contacts'),
'ref': fields.char('Reference', size=64, select=1),
@@ -163,9 +162,9 @@ class res_partner(osv.osv):
"It is important to set a value for this field. You should use the same timezone "
"that is otherwise used to pick and render date and time values: your computer's timezone."),
'user_id': fields.many2one('res.users', 'Salesperson', help='The internal user that is in charge of communicating with this partner if any.'),
'vat': fields.char('TIN',size=32 ,help="Tax Identification Number. Check the box if the partner is subjected to taxes. Used by the some of the legal statements."),
'vat': fields.char('TIN', size=32, help="Tax Identification Number. Check the box if the partner is subjected to taxes. Used by the some of the legal statements."),
'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'),
'address': fields.one2many('res.partner.address', 'partner_id', 'Contacts'), # should be removed in version 7, but kept until then for backward compatibility
'category_id': fields.many2many('res.partner.category', id1='partner_id', id2='category_id', string='Tags'),
@@ -176,8 +175,8 @@ class res_partner(osv.osv):
'supplier': fields.boolean('Supplier', help="Check this box if the partner is a supplier. If it's not checked, purchase people will not see it when encoding a purchase order."),
'employee': fields.boolean('Employee', help="Check this box if the partner is an Employee."),
'function': fields.char('Job Position', size=128),
'type': fields.selection( [('default','Default'), ('invoice','Invoice'),
('delivery','Delivery'), ('contact','Contact'),
'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."),
'street': fields.char('Street', size=128),
@@ -194,28 +193,28 @@ class res_partner(osv.osv):
'birthdate': fields.char('Birthdate', size=64),
'is_company': fields.boolean('Company', help="Check if the contact is a company, otherwise it is a person"),
'use_parent_address': fields.boolean('Use Company Address', help="Select this if you want to set company's address information for this contact"),
# image: all image fields are base64 encoded and PIL-supported
'image': fields.binary("Image",
help="This field holds the image used as avatar for the "\
"partner. The image is base64 encoded, and PIL-supported. "\
"It is limited to a 1024x1024 px image."),
help="This field holds the image used as avatar for the partner, limited to 1024x1024px"),
'image_medium': fields.function(_get_image, fnct_inv=_set_image,
string="Medium-sized image", type="binary", multi="_get_image",
store = {
store={
'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Medium-sized image of the partner. It is automatically "\
"resized as a 180x180 px image, with aspect ratio preserved. "\
"resized as a 128x128px image, with aspect ratio preserved. "\
"Use this field in form views or some kanban views."),
'image_small': fields.function(_get_image, fnct_inv=_set_image,
string="Small-sized image", type="binary", multi="_get_image",
store = {
store={
'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Small-sized image of the partner. It is automatically "\
"resized as a 50x50 px image, with aspect ratio preserved. "\
"resized as a 64x64px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
'company_id': fields.many2one('res.company', 'Company', select=1),
'color': fields.integer('Color Index'),
'user_ids': fields.one2many('res.users', 'partner_id', 'Users'),
'contact_address': fields.function(_address_display, type='char', string='Complete Address'),
}
@@ -226,34 +225,32 @@ class res_partner(osv.osv):
return [context['category_id']]
return False
def _get_default_image(self, cr, uid, is_company, context=None):
def _get_default_image(self, cr, uid, is_company, context=None, colorize=False):
if is_company:
image_path = openerp.modules.get_module_resource('base', 'static/src/img', 'company_image.png')
image = open(openerp.modules.get_module_resource('base', 'static/src/img', 'company_image.png')).read()
else:
image_path = openerp.modules.get_module_resource('base', 'static/src/img', 'partner_image.png')
return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
image = tools.image_colorize(open(openerp.modules.get_module_resource('base', 'static/src/img', 'avatar.png')).read())
return tools.image_resize_image_big(image.encode('base64'))
_defaults = {
'active': True,
'lang': lambda self, cr, uid, context: context.get('lang', 'en_US'),
'tz': lambda self, cr, uid, context: context.get('tz', False),
'lang': lambda self, cr, uid, ctx: ctx.get('lang', 'en_US'),
'tz': lambda self, cr, uid, ctx: ctx.get('tz', False),
'customer': True,
'category_id': _default_category,
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner', context=c),
'company_id': lambda self, cr, uid, ctx: self.pool.get('res.company')._company_default_get(cr, uid, 'res.partner', context=ctx),
'color': 0,
'is_company': False,
'type': 'default',
'use_parent_address': True,
'image': lambda self, cr, uid, context: self._get_default_image(cr, uid, False, context),
'image_small': lambda self, cr, uid, context: self._get_default_image(cr, uid, False, context),
'image_medium': lambda self, cr, uid, context: self._get_default_image(cr, uid, False, context),
'image': lambda self, cr, uid, ctx: self._get_default_image(cr, uid, ctx.get('default_is_company', False), ctx),
}
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
name = self.read(cr, uid, [id], ['name'], context)[0]['name']
default.update({'name': _('%s (copy)')%(name)})
default.update({'name': _('%s (copy)') % (name)})
return super(res_partner, self).copy(cr, uid, id, default, context)
def onchange_type(self, cr, uid, ids, is_company, context=None):
@@ -324,9 +321,6 @@ class res_partner(osv.osv):
domain_siblings = [('parent_id', '=', vals['parent_id']), ('use_parent_address', '=', True)]
update_ids = [vals['parent_id']] + self.search(cr, uid, domain_siblings, context=context)
self.update_address(cr, uid, update_ids, vals, context)
if 'image' not in vals :
image_value = self._get_default_image(cr, uid, vals.get('is_company', False) or context.get('default_is_company'), context)
vals.update(tools.image_get_resized_images(image_value, return_big=True))
return super(res_partner,self).create(cr, uid, vals, context=context)
def update_address(self, cr, uid, ids, vals, context=None):
@@ -351,37 +345,34 @@ class res_partner(osv.osv):
res.append((record.id, name))
return res
def _parse_partner_name(self, text, context=None):
""" Supported syntax:
- 'Raoul <raoul@grosbedon.fr>': will find name and email address
- otherwise: default, everything is set as the name """
match = re.search(r'([^\s,<@]+@[^>\s,]+)', text)
if match:
email = match.group(1)
name = text[:text.index(email)].replace('"','').replace('<','').strip()
else:
name, email = text, ''
return name, email
def name_create(self, cr, uid, name, context=None):
""" Override of orm's name_create method for partners. The purpose is
to handle some basic formats to create partners using the
name_create.
Supported syntax:
- 'raoul@grosbedon.fr': create a partner with name raoul@grosbedon.fr
and sets its email to raoul@grosbedon.fr
- 'Raoul Grosbedon <raoul@grosbedon.fr>': create a partner with name
Raoul Grosbedon, and set its email to raoul@grosbedon.fr
- anything else: fall back on the default name_create
Regex :
- ([a-zA-Z0-9._%-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9._]{1,8}): raoul@grosbedon.fr
- ([\w\s.\\-]+)[\<]([a-zA-Z0-9._%-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9._]{1,8})[\>]:
Raoul Grosbedon, raoul@grosbedon.fr
"""
contact_regex = re.compile('([\w\s.\\-]+)[\<]([a-zA-Z0-9._%-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9._]{1,8})[\>]')
email_regex = re.compile('([a-zA-Z0-9._%-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9._]{1,8})')
contact_regex_res = contact_regex.findall(name)
email_regex_res = email_regex.findall(name)
if contact_regex_res:
name = contact_regex_res[0][0].rstrip(' ') # remove extra spaces on the right
email = contact_regex_res[0][1]
rec_id = self.create(cr, uid, {self._rec_name: name, 'email': email}, context);
return self.name_get(cr, uid, [rec_id], context)[0]
elif email_regex_res:
email = '%s' % (email_regex_res[0])
rec_id = self.create(cr, uid, {self._rec_name: email, 'email': email}, context);
return self.name_get(cr, uid, [rec_id], context)[0]
else:
rec_id = super(res_partner, self).create(cr, uid, {self._rec_name: name}, context)
return self.name_get(cr, uid, [rec_id], context)[0]
If only an email address is received and that the regex cannot find
a name, the name will have the email value.
If 'force_email' key in context: must find the email address. """
if context is None:
context = {}
name, email = self._parse_partner_name(name, context=context)
if context.get('force_email') and not email:
raise osv.except_osv(_('Warning'), _("Couldn't create contact without email address !"))
if not name and email:
name = email
rec_id = self.create(cr, uid, {self._rec_name: name or email, 'email': email or False}, context=context)
return self.name_get(cr, uid, [rec_id], context)[0]
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
if not args:
@@ -405,6 +396,21 @@ class res_partner(osv.osv):
return self.name_get(cr, uid, ids, context)
return super(res_partner,self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit)
def find_or_create(self, cr, uid, email, context=None):
""" Find a partner with the given ``email`` or use :py:method:`~.name_create`
to create one
:param str email: email-like string, which should contain at least one email,
e.g. ``"Raoul Grosbedon <r.g@grosbedon.fr>"``"""
assert email, 'an email is required for find_or_create to work'
emails = tools.email_split(email)
if emails:
email = emails[0]
ids = self.search(cr, uid, [('email','ilike',email)], context=context)
if not ids:
return self.name_create(cr, uid, email, context=context)[0]
return ids[0]
def _email_send(self, cr, uid, ids, email_from, subject, body, on_error=None):
partners = self.browse(cr, uid, ids)
for partner in partners:
@@ -493,7 +499,7 @@ class res_partner(osv.osv):
# get the information that will be injected into the display format
# get the address format
address_format = address.country_id and address.country_id.address_format or \
'%(company_name)s\n%(street)s\n%(street2)s\n%(city)s,%(state_code)s %(zip)s'
"%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s"
args = {
'state_code': address.state_id and address.state_id.code or '',
'state_name': address.state_id and address.state_id.name or '',
@@ -506,6 +512,8 @@ class res_partner(osv.osv):
args[field] = getattr(address, field) or ''
if without_company:
args['company_name'] = ''
elif address.parent_id:
address_format = '%(company_name)s\n' + address_format
return address_format % args
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
@@ -549,7 +557,6 @@ class res_partner(osv.osv):
res['arch'] = etree.tostring(doc)
return res
# 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"
+8 -11
View File
@@ -95,7 +95,7 @@
<field name="arch" type="xml">
<form string="Partners" version="7.0">
<sheet>
<field name="image" widget='image' class="oe_left" options='{"preview_image": "image_medium", "size": [90, 90]}'/>
<field name="image" widget='image' class="oe_left oe_avatar" options='{"preview_image": "image_medium", "size": [90, 90]}'/>
<div class="oe_title">
<div class="oe_edit_only">
<label for="name"/> (
@@ -130,8 +130,8 @@
<field name="street2"/>
<div class="address_format">
<field name="city" placeholder="City" style="width: 40%%"/>
<field name="state_id" class="oe_no_button" placeholder="State" style="width: 24%%" options='{"no_open": true}'/>
<field name="zip" placeholder="ZIP" style="width: 34%%"/>
<field name="state_id" class="oe_no_button" placeholder="State" style="width: 37%%" options='{"no_open": true}'/>
<field name="zip" placeholder="ZIP" style="width: 20%%"/>
</div>
<field name="country_id" placeholder="Country" class="oe_no_button" options='{"no_open": true}'/>
</div>
@@ -186,13 +186,10 @@
<td class="oe_kanban_title1" align="left" valign="middle">
<h4><a type="open"><field name="name"/></a></h4>
<i><div t-if="record.function.raw_value">
<field name="function"/><br/></div></i>
</td>
<td valign="top" align="right">
<a t-if="record.email.raw_value" title="Mail" t-att-href="'mailto:'+record.email.value" style="text-decoration: none;" >
<img src="/web/static/src/img/icons/terp-mail-message-new.png" border="0" width="16" height="16"/>
</a>
<field name="function"/></div></i>
<div><a t-if="record.email.raw_value" title="Mail" t-att-href="'mailto:'+record.email.value">
<field name="email"/>
</a></div>
</td>
</tr>
</table>
@@ -301,7 +298,7 @@
<field name="category_id"/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_vignette">
<div class="oe_kanban_vignette oe_semantic_html_override">
<a type="open">
<img t-att-src="kanban_image('res.partner', 'image_small', record.id.value)" class="oe_kanban_image"/>
</a>
+14 -18
View File
@@ -26,6 +26,7 @@ import logging
from lxml import etree
from lxml.builder import E
import netsvc
from openerp import SUPERUSER_ID
import openerp
import openerp.exceptions
from osv import fields,osv
@@ -188,7 +189,7 @@ class res_users(osv.osv):
result = super(res_users, self).read(cr, uid, ids, fields, context, load)
canwrite = self.pool.get('ir.model.access').check(cr, uid, 'res.users', 'write', False)
if not canwrite:
if isinstance(ids, (int, float)):
if isinstance(ids, (int, long)):
result = override_password(result)
else:
result = map(override_password, result)
@@ -206,11 +207,6 @@ class res_users(osv.osv):
('login_key', 'UNIQUE (login)', 'You can not have two users with the same login !')
]
def _get_default_image(self, cr, uid, context=None):
""" Override of res.partner: multicolor avatars ! """
image_path = openerp.modules.get_module_resource('base', 'static/src/img', 'avatar%d.png' % random.randint(0, 6))
return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
def _get_company(self,cr, uid, context=None, uid2=False):
if not uid2:
uid2 = uid
@@ -238,9 +234,9 @@ class res_users(osv.osv):
dataobj = self.pool.get('ir.model.data')
result = []
try:
dummy,group_id = dataobj.get_object_reference(cr, 1, 'base', 'group_user')
dummy,group_id = dataobj.get_object_reference(cr, SUPERUSER_ID, 'base', 'group_user')
result.append(group_id)
dummy,group_id = dataobj.get_object_reference(cr, 1, 'base', 'group_partner_manager')
dummy,group_id = dataobj.get_object_reference(cr, SUPERUSER_ID, 'base', 'group_partner_manager')
result.append(group_id)
except ValueError:
# If these groups does not exists anymore
@@ -248,14 +244,14 @@ class res_users(osv.osv):
return result
_defaults = {
'password' : '',
'active' : True,
'password': '',
'active': True,
'customer': False,
'menu_id': _get_menu,
'company_id': _get_company,
'company_ids': _get_companies,
'groups_id': _get_group,
'image': lambda self, cr, uid, context: self._get_default_image(cr, uid, context),
'image': lambda self, cr, uid, ctx={}: self.pool.get('res.partner')._get_default_image(cr, uid, False, ctx, colorize=True),
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
@@ -280,7 +276,7 @@ class res_users(osv.osv):
break
else:
if 'company_id' in values:
if not (values['company_id'] in self.read(cr, 1, uid, ['company_ids'], context=context)['company_ids']):
if not (values['company_id'] in self.read(cr, SUPERUSER_ID, uid, ['company_ids'], context=context)['company_ids']):
del values['company_id']
uid = 1 # safe fields only, so we write as super-user to bypass access rights
@@ -332,7 +328,7 @@ class res_users(osv.osv):
return super(res_users, self).copy(cr, uid, id, copydef, context)
def context_get(self, cr, uid, context=None):
user = self.browse(cr, 1, uid, context)
user = self.browse(cr, SUPERUSER_ID, uid, context)
result = {}
for k in self._all_columns.keys():
if k.startswith('context_'):
@@ -350,7 +346,7 @@ class res_users(osv.osv):
def action_get(self, cr, uid, context=None):
dataobj = self.pool.get('ir.model.data')
data_id = dataobj._get_id(cr, 1, 'base', 'action_res_users_my')
data_id = dataobj._get_id(cr, SUPERUSER_ID, 'base', 'action_res_users_my')
return dataobj.browse(cr, uid, data_id, context=context).res_id
def check_super(self, passwd):
@@ -361,7 +357,7 @@ class res_users(osv.osv):
def check_credentials(self, cr, uid, password):
""" Override this method to plug additional authentication methods"""
res = self.search(cr, 1, [('id','=',uid),('password','=',password)])
res = self.search(cr, SUPERUSER_ID, [('id','=',uid),('password','=',password)])
if not res:
raise openerp.exceptions.AccessDenied()
@@ -377,7 +373,7 @@ class res_users(osv.osv):
# of them rolled back due to a concurrent access.)
cr.autocommit(True)
# check if user exists
res = self.search(cr, 1, [('login','=',login)])
res = self.search(cr, SUPERUSER_ID, [('login','=',login)])
if res:
user_id = res[0]
# check credentials
@@ -542,7 +538,7 @@ class groups_implied(osv.osv):
return memo[g]
res = {}
for g in self.browse(cr, 1, ids, context):
for g in self.browse(cr, SUPERUSER_ID, ids, context):
res[g.id] = map(int, computed_set(g))
return res
@@ -687,7 +683,7 @@ class groups_view(osv.osv):
def get_user_groups_view(self, cr, uid, context=None):
try:
view = self.pool.get('ir.model.data').get_object(cr, 1, 'base', 'user_groups_view', context)
view = self.pool.get('ir.model.data').get_object(cr, SUPERUSER_ID, 'base', 'user_groups_view', context)
assert view and view._table_name == 'ir.ui.view'
except Exception:
view = False
+2 -4
View File
@@ -88,7 +88,7 @@
<form string="Users" version="7.0">
<field name="id" invisible="1"/>
<sheet>
<field name="image_medium" widget='image' class="oe_avatar oe_left"/>
<field name="image" widget='image' class="oe_avatar oe_left" options='{"preview_image": "image_medium"}'/>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1><field name="name"/></h1>
@@ -195,9 +195,7 @@
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<form string="Users" version="7.0">
<div class="oe_right oe_avatar">
<field name="image_small" widget='image' class="oe_image_small"/>
</div>
<field name="image" widget='image' class="oe_right oe_avatar" options='{"preview_image": "image_small"}'/>
<h1>
<field name="name" readonly="1" class="oe_inline"/>
(<field name="login" readonly="1" class="oe_inline"/>)
+13 -1
View File
@@ -172,6 +172,9 @@
<rng:define name="form">
<rng:element name="form">
<rng:ref name="overload"/>
<rng:optional><rng:attribute name="create" /></rng:optional>
<rng:optional><rng:attribute name="delete" /></rng:optional>
<rng:optional><rng:attribute name="edit" /></rng:optional>
<rng:optional><rng:attribute name="string"/></rng:optional>
<rng:optional><rng:attribute name="type"/></rng:optional>
<rng:optional><rng:attribute name="link"/></rng:optional>
@@ -181,7 +184,8 @@
<rng:define name="diagram">
<rng:element name="diagram">
<rng:optional><rng:attribute name="string"/></rng:optional>
<rng:optional><rng:attribute name="create" /></rng:optional>
<rng:optional><rng:attribute name="string"/></rng:optional>
<rng:ref name="node"/>
<rng:ref name="arrow"/>
<rng:zeroOrMore>
@@ -223,6 +227,8 @@
<rng:attribute name="default_group_by" />
</rng:optional>
<rng:optional><rng:attribute name="create" /></rng:optional>
<rng:optional><rng:attribute name="delete" /></rng:optional>
<rng:optional><rng:attribute name="edit" /></rng:optional>
<rng:optional><rng:attribute name="quick_create" /></rng:optional>
<rng:zeroOrMore>
<rng:ref name="field"/>
@@ -238,6 +244,9 @@
<rng:define name="tree">
<rng:element name="tree">
<rng:ref name="overload"/>
<rng:optional><rng:attribute name="create" /></rng:optional>
<rng:optional><rng:attribute name="delete" /></rng:optional>
<rng:optional><rng:attribute name="edit" /></rng:optional>
<rng:optional><rng:attribute name="string"/></rng:optional>
<rng:optional><rng:attribute name="colors"/></rng:optional>
<rng:optional><rng:attribute name="fonts"/></rng:optional>
@@ -376,6 +385,9 @@
<rng:value>5years</rng:value>
</rng:choice></rng:attribute>
</rng:optional>
<rng:optional><rng:attribute name="create"/></rng:optional>
<rng:optional><rng:attribute name="delete"/></rng:optional>
<rng:optional><rng:attribute name="edit"/></rng:optional>
<rng:optional><rng:attribute name="color"/></rng:optional>
<rng:optional><rng:attribute name="date_delay"/></rng:optional>
<rng:optional><rng:attribute name="day_length"/></rng:optional>
@@ -120,6 +120,5 @@
"access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0
"access_ir_mail_server_all","ir_mail_server","model_ir_mail_server",,1,0,0,0
"access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0
"access_ir_needaction_users_rel","ir_needaction_users_rel","model_ir_needaction_users_rel",,1,1,1,1
"access_ir_needaction_mixin","ir_needaction_mixin","model_ir_needaction_mixin",,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
120 access_ir_config_parameter ir_config_parameter model_ir_config_parameter 1 0 0 0
121 access_ir_mail_server_all ir_mail_server model_ir_mail_server 1 0 0 0
122 access_ir_actions_client ir_actions_client all model_ir_actions_client 1 0 0 0
access_ir_needaction_users_rel ir_needaction_users_rel model_ir_needaction_users_rel 1 1 1 1
123 access_ir_needaction_mixin ir_needaction_mixin model_ir_needaction_mixin 1 1 1 1
124
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Some files were not shown because too many files have changed in this diff Show More