1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2011 OpenERP S.A (<http://www.openerp.com>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
25 from osv import osv, fields
26 from tools.misc import email_re
27 from tools.translate import _
29 from base.res.res_users import _lang_get
33 # welcome email sent to new portal users (note that calling tools.translate._
34 # has no effect except exporting those strings for translation)
35 WELCOME_EMAIL_SUBJECT = _("Your OpenERP account at %(company)s")
36 WELCOME_EMAIL_BODY = _("""Dear %(name)s,
38 You have been created an OpenERP account at %(url)s.
40 Your login account data is:
43 Password: %(password)s
48 OpenERP - Open Source Business Applications
49 http://www.openerp.com
54 # character sets for passwords, excluding 0, O, o, 1, I, l
55 _PASSU = 'ABCDEFGHIJKLMNPQRSTUVWXYZ'
56 _PASSL = 'abcdefghijkmnpqrstuvwxyz'
59 def random_password():
60 # get 3 uppercase letters, 3 lowercase letters, 2 digits, and shuffle them
61 chars = map(random.choice, [_PASSU] * 3 + [_PASSL] * 3 + [_PASSD] * 2)
65 def extract_email(user_email):
66 """ extract the email address from a user-friendly email address """
67 m = email_re.search(user_email or "")
68 return m and m.group(0) or ""
72 class wizard(osv.osv_memory):
74 A wizard to create portal users from instances of either 'res.partner'
75 or 'res.partner.address'. The purpose is to provide an OpenERP database
76 access to customers or suppliers.
78 _name = 'res.portal.wizard'
79 _description = 'Portal Wizard'
82 'portal_id': fields.many2one('res.portal', required=True,
84 help="The portal in which new users must be added"),
85 'user_ids': fields.one2many('res.portal.wizard.user', 'wizard_id',
87 'message': fields.text(string='Invitation message',
88 help="This text is included in the welcome email sent to the users"),
91 def _default_user_ids(self, cr, uid, context):
92 """ determine default user_ids from the active records """
93 def create_user_from_address(address):
94 if isinstance(address, int):
95 res_partner_obj = self.pool.get('res.partner')
96 address = res_partner_obj.browse(cr, uid, address, context=context)
97 lang = address.id and address.lang or 'en_US'
98 partner_id = address.id
101 lang = address.parent_id and address.parent_id.lang or 'en_US'
102 partner_id = address.parent_id and address.parent_id.id
105 'name': address.name,
106 'user_email': extract_email(address.email),
108 'partner_id': partner_id,
112 if context.get('active_model') == 'res.partner':
113 partner_obj = self.pool.get('res.partner')
114 partner_ids = context.get('active_ids', [])
115 partners = partner_obj.browse(cr, uid, partner_ids, context)
117 # add one user per contact, or one user if no contact
119 user_ids.extend(map(create_user_from_address, p.child_ids))
120 elif p.is_company == False and p.customer == True:
121 user_ids.extend(map(create_user_from_address, [p.id]))
123 user_ids.append({'lang': p.lang or 'en_US', 'parent_id': p.id})
128 'user_ids': _default_user_ids
131 def action_create(self, cr, uid, ids, context=None):
132 """ create new users in portal(s), and notify them by email """
133 # we copy the context to change the language for translating emails
134 context0 = context or {}
135 context0['noshortcut'] = True # prevent shortcut creation
136 context = context0.copy()
138 user_obj = self.pool.get('res.users')
139 user = user_obj.browse(cr, ROOT_UID, uid, context0)
140 if not user.user_email:
141 raise osv.except_osv(_('Email required'),
142 _('You must have an email address in your User Preferences'
145 portal_obj = self.pool.get('res.portal')
146 for wiz in self.browse(cr, uid, ids, context):
147 # determine existing users
148 login_cond = [('login', 'in', [u.user_email for u in wiz.user_ids])]
149 existing_uids = user_obj.search(cr, ROOT_UID, login_cond)
150 existing_users = user_obj.browse(cr, ROOT_UID, existing_uids)
151 existing_logins = [u.login for u in existing_users]
153 # create new users in portal (skip existing logins)
156 'login': u.user_email,
157 'password': random_password(),
158 'user_email': u.user_email,
159 'context_lang': u.lang,
161 'action_id': wiz.portal_id.home_action_id and wiz.portal_id.home_action_id.id or False,
162 'partner_id': u.partner_id and u.partner_id.id,
163 'groups_id': [(6, 0, [])],
164 } for u in wiz.user_ids if u.user_email not in existing_logins ]
165 portal_obj.write(cr, ROOT_UID, [wiz.portal_id.id],
166 {'users': [(0, 0, data) for data in new_users_data]}, context0)
168 # send email to all users (translated in their language)
170 'company': user.company_id.name,
171 'message': wiz.message or "",
172 'url': wiz.portal_id.url or _("(missing url)"),
175 mail_message_obj = self.pool.get('mail.message')
176 dest_uids = user_obj.search(cr, ROOT_UID, login_cond)
177 dest_users = user_obj.browse(cr, ROOT_UID, dest_uids)
178 for dest_user in dest_users:
179 context['lang'] = dest_user.context_lang
180 data['login'] = dest_user.login
181 data['password'] = dest_user.password
182 data['name'] = dest_user.name
184 email_from = user.user_email
185 email_to = dest_user.user_email
186 subject = _(WELCOME_EMAIL_SUBJECT) % data
187 body = _(WELCOME_EMAIL_BODY) % data
188 res = mail_message_obj.schedule_with_attach(cr, uid, email_from , [email_to], subject, body, context=context)
190 logging.getLogger('res.portal.wizard').warning(
191 'Failed to send email from %s to %s', email_from, email_to)
193 return {'type': 'ir.actions.act_window_close'}
199 class wizard_user(osv.osv_memory):
201 A model to configure users in the portal wizard.
203 _name = 'res.portal.wizard.user'
204 _description = 'Portal User Config'
207 'wizard_id': fields.many2one('res.portal.wizard', required=True,
209 'name': fields.char(size=64, required=True,
211 help="The user's real name"),
212 'user_email': fields.char(size=64, required=True,
214 help="Will be used as user login. "
215 "Also necessary to send the account information to new users"),
216 'lang': fields.selection(_lang_get, required=True,
218 help="The language for the user's user interface"),
219 'partner_id': fields.many2one('res.partner',
223 def _check_email(self, cr, uid, ids):
224 """ check syntax of email address """
225 for wuser in self.browse(cr, uid, ids):
226 if not email_re.match(wuser.user_email): return False
230 (_check_email, 'Invalid email address', ['email']),
238 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: