[FIX] remove list coloring (mistake)
[odoo/odoo.git] / addons / portal / wizard.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2011 OpenERP S.A (<http://www.openerp.com>).
6 #
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.
11 #
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.
16 #
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/>.
19 #
20 ##############################################################################
21
22 import logging
23 import random
24
25 from osv import osv, fields
26 from tools.misc import email_re, email_send
27 from tools.translate import _
28
29 from base.res.res_user import _lang_get
30
31
32
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,
37
38 You have been created an OpenERP account at %(url)s.
39
40 Your login account data is:
41 Database: %(db)s
42 User:     %(login)s
43 Password: %(password)s
44
45 %(message)s
46
47 --
48 OpenERP - Open Source Business Applications
49 http://www.openerp.com
50 """)
51
52 ROOT_UID = 1
53
54 # character sets for passwords, excluding 0, O, o, 1, I, l
55 _PASSU = 'ABCDEFGHIJKLMNPQRSTUVWXYZ'
56 _PASSL = 'abcdefghijkmnpqrstuvwxyz'
57 _PASSD = '23456789'
58
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)
62     random.shuffle(chars)
63     return ''.join(chars)
64
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 ""
69
70
71
72 class wizard(osv.osv_memory):
73     """
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.
77     """
78     _name = 'res.portal.wizard'
79     _description = 'Portal Wizard'
80     
81     _columns = {
82         'portal_id': fields.many2one('res.portal', required=True,
83             string='Portal',
84             help="The portal in which new users must be added"),
85         'user_ids': fields.one2many('res.portal.wizard.user', 'wizard_id',
86             string='Users'),
87         'message': fields.text(string='Invitation message',
88             help="This text is included in the welcome email sent to the users"),
89     }
90
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             return {    # a user config based on a contact (address)
95                 'name': address.name,
96                 'user_email': extract_email(address.email),
97                 'lang': address.partner_id and address.partner_id.lang or 'en_US',
98                 'partner_id': address.partner_id and address.partner_id.id,
99             }
100         
101         user_ids = []
102         if context.get('active_model') == 'res.partner.address':
103             address_obj = self.pool.get('res.partner.address')
104             address_ids = context.get('active_ids', [])
105             addresses = address_obj.browse(cr, uid, address_ids, context)
106             user_ids = map(create_user_from_address, addresses)
107         
108         elif context.get('active_model') == 'res.partner':
109             partner_obj = self.pool.get('res.partner')
110             partner_ids = context.get('active_ids', [])
111             partners = partner_obj.browse(cr, uid, partner_ids, context)
112             for p in partners:
113                 # add one user per contact, or one user if no contact
114                 if p.address:
115                     user_ids.extend(map(create_user_from_address, p.address))
116                 else:
117                     user_ids.append({'lang': p.lang or 'en_US', 'partner_id': p.id})
118         
119         return user_ids
120
121     _defaults = {
122         'user_ids': _default_user_ids
123     }
124
125     def action_create(self, cr, uid, ids, context=None):
126         """ create new users in portal(s), and notify them by email """
127         # we copy the context to change the language for translating emails
128         context0 = context or {}
129         context = context0.copy()
130         
131         user_obj = self.pool.get('res.users')
132         user = user_obj.browse(cr, ROOT_UID, uid, context0)
133         if not user.user_email:
134             raise osv.except_osv(_('Email required'),
135                 _('You must have an email address in your User Preferences'
136                   ' to send emails.'))
137         
138         portal_obj = self.pool.get('res.portal')
139         for wiz in self.browse(cr, uid, ids, context):
140             # determine existing users
141             login_cond = [('login', 'in', [u.user_email for u in wiz.user_ids])]
142             user_ids = user_obj.search(cr, ROOT_UID, login_cond)
143             users = user_obj.browse(cr, ROOT_UID, user_ids)
144             logins = [u.login for u in users]
145             
146             # create new users in portal (skip existing logins)
147             new_users_data = [ {
148                     'name': u.name,
149                     'login': u.user_email,
150                     'password': random_password(),
151                     'user_email': u.user_email,
152                     'context_lang': u.lang,
153                     'partner_id': u.partner_id and u.partner_id.id,
154                 } for u in wiz.user_ids if u.user_email not in logins ]
155             portal_obj.write(cr, ROOT_UID, [wiz.portal_id.id],
156                 {'users': [(0, 0, data) for data in new_users_data]}, context0)
157             
158             # send email to all users (translated in their language)
159             data = {
160                 'company': user.company_id.name,
161                 'message': wiz.message or "",
162                 'url': wiz.portal_id.url or "(missing url)",
163                 'db': cr.dbname,
164             }
165             user_ids = user_obj.search(cr, ROOT_UID, login_cond)
166             users = user_obj.browse(cr, ROOT_UID, user_ids)
167             for dest_user in users:
168                 context['lang'] = dest_user.context_lang
169                 data['login'] = dest_user.login
170                 data['password'] = dest_user.password
171                 data['name'] = dest_user.name
172                 
173                 email_from = user.user_email
174                 email_to = dest_user.user_email
175                 subject = _(WELCOME_EMAIL_SUBJECT) % data
176                 body = _(WELCOME_EMAIL_BODY) % data
177                 res = email_send(email_from, [email_to], subject, body)
178                 if not res:
179                     logging.getLogger('res.portal.wizard').warning(
180                         'Failed to send email from %s to %s', email_from, email_to)
181         
182         return {'type': 'ir.actions.act_window_close'}
183
184 wizard()
185
186
187
188 class wizard_user(osv.osv_memory):
189     """
190         A model to configure users in the portal wizard.
191     """
192     _name = 'res.portal.wizard.user'
193     _description = 'Portal User Config'
194
195     _columns = {
196         'wizard_id': fields.many2one('res.portal.wizard', required=True,
197             string='Wizard'),
198         'name': fields.char(size=64, required=True,
199             string='User Name',
200             help="The user's real name"),
201         'user_email': fields.char(size=64, required=True,
202             string='E-mail',
203             help="Will be used as user login.  "  
204                  "Also necessary to send the account information to new users"),
205         'lang': fields.selection(_lang_get, required=True,
206             string='Language',
207             help="The language for the user's user interface"),
208         'partner_id': fields.many2one('res.partner',
209             string='Partner'),
210     }
211
212     def _check_email(self, cr, uid, ids):
213         """ check syntax of email address """
214         for wuser in self.browse(cr, uid, ids):
215             if not email_re.match(wuser.user_email): return False
216         return True
217
218     _constraints = [
219         (_check_email, 'Invalid email address', ['email']),
220     ]
221
222 wizard_user()
223
224
225