2011-04-22 14:41:22 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
##############################################################################
|
|
|
|
#
|
|
|
|
# OpenERP, Open Source Management Solution
|
|
|
|
# Copyright (C) 2004-2011 Tiny SPRL (<http://tiny.be>).
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as
|
|
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
|
|
# License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Affero General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
|
|
##############################################################################
|
|
|
|
|
2011-04-26 14:59:57 +00:00
|
|
|
import logging
|
|
|
|
import random
|
|
|
|
|
2011-04-22 14:41:22 +00:00
|
|
|
from osv import osv, fields
|
2011-04-26 14:59:57 +00:00
|
|
|
from tools.misc import email_re, email_send
|
2011-04-22 14:41:22 +00:00
|
|
|
from tools.translate import _
|
2011-04-26 14:59:57 +00:00
|
|
|
|
2011-04-22 14:41:22 +00:00
|
|
|
from base.res.res_user import _lang_get
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-04-28 13:52:27 +00:00
|
|
|
# welcome email sent to new portal users (note that calling tools.translate._
|
|
|
|
# has no effect except exporting those strings for translation)
|
|
|
|
WELCOME_EMAIL_SUBJECT = _("Your OpenERP account at %(company)s")
|
|
|
|
WELCOME_EMAIL_BODY = _("""Dear %(name)s,
|
2011-04-28 13:17:22 +00:00
|
|
|
|
|
|
|
You have been created an OpenERP account at %(url)s.
|
|
|
|
|
|
|
|
Your login account data is:
|
|
|
|
Database: %(db)s
|
|
|
|
User: %(login)s
|
|
|
|
Password: %(password)s
|
|
|
|
|
|
|
|
--
|
|
|
|
OpenERP - Open Source Business Applications
|
|
|
|
http://www.openerp.com
|
2011-04-28 13:52:27 +00:00
|
|
|
""")
|
2011-04-28 13:17:22 +00:00
|
|
|
|
2011-04-26 14:59:57 +00:00
|
|
|
ROOT_UID = 1
|
|
|
|
|
|
|
|
# character sets for passwords, excluding 0, O, o, 1, I, l
|
|
|
|
_PASSU = 'ABCDEFGHIJKLMNPQRSTUVWXYZ'
|
|
|
|
_PASSL = 'abcdefghijkmnpqrstuvwxyz'
|
|
|
|
_PASSD = '23456789'
|
|
|
|
|
|
|
|
def random_password():
|
|
|
|
# get 3 uppercase letters, 3 lowercase letters, 2 digits, and shuffle them
|
|
|
|
chars = map(random.choice, [_PASSU] * 3 + [_PASSL] * 3 + [_PASSD] * 2)
|
|
|
|
random.shuffle(chars)
|
|
|
|
return ''.join(chars)
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-04-27 10:26:55 +00:00
|
|
|
class wizard(osv.osv_memory):
|
2011-04-22 14:41:22 +00:00
|
|
|
"""
|
2011-04-27 10:26:55 +00:00
|
|
|
A wizard to create portal users from instances of either 'res.partner'
|
|
|
|
or 'res.partner.address'. The purpose is to provide an OpenERP database
|
|
|
|
access to customers or suppliers.
|
2011-04-22 14:41:22 +00:00
|
|
|
"""
|
2011-04-27 10:26:55 +00:00
|
|
|
_name = 'res.portal.wizard'
|
|
|
|
_description = 'Portal Wizard'
|
2011-04-22 14:41:22 +00:00
|
|
|
|
|
|
|
_columns = {
|
|
|
|
'portal_id': fields.many2one('res.portal', required=True,
|
|
|
|
string='Portal',
|
2011-04-27 12:57:58 +00:00
|
|
|
help="The portal in which new users must be added"),
|
2011-04-27 10:26:55 +00:00
|
|
|
'user_ids': fields.one2many('res.portal.wizard.user', 'wizard_id',
|
|
|
|
string='Users'),
|
2011-04-22 14:41:22 +00:00
|
|
|
}
|
2011-04-27 14:48:23 +00:00
|
|
|
_defaults = {
|
|
|
|
'user_ids': (lambda self, *args: self._default_user_ids(*args))
|
|
|
|
}
|
2011-04-26 08:41:30 +00:00
|
|
|
|
2011-04-27 14:48:23 +00:00
|
|
|
def _default_user_ids(self, cr, uid, context):
|
|
|
|
""" determine default user_ids from the active records """
|
2011-04-27 10:26:55 +00:00
|
|
|
# determine relevant res.partner.address(es) depending on context
|
|
|
|
addresses = []
|
2011-04-27 07:53:06 +00:00
|
|
|
if context.get('active_model') == 'res.partner.address':
|
2011-04-22 14:41:22 +00:00
|
|
|
address_obj = self.pool.get('res.partner.address')
|
2011-04-27 10:26:55 +00:00
|
|
|
address_ids = context.get('active_ids', [])
|
|
|
|
addresses = address_obj.browse(cr, uid, address_ids, context)
|
2011-04-27 07:53:06 +00:00
|
|
|
elif context.get('active_model') == 'res.partner':
|
|
|
|
partner_obj = self.pool.get('res.partner')
|
2011-04-27 10:26:55 +00:00
|
|
|
partner_ids = context.get('active_ids', [])
|
|
|
|
partners = partner_obj.browse(cr, uid, partner_ids, context)
|
|
|
|
for p in partners:
|
|
|
|
if p.address:
|
|
|
|
# take default address if present, or any address otherwise
|
2011-04-28 07:02:02 +00:00
|
|
|
def_addrs = filter(lambda a: a.type == 'default', p.address)
|
|
|
|
addresses.append(def_addrs[0] if def_addrs else p.address[0])
|
2011-04-27 07:53:06 +00:00
|
|
|
|
2011-04-27 10:26:55 +00:00
|
|
|
# create user configs based on these addresses
|
2011-04-27 14:48:23 +00:00
|
|
|
user_data = lambda address: {
|
|
|
|
'name': address.name,
|
|
|
|
'email': address.email,
|
|
|
|
'lang': address.partner_id and address.partner_id.lang,
|
|
|
|
'address_id': address.id,
|
|
|
|
}
|
|
|
|
return map(user_data, addresses)
|
2011-04-22 14:41:22 +00:00
|
|
|
|
2011-04-27 14:48:23 +00:00
|
|
|
def action_create(self, cr, uid, ids, context=None):
|
2011-04-27 10:26:55 +00:00
|
|
|
""" create new users in portal(s), and notify them by email """
|
2011-04-26 14:59:57 +00:00
|
|
|
# we copy the context to change the language for translating emails
|
|
|
|
context0 = context or {}
|
|
|
|
context = context0.copy()
|
|
|
|
|
|
|
|
user = self.pool.get('res.users').browse(cr, ROOT_UID, uid, context0)
|
|
|
|
if not user.user_email:
|
|
|
|
raise osv.except_osv(_('Email required'),
|
|
|
|
_('You must have an email address in your User Preferences'
|
|
|
|
' to send emails.'))
|
|
|
|
|
|
|
|
portal_obj = self.pool.get('res.portal')
|
2011-04-27 10:26:55 +00:00
|
|
|
for wiz in self.browse(cr, uid, ids, context):
|
2011-04-28 13:17:22 +00:00
|
|
|
# create new users in portal
|
2011-04-29 07:11:47 +00:00
|
|
|
users_data = [ {
|
2011-04-27 10:26:55 +00:00
|
|
|
'name': u.name,
|
|
|
|
'login': u.email,
|
|
|
|
'password': random_password(),
|
|
|
|
'user_email': u.email,
|
|
|
|
'context_lang': u.lang,
|
|
|
|
'address_id': u.address_id.id,
|
2011-04-29 07:11:47 +00:00
|
|
|
} for u in wiz.user_ids ]
|
2011-04-27 10:26:55 +00:00
|
|
|
portal_obj.write(cr, ROOT_UID, [wiz.portal_id.id],
|
2011-04-29 07:11:47 +00:00
|
|
|
{'users': [(0, 0, data) for data in users_data]}, context0)
|
2011-04-26 14:59:57 +00:00
|
|
|
|
2011-04-27 10:26:55 +00:00
|
|
|
# send email to new users (translated in their language)
|
|
|
|
for data in users_data:
|
|
|
|
context['lang'] = data['context_lang']
|
2011-04-28 13:17:22 +00:00
|
|
|
data['company'] = user.company_id.name
|
|
|
|
data['db'] = cr.dbname
|
2011-04-27 10:26:55 +00:00
|
|
|
data['url'] = "(missing url)"
|
|
|
|
|
2011-04-28 13:17:22 +00:00
|
|
|
email_from = user.user_email
|
2011-04-27 10:26:55 +00:00
|
|
|
email_to = data['user_email']
|
2011-04-28 13:17:22 +00:00
|
|
|
subject = _(WELCOME_EMAIL_SUBJECT) % data
|
|
|
|
body = _(WELCOME_EMAIL_BODY) % data
|
2011-04-27 10:26:55 +00:00
|
|
|
res = email_send(email_from, [email_to], subject, body)
|
|
|
|
if not res:
|
|
|
|
logging.getLogger('res.portal.wizard').warning(
|
|
|
|
'Failed to send email from %s to %s', email_from, email_to)
|
|
|
|
|
2011-04-28 09:33:07 +00:00
|
|
|
return {'type': 'ir.actions.act_window_close'}
|
2011-04-26 14:59:57 +00:00
|
|
|
|
2011-04-27 10:26:55 +00:00
|
|
|
wizard()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class wizard_user(osv.osv_memory):
|
|
|
|
"""
|
|
|
|
A model to configure users in the portal wizard.
|
|
|
|
"""
|
|
|
|
_name = 'res.portal.wizard.user'
|
|
|
|
_description = 'Portal User Config'
|
|
|
|
|
|
|
|
_columns = {
|
|
|
|
'wizard_id': fields.many2one('res.portal.wizard', required=True,
|
|
|
|
string='Wizard'),
|
|
|
|
'name': fields.char(size=64, required=True,
|
|
|
|
string='User Name',
|
|
|
|
help="The user's real name"),
|
|
|
|
'email': fields.char(size=64, required=True,
|
|
|
|
string='E-mail',
|
|
|
|
help="Will be used as user login. "
|
|
|
|
"Also necessary to send the account information to new users"),
|
|
|
|
'lang': fields.selection(_lang_get, required=True,
|
|
|
|
string='Language',
|
|
|
|
help="The language for the user's user interface"),
|
|
|
|
'address_id': fields.many2one('res.partner.address', required=True,
|
|
|
|
string='Address'),
|
|
|
|
'partner_id': fields.related('address_id', 'partner_id',
|
|
|
|
type='many2one', relation='res.partner', readonly=True,
|
|
|
|
string='Partner'),
|
|
|
|
}
|
|
|
|
|
|
|
|
def _check_email(self, cr, uid, ids):
|
|
|
|
""" check syntax of email address """
|
|
|
|
for wizard in self.browse(cr, uid, ids):
|
|
|
|
if not email_re.match(wizard.email): return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
def _check_exist(self, cr, uid, ids):
|
|
|
|
""" check whether login (email) already in use """
|
|
|
|
user_obj = self.pool.get('res.users')
|
|
|
|
for wizard in self.browse(cr, uid, ids):
|
|
|
|
condition = [('login', '=', wizard.email)]
|
|
|
|
if user_obj.search(cr, ROOT_UID, condition): return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
_constraints = [
|
|
|
|
(_check_email, 'Invalid email address', ['email']),
|
|
|
|
(_check_exist, 'User login already exists', ['email']),
|
|
|
|
]
|
|
|
|
|
|
|
|
wizard_user()
|
2011-04-22 14:41:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
|