[IMP] attach the 'Our company' menu items to the portal's root menu
[odoo/odoo.git] / addons / portal / wizard / 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
27 from tools.translate import _
28
29 from base.res.res_users import _lang_get
30 _logger = logging.getLogger(__name__)
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             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
99                 
100             else:
101                 lang = address.parent_id and address.parent_id.lang or 'en_US'
102                 partner_id = address.parent_id and address.parent_id.id
103             
104             return{
105                    'name': address.name,
106                    'user_email': extract_email(address.email),
107                    'lang': lang,
108                    'partner_id': partner_id,
109                    }
110         
111         user_ids = []
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)
116             for p in partners:
117                 # add one user per contact, or one user if no contact
118                 if p.child_ids:
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]))
122                 else:
123                     user_ids.append({'lang': p.lang or 'en_US', 'parent_id': p.id})
124         
125         return user_ids
126
127     _defaults = {
128         'user_ids': _default_user_ids
129     }
130
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()
137         
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'
143                   ' to send emails.'))
144         
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]
152             
153             # create new users in portal (skip existing logins)
154             new_users_data = [ {
155                     'name': u.name,
156                     'login': u.user_email,
157                     'password': random_password(),
158                     'user_email': u.user_email,
159                     'context_lang': u.lang,
160                     'share': True,
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)
167             
168             # send email to all users (translated in their language)
169             data = {
170                 'company': user.company_id.name,
171                 'message': wiz.message or "",
172                 'url': wiz.portal_id.url or _("(missing url)"),
173                 'db': cr.dbname,
174             }
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
183                 
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)
189                 if not res:
190                     _logger.warning(
191                         'Failed to send email from %s to %s', email_from, email_to)
192         
193         return {'type': 'ir.actions.act_window_close'}
194
195 wizard()
196
197
198
199 class wizard_user(osv.osv_memory):
200     """
201         A model to configure users in the portal wizard.
202     """
203     _name = 'res.portal.wizard.user'
204     _description = 'Portal User Config'
205
206     _columns = {
207         'wizard_id': fields.many2one('res.portal.wizard', required=True,
208             string='Wizard'),
209         'name': fields.char(size=64, required=True,
210             string='User Name',
211             help="The user's real name"),
212         'user_email': fields.char(size=64, required=True,
213             string='Email',
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,
217             string='Language',
218             help="The language for the user's user interface"),
219         'partner_id': fields.many2one('res.partner',
220             string='Partner'),
221     }
222
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
227         return True
228
229     _constraints = [
230         (_check_email, 'Invalid email address', ['email']),
231     ]
232
233 wizard_user()
234
235
236
237
238 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: