- Click to create a new portal. -
- A portal helps defining specific views and rules for a group of - users (the portal group). A portal menu, widgets and specific - groups may be assigned to the portal's users. -
-%s' % body}, context=context) - + def onchange_portal_id(self, cr, uid, ids, portal_id, context=None): + # for each partner, determine corresponding portal.wizard.user records + res_partner = self.pool.get('res.partner') + partner_ids = context and context.get('active_ids') or [] + contact_ids = set() + user_changes = [] + for partner in res_partner.browse(cr, SUPERUSER_ID, partner_ids, context): + for contact in (partner.child_ids or [partner]): + # make sure that each contact appears at most once in the list + if contact.id not in contact_ids: + contact_ids.add(contact.id) + in_portal = False + if contact.user_ids: + in_portal = portal_id in [g.id for g in contact.user_ids[0].groups_id] + user_changes.append((0, 0, { + 'partner_id': contact.id, + 'email': contact.email, + 'in_portal': in_portal, + })) + return {'value': {'user_ids': user_changes}} + + def action_apply(self, cr, uid, ids, context=None): + wizard = self.browse(cr, uid, ids[0], context) + portal_user_ids = [user.id for user in wizard.user_ids] + self.pool.get('portal.wizard.user').action_apply(cr, uid, portal_user_ids, context) return {'type': 'ir.actions.act_window_close'} -wizard() - - - class wizard_user(osv.osv_memory): """ A model to configure users in the portal wizard. """ - _name = 'res.portal.wizard.user' + _name = '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='Email', - 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"), - 'partner_id': fields.many2one('res.partner', - string='Partner'), + 'wizard_id': fields.many2one('portal.wizard', string='Wizard', required=True), + 'partner_id': fields.many2one('res.partner', string='Contact', required=True, readonly=True), + 'email': fields.char(size=240, string='Email'), + 'in_portal': fields.boolean('In Portal'), } - def _check_email(self, cr, uid, ids): - """ check syntax of email address """ - for wuser in self.browse(cr, uid, ids): - if not email_re.match(wuser.email): return False - return True + def create(self, cr, uid, values, context=None): + """ overridden to update the partner's email (if necessary) """ + id = super(wizard_user, self).create(cr, uid, values, context) + wuser = self.browse(cr, uid, id, context) + if wuser.partner_id.email != wuser.email: + wuser.partner_id.write({'email': wuser.email}) + return id - _constraints = [ - (_check_email, 'Invalid email address', ['email']), - ] + def action_apply(self, cr, uid, ids, context=None): + res_users = self.pool.get('res.users') + for wizard_user in self.browse(cr, SUPERUSER_ID, ids, context): + portal = wizard_user.wizard_id.portal_id + user = self._retrieve_user(cr, SUPERUSER_ID, wizard_user, context) + if wizard_user.in_portal: + # create a user if necessary, and make sure it is in the portal group + if not user: + user = self._create_user(cr, SUPERUSER_ID, wizard_user, context) + if (not user.active) or (portal not in user.groups_id): + user.write({'active': True, 'groups_id': [(4, portal.id)]}) + wizard_user = self.browse(cr, SUPERUSER_ID, wizard_user.id, context) + self._send_email(cr, uid, wizard_user, context) + else: + # remove the user (if it exists) from the portal group + if user and (portal in user.groups_id): + # if user belongs to portal only, deactivate it + if len(user.groups_id) <= 1: + user.write({'groups_id': [(3, portal.id)], 'active': False}) + else: + user.write({'groups_id': [(3, portal.id)]}) + wizard_user = self.browse(cr, SUPERUSER_ID, wizard_user.id, context) + self._send_email(cr, uid, wizard_user, context) -wizard_user() + def _retrieve_user(self, cr, uid, wizard_user, context=None): + """ retrieve the (possibly inactive) user corresponding to wizard_user.partner_id + @param wizard_user: browse record of model portal.wizard.user + @return: browse record of model res.users + """ + if wizard_user.partner_id.user_ids: + return wizard_user.partner_id.user_ids[0] + # the user may be inactive, search for it + res_users = self.pool.get('res.users') + domain = [('partner_id', '=', wizard_user.partner_id.id), ('active', '=', False)] + user_ids = res_users.search(cr, uid, domain) + return user_ids and res_users.browse(cr, uid, user_ids[0], context) or False + def _create_user(self, cr, uid, wizard_user, context=None): + """ create a new user for wizard_user.partner_id + @param wizard_user: browse record of model portal.wizard.user + @return: browse record of model res.users + """ + res_users = self.pool.get('res.users') + create_context = dict(context or {}, noshortcut=True) # to prevent shortcut creation + values = { + 'login': extract_email(wizard_user.email), + 'password': random_password(), + 'partner_id': wizard_user.partner_id.id, + 'groups_id': [(6, 0, [])], + 'share': True, + } + user_id = res_users.create(cr, uid, values, context=create_context) + return res_users.browse(cr, uid, user_id, context) + def _send_email(self, cr, uid, wizard_user, context=None): + """ send notification email to a new/former portal user + @param wizard_user: browse record of model portal.wizard.user + @return: the id of the created mail.mail record + """ + this_context = context + this_user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context) + if not this_user.email: + raise osv.except_osv(_('Email required'), + _('You must have an email address in your User Preferences to send emails.')) + # determine subject and body in the portal user's language + url = self.pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'web.base.url', context=this_context) + user = self._retrieve_user(cr, SUPERUSER_ID, wizard_user, context) + context = dict(this_context or {}, lang=user.lang) + data = { + 'company': this_user.company_id.name, + 'portal': wizard_user.wizard_id.portal_id.name, + 'welcome_message': wizard_user.wizard_id.welcome_message or "", + 'goodbye_message': wizard_user.wizard_id.goodbye_message or "", + 'url': url or _("(missing url)"), + 'db': cr.dbname, + 'login': user.login, + 'password': user.password, + 'name': user.name + } + if wizard_user.in_portal: + subject = _(WELCOME_EMAIL_SUBJECT) % data + body = _(WELCOME_EMAIL_BODY) % data + else: + subject = _(GOODBYE_EMAIL_SUBJECT) % data + body = _(GOODBYE_EMAIL_BODY) % data + + mail_mail = self.pool.get('mail.mail') + mail_values = { + 'email_from': this_user.email, + 'email_to': user.email, + 'subject': subject, + 'body_html': '
%s' % body, + 'state': 'outgoing', + } + return mail_mail.create(cr, uid, mail_values, context=this_context) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal/wizard/portal_wizard_view.xml b/addons/portal/wizard/portal_wizard_view.xml index f3cd5c98bb4..c8e3f30b128 100644 --- a/addons/portal/wizard/portal_wizard_view.xml +++ b/addons/portal/wizard/portal_wizard_view.xml @@ -3,28 +3,34 @@