Thibault Delavallée (OpenERP) has proposed merging
lp:~openerp-dev/openobject-server/trunk-openchatter-3-5-user-partner-inherit-tde
into lp:~openerp-dev/openobject-server/trunk-openchatter-3-5-tde.
Requested reviews:
OpenERP R&D Team (openerp-dev)
For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-openchatter-3-5-user-partner-inherit-tde/+merge/118705
OpenChatter intra feature branch.
User inherits from partner. Server-side branch :
- res.user inherits res.partner
- context_lang -> lang on res.partner
- user_email -> email on res.partner
- context_tz -> tz on res.partner
- modified base.sql
- modified algorithm to set context from res.user: all_columns, lang and tz
specific, now only context_*
--
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-openchatter-3-5-user-partner-inherit-tde/+merge/118705
Your team OpenERP R&D Team is requested to review the proposed merge of
lp:~openerp-dev/openobject-server/trunk-openchatter-3-5-user-partner-inherit-tde
into lp:~openerp-dev/openobject-server/trunk-openchatter-3-5-tde.
=== modified file 'openerp/addons/base/base.sql'
--- openerp/addons/base/base.sql 2012-07-17 08:50:28 +0000
+++ openerp/addons/base/base.sql 2012-08-08 10:24:40 +0000
@@ -151,9 +151,9 @@
login varchar(64) NOT NULL UNIQUE,
password varchar(64) default null,
email varchar(64) default null,
- context_tz varchar(64) default null,
+ tz varchar(64) default null,
signature text,
- context_lang varchar(64) default '',
+ lang varchar(64) default '',
-- No FK references below, will be added later by ORM
-- (when the destination rows exist)
company_id int,
@@ -385,7 +385,7 @@
-- Users
---------------------------------
-insert into res_users (id,login,password,name,active,company_id,context_lang) values (1,'admin','admin','Administrator',True,1,'en_US');
+insert into res_users (id,login,password,name,active,company_id,lang) values (1,'admin','admin','Administrator',True,1,'en_US');
insert into ir_model_data (name,module,model,noupdate,res_id) values ('user_root','base','res.users',True,1);
-- Compatibility purpose, to remove V6.0
=== modified file 'openerp/addons/base/base_data.xml'
--- openerp/addons/base/base_data.xml 2012-03-23 06:40:37 +0000
+++ openerp/addons/base/base_data.xml 2012-08-08 10:24:40 +0000
@@ -1087,9 +1087,15 @@
<field name="currency_id" ref="base.EUR"/>
</record>
+ <record model="res.partner" id="base.partner_root">
+ <field name="name">Administrator</field>
+ <field name="company_id" ref="main_company"/>
+ </record>
+
<record model="res.users" id="base.user_root">
<field name="signature">Administrator</field>
- <field name="company_id" ref="main_company"/>
+ <field name="partner_id" ref="base.partner_root"/>
+ <!-- <field name="company_id" ref="main_company"/> -->
<field name="menu_id" ref="action_menu_admin"/>
<field name="company_ids" eval="[(4, ref('main_company'))]"/>
</record>
@@ -1097,9 +1103,6 @@
<record id="main_partner" model="res.partner">
<field name="company_id" ref="main_company"/>
</record>
- <record id="EUR" model="res.currency">
- <field name="company_id" ref="main_company"/>
- </record>
<!-- The Following currency rates are considered as on 1st Jan,2010 against EUR. -->
<!-- Currencies -->
=== modified file 'openerp/addons/base/ir/ir_actions.py'
--- openerp/addons/base/ir/ir_actions.py 2012-08-04 21:53:00 +0000
+++ openerp/addons/base/ir/ir_actions.py 2012-08-08 10:24:40 +0000
@@ -625,8 +625,8 @@
if not email_from:
_logger.debug('--email-from command line option is not specified, using a fallback value instead.')
- if user.user_email:
- email_from = user.user_email
+ if user.email:
+ email_from = user.email
else:
email_from = "%s@%s" % (user.login, gethostname())
=== modified file 'openerp/addons/base/publisher_warranty/publisher_warranty.py'
--- openerp/addons/base/publisher_warranty/publisher_warranty.py 2012-05-09 05:38:31 +0000
+++ openerp/addons/base/publisher_warranty/publisher_warranty.py 2012-08-08 10:24:40 +0000
@@ -86,7 +86,7 @@
db_create_date = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
user = self.pool.get("res.users").browse(cr, uid, uid)
user_name = user.name
- email = user.user_email
+ email = user.email
msg = {'contract_name': valid_contract.name,
'tb': tb,
@@ -333,7 +333,7 @@
"db_create_date": db_create_date,
"version": release.version,
"contracts": [c.name for c in contracts],
- "language": user.context_lang,
+ "language": user.lang,
}
add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
=== removed file 'openerp/addons/base/res/photo.png'
Binary files openerp/addons/base/res/photo.png 2012-03-01 06:43:12 +0000 and openerp/addons/base/res/photo.png 1970-01-01 00:00:00 +0000 differ
=== modified file 'openerp/addons/base/res/res_partner.py'
--- openerp/addons/base/res/res_partner.py 2012-08-07 14:42:53 +0000
+++ openerp/addons/base/res/res_partner.py 2012-08-08 10:24:40 +0000
@@ -20,6 +20,7 @@
##############################################################################
import math
+import openerp
import os
from osv import osv, fields
import re
@@ -27,6 +28,11 @@
from tools.translate import _
import logging
import pooler
+import pytz
+import random
+
+def _tz_get(self,cr,uid, context=None):
+ return [(x, x) for x in pytz.all_timezones]
class res_payterm(osv.osv):
_description = 'Payment term'
@@ -150,7 +156,12 @@
'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),
- 'lang': fields.selection(_lang_get, 'Language', help="If the selected language is loaded in the system, all documents related to this partner will be printed in this language. If not, it will be english."),
+ 'lang': fields.selection(_lang_get, 'Language',
+ help="If the selected language is loaded in the system, all documents related to this partner will be printed in this language. If not, it will be english."),
+ 'tz': fields.selection(_tz_get, 'Timezone', size=64,
+ help="The partner's timezone, used to output proper date and time values inside printed reports. "
+ "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('VAT',size=32 ,help="Value Added Tax number. Check the box if the partner is subjected to the VAT. Used by the VAT legal statement."),
'bank_ids': fields.one2many('res.partner.bank', 'partner_id', 'Banks'),
@@ -203,7 +214,11 @@
help="Small-sized image of the partner. It is automatically "\
"resized as a 50x50 px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
- 'company_id': fields.many2one('res.company', 'Company', select=1),
+ # Special behavior for this field: res.company.search() will only return the companies
+ # available to the current user (should be the user's companies?), when the user_preference
+ # context is set.
+ 'company_id': fields.many2one('res.company', 'Company', select=1,
+ help="The company this partner is currently working for.", context={'user_preference': True}),
'color': fields.integer('Color Index'),
'contact_address': fields.function(_address_display, type='char', string='Complete Address'),
}
@@ -217,13 +232,15 @@
def _get_default_image(self, cr, uid, is_company, context=None):
if is_company:
- image_path = os.path.join( tools.config['root_path'], 'addons', 'base', 'res', 'company_icon.png')
+ image_path = openerp.modules.get_module_resource('base', 'static/src/img', 'company_icon.png')
else:
- image_path = os.path.join( tools.config['root_path'], 'addons', 'base', 'res', 'photo.png')
+ 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'))
_defaults = {
'active': True,
+ 'lang': lambda self, cr, uid, context: context.get('lang', 'en_US'),
+ 'tz': lambda self, cr, uid, context: context.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),
=== modified file 'openerp/addons/base/res/res_users.py'
--- openerp/addons/base/res/res_users.py 2012-08-07 11:08:59 +0000
+++ openerp/addons/base/res/res_users.py 2012-08-08 10:24:40 +0000
@@ -33,7 +33,6 @@
from osv import fields,osv
from osv.orm import browse_record
import pooler
-import random
from service import security
import tools
from tools.translate import _
@@ -96,60 +95,27 @@
groups()
-def _lang_get(self, cr, uid, context=None):
- obj = self.pool.get('res.lang')
- ids = obj.search(cr, uid, [('translatable','=',True)])
- res = obj.read(cr, uid, ids, ['code', 'name'], context=context)
- res = [(r['code'], r['name']) for r in res]
- return res
-
-def _tz_get(self,cr,uid, context=None):
- return [(x, x) for x in pytz.all_timezones]
-
class users(osv.osv):
+ """ User class. A res.users record models an OpenERP user and is different
+ from an employee.
+
+ res.users class now inherits from res.partner. The partner model is
+ used to store the data related to the partner: lang, name, address,
+ avatar, ... The user model is now dedicated to technical data.
+ """
__admin_ids = {}
_uid_cache = {}
+ _inherits = {
+ 'res.partner': 'partner_id',
+ }
_name = "res.users"
_description = 'Users'
_order = 'name'
- WELCOME_MAIL_SUBJECT = u"Welcome to OpenERP"
- WELCOME_MAIL_BODY = u"An OpenERP account has been created for you, "\
- "\"%(name)s\".\n\nYour login is %(login)s, "\
- "you should ask your supervisor or system administrator if you "\
- "haven't been given your password yet.\n\n"\
- "If you aren't %(name)s, this email reached you errorneously, "\
- "please delete it."
-
- def get_welcome_mail_subject(self, cr, uid, context=None):
- """ Returns the subject of the mail new users receive (when
- created via the res.config.users wizard), default implementation
- is to return config_users.WELCOME_MAIL_SUBJECT
- """
- return self.WELCOME_MAIL_SUBJECT
- def get_welcome_mail_body(self, cr, uid, context=None):
- """ Returns the subject of the mail new users receive (when
- created via the res.config.users wizard), default implementation
- is to return config_users.WELCOME_MAIL_BODY
- """
- return self.WELCOME_MAIL_BODY
-
def get_current_company(self, cr, uid):
cr.execute('select company_id, res_company.name from res_users left join res_company on res_company.id = company_id where res_users.id=%s' %uid)
return cr.fetchall()
- def send_welcome_email(self, cr, uid, id, context=None):
- if isinstance(id,list): id = id[0]
- user = self.read(cr, uid, id, ['email','login','name', 'user_email'], context=context)
- email = user['email'] or user['user_email']
-
- ir_mail_server = self.pool.get('ir.mail_server')
- msg = ir_mail_server.build_email(email_from=None, # take config default
- email_to=[email],
- subject=self.get_welcome_mail_subject(cr, uid, context=context),
- body=(self.get_welcome_mail_body(cr, uid, context=context) % user))
- return ir_mail_server.send_email(cr, uid, msg, context=context)
-
def _set_new_password(self, cr, uid, id, name, value, args, context=None):
if value is False:
# Do not update the password if no value is provided, ignore silently.
@@ -164,69 +130,28 @@
def _get_password(self, cr, uid, ids, arg, karg, context=None):
return dict.fromkeys(ids, '')
-
- def _get_image(self, cr, uid, ids, name, args, context=None):
- result = dict.fromkeys(ids, False)
- 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)
_columns = {
'id': fields.integer('ID'),
- 'name': fields.char('User Name', size=64, required=True, select=True,
- help="The new user's real name, used for searching"
- " and most listings"),
+ 'active': fields.boolean('Active'),
+ 'partner_id': fields.many2one('res.partner', required=True,
+ string='Related Partner', ondelete='cascade',
+ help='Partner-related data of the user'),
'login': fields.char('Login', size=64, required=True,
- help="Used to log into the system"),
- 'password': fields.char('Password', size=64, invisible=True, help="Keep empty if you don't want the user to be able to connect on the system."),
+ help="Used to log into the system"),
+ 'password': fields.char('Password', size=64, invisible=True,
+ help="Keep empty if you don't want the user to be able to connect on the system."),
'new_password': fields.function(_get_password, type='char', size=64,
- fnct_inv=_set_new_password,
- string='Set Password', help="Specify a value only when creating a user or if you're changing the user's password, "
- "otherwise leave empty. After a change of password, the user has to login again."),
- 'user_email': fields.char('Email', size=64),
+ fnct_inv=_set_new_password, string='Set Password',
+ help="Specify a value only when creating a user or if you're "\
+ "changing the user's password, otherwise leave empty. After "\
+ "a change of password, the user has to login again."),
'signature': fields.text('Signature', size=64),
- 'image': fields.binary("Avatar",
- help="This field holds the image used as avatar for the "\
- "user. The image is base64 encoded, and PIL-supported. "\
- "It is limited to a 1024x1024 px image."),
- 'image_medium': fields.function(_get_image, fnct_inv=_set_image,
- string="Medium-sized avatar", type="binary", multi="_get_image",
- store = {
- 'res.users': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
- },
- help="Medium-sized image of the user. It is automatically "\
- "resized as a 180x180 px 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="Smal-sized avatar", type="binary", multi="_get_image",
- store = {
- 'res.users': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
- },
- help="Small-sized image of the user. It is automatically "\
- "resized as a 50x50 px image, with aspect ratio preserved. "\
- "Use this field anywhere a small image is required."),
'active': fields.boolean('Active'),
'action_id': fields.many2one('ir.actions.actions', 'Home Action', help="If specified, this action will be opened at logon for this user, in addition to the standard menu."),
'menu_id': fields.many2one('ir.actions.actions', 'Menu Action', help="If specified, the action will replace the standard menu for this user."),
'groups_id': fields.many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', 'Groups'),
-
- # Special behavior for this field: res.company.search() will only return the companies
- # available to the current user (should be the user's companies?), when the user_preference
- # context is set.
- 'company_id': fields.many2one('res.company', 'Company', required=True,
- help="The company this user is currently working for.", context={'user_preference': True}),
-
'company_ids':fields.many2many('res.company','res_company_users_rel','user_id','cid','Companies'),
- 'context_lang': fields.selection(_lang_get, 'Language', required=True,
- help="The default language used in the graphical user interface, when translations are available. To add a new language, you can use the 'Load a Translation' wizard available from the 'Administration' menu."),
- 'context_tz': fields.selection(_tz_get, 'Timezone', size=64,
- help="The user's timezone, used to output proper date and time values inside printed reports. "
- "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."),
- 'date': fields.datetime('Latest Connection', readonly=True),
}
def on_change_company_id(self, cr, uid, ids, company_id):
@@ -268,8 +193,8 @@
ids = [ids]
res = dict.fromkeys(ids, False)
for user in self.browse(cr, uid, ids, context=context):
- if user.user_email:
- res[user.id] = "%s <%s>" % (user.name, user.user_email)
+ if user.email:
+ res[user.id] = "%s <%s>" % (user.name, user.email)
return res
def _get_admin_id(self, cr):
@@ -315,16 +240,8 @@
pass
return result
- def _get_default_image(self, cr, uid, context=None):
- # default image file name: avatar0 -> avatar6.png, choose randomly
- 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'))
-
_defaults = {
'password' : '',
- 'context_lang': lambda self, cr, uid, context: context.get('lang', 'en_US'),
- 'context_tz': lambda self, cr, uid, context: context.get('tz', False),
- 'image': _get_default_image,
'active' : True,
'menu_id': _get_menu,
'company_id': _get_company,
@@ -333,7 +250,7 @@
}
# User can write to a few of her own fields (but not her groups for example)
- SELF_WRITEABLE_FIELDS = ['password', 'signature', 'action_id', 'company_id', 'user_email', 'name', 'image', 'image_medium', 'image_small']
+ SELF_WRITEABLE_FIELDS = ['password', 'signature', 'action_id', 'company_id', 'email', 'name', 'image', 'image_medium', 'image_small']
def write(self, cr, uid, ids, values, context=None):
if not hasattr(ids, '__iter__'):
@@ -398,12 +315,18 @@
def context_get(self, cr, uid, context=None):
user = self.browse(cr, uid, uid, context)
result = {}
- for k in self._columns.keys():
+ for k in self._all_columns.keys():
if k.startswith('context_'):
+ context_key = k[8:]
+ elif k in ['lang', 'tz']:
+ context_key = k
+ else:
+ context_key = False
+ if context_key:
res = getattr(user,k) or False
if isinstance(res, browse_record):
res = res.id
- result[k[8:]] = res or False
+ result[context_key] = res or False
return result
def action_get(self, cr, uid, context=None):
=== modified file 'openerp/addons/base/res/res_users_view.xml'
--- openerp/addons/base/res/res_users_view.xml 2012-08-06 15:53:25 +0000
+++ openerp/addons/base/res/res_users_view.xml 2012-08-08 10:24:40 +0000
@@ -112,8 +112,8 @@
<page string="Preferences">
<group>
<group name="preferences">
- <field name="context_lang"/>
- <field name="context_tz"/>
+ <field name="lang"/>
+ <field name="tz"/>
</group>
<group groups="base.group_no_one">
<field name="action_id"/>
@@ -121,7 +121,7 @@
</group>
</group>
<group>
- <field name="user_email" widget="email"/>
+ <field name="email" widget="email"/>
<field name="signature"/>
</group>
</page>
@@ -146,7 +146,7 @@
<tree string="Users">
<field name="name"/>
<field name="login"/>
- <field name="context_lang"/>
+ <field name="lang"/>
<field name="date"/>
</tree>
</field>
@@ -210,15 +210,15 @@
(<field name="login" readonly="1" class="oe_inline"/>)
</h1>
<group name="preferences" col="4">
- <field name="context_lang" readonly="0"/>
+ <field name="lang" readonly="0"/>
<field name="company_id" readonly="0"
groups="base.group_multi_company" on_change="on_change_company_id(company_id)"/>
- <field name="context_tz" readonly="0"/>
+ <field name="tz" readonly="0"/>
<field name="company_id" widget="selection" readonly="0"
groups="base.group_multi_company" on_change="on_change_company_id(company_id)"/>
</group>
<group string="Email Preferences">
- <field name="user_email" widget="email" readonly="0"/>
+ <field name="email" widget="email" readonly="0"/>
<field name="signature" readonly="0"/>
</group>
</sheet>
=== renamed file 'openerp/addons/base/res/company_icon.png' => 'openerp/addons/base/static/src/img/company_icon.png'
=== modified file 'openerp/service/web_services.py'
--- openerp/service/web_services.py 2012-03-22 15:05:06 +0000
+++ openerp/service/web_services.py 2012-08-08 10:24:40 +0000
@@ -75,10 +75,10 @@
mids = modobj.search(cr, 1, [('state', '=', 'installed')])
modobj.update_translations(cr, 1, mids, lang)
- cr.execute('UPDATE res_users SET password=%s, context_lang=%s, active=True WHERE login=%s', (
+ cr.execute('UPDATE res_users SET password=%s, lang=%s, active=True WHERE login=%s', (
user_password, lang, 'admin'))
cr.execute('SELECT login, password, name ' \
- ' FROM res_users ' \
+ ' FROM res_users ' \
' ORDER BY login')
serv.actions[id].update(users=cr.dictfetchall(), clean=True)
cr.commit()
@@ -425,7 +425,7 @@
The whole source code is distributed under the terms of the
GNU Public Licence.
-(c) 2003-TODAY, Fabien Pinckaers - Tiny sprl''')
+(c) 2003-TODAY - OpenERP SA''')
if extended:
return info, release.version
_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help : https://help.launchpad.net/ListHelp