3
votes

I've created a model named event and another one named event.participant. The model event has the field participants, which is a One2many field pointing to event.participant (event 1:N event.participant).

In the form of event I have a button Confirm event, with the next code:

@api.multi
def confirm_event(self):
    for event in self:
        return event.participants.notify(composition_mode='mass_mail')

The method notify was created by me in the model event.participant. What it does is to open the mail.compose.message wizard form you see each time you want to send a mail from Odoo (with the fields from, to, subject, body, template_id, etc). Here is the code of the method notify:

@api.multi
def notify(self, composition_mode=False):
    form_view_id = self.env.ref(
        'mail.email_compose_message_wizard_form').id
    ctx = self.env.context.copy()
    if composition_mode:
        ctx.update({
            'default_composition_mode': composition_mode,
        })
    result = {
        'name': 'Send Mail',
        'view_type': 'form',
        'view_mode': 'form',
        'views': [(form_view_id, 'form'), ],
        'res_model': 'mail.compose.message',
        'context': ctx,
        'type': 'ir.actions.act_window',
        'target': 'new',
    }
    return result

Now I'm going to show an example of the behaviour I'm getting with this code:

I have an event with ID 16. That event has two participants with IDs 21 and 22. I go to the form of the event and click on the button Confirm event. The wizard form to send the email is opened rightly. But, then, I select an email template (this email template applies to event.participant model), and click on Send mail.

I get a template renderization error. I guess I know why I'm getting that error:

The active_model at the wizard form is event and the active_ids is [16], while they should be event.participant and [21, 22] respectively. So, as the email template selected applies to event.participant, the variables inside it fail. For example, the to of the email template is ${object.email|safe}. That object variable is replaced by the record 16 of event. The model event doesn't have a field named email, so it generates a renderization error.

I cannot create a template which applies to event, because it would be a nosense (how can I indicate in the to of the template all the email addresses of the participants?).

I have to use a template which applies to event.participant, but I need to have the right active_model and active_ids in the moment of the renderization. I tried to modify these variables directly in the context, but I give another error.

How can I achieve my purpose? Is there any easier mode to do that? Any help would be much appreciated!

3

3 Answers

4
votes

You can try this code:

@api.multi
def confirm_event(self):
    for event in self:
        return event.participants.notify()


@api.multi
def notify(self):
    self.ensure_one()
    form_view_id = self.env.ref('mail.email_compose_message_wizard_form')
    ctx = dict(default_model='event.participants',
               default_res_id=self.id,
               default_composition_mode='mass_mail',
               )
    return {
        'name': 'Send Mail',
        'type': 'ir.actions.act_window',
        'view_type': 'form',
        'view_mode': 'form',
        'res_model': 'mail.compose.message',
        'views': [(form_view_id.id, 'form'), ],
        'view_id': form_view_id.id,
        'context': ctx,
        'target': 'new',
    }
2
votes

I found a solution, but I think it's crazy. Finally I've modified the active_model and the active_ids in the context, I told it was giving an error, so I've also modified the active_id variable. Now it works. So I've added these lines to the ctx update in the notify method:

ctx.update({
    'default_composition_mode': composition_mode,
    'active_model': self._name,
    'active_ids': self._ids,
    'active_id': self._ids[0],
})

In spite of being working as I want, I think this is an awful workaround, and I'm pretty sure that it must be a better solution to solve my problem.

If anyone knows it, please, post the answer here!

2
votes

If you send view_id in to it, than it will open/redirect as given form view.

You may try this solution:

@api.multi
def notify(self, composition_mode=False):
    form_view_id = self.env.ref('mail.email_compose_message_wizard_form', False)
    ctx = self.env.context.copy()
    if composition_mode:
        ctx.update({
            'default_composition_mode': composition_mode,
        })
    result = {
        'name': _('Send Mail'),
        'view_type': 'form',
        'view_mode': 'form',
        'views': [(form_view_id, 'form')],
        'res_model': 'mail.compose.message',
        'view_id': form_view_id and form_view_id.id,
        'context': ctx,
        'type': 'ir.actions.act_window',
        'target': 'new',
    }
    return result