Skip to content
Snippets Groups Projects
Commit 313a7d9e authored by Jérémy Hennecart's avatar Jérémy Hennecart Committed by Thibault Delavallée
Browse files

[ADD] mass_mailing_slides: allow to mass mail course attendees


PURPOSE

eLearning should have its own application in manager. Indeed this is becoming
a big application and having it embedded inside Website application is not
enough anymore. It should also hold updated and easy-to-use menus,
navigation, actions and views in backend.

SPECIFICATIONS

Integrate a button on slide.channel form view allowing to perform a mass
mailing on course attendees. Do a flow similar to event.

Add menu entry in menu of slide.channel kanban card after invite
  * Mail Attendees (same as on the course card and depend of the setting)

Add menu entry inside Settings
  * Settings: add an option to install module mass_mailing_slide

LINKS

Task 1978729
PR #35061

Co-Authored-By: default avatarThibault Delavallée <tde@odoo.com>
Co-Authored-By: default avatarJérémy Hennecart <jeh@odoo.com>
parent fd9962cd
No related branches found
No related tags found
No related merge requests found
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Mass mailing on course members',
'category': 'Hidden',
'version': '1.0',
'description':
"""
Mass mail course members
========================
Bridge module adding UX requirements to ease mass mailing of course members.
""",
'depends': ['website_slides', 'mass_mailing'],
'data': [
'views/slide_channel_views.xml'
],
'auto_install': True,
}
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import slide_channel
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, _
class Course(models.Model):
_inherit = "slide.channel"
def action_mass_mailing_attendees(self):
domain = [('slide_channel_ids', 'in', self.ids)]
mass_mailing_action = dict(
name=_('Mass Mail Course Members'),
type='ir.actions.act_window',
res_model='mailing.mailing',
view_mode='form',
target='current',
context=dict(
default_mailing_model_id=self.env.ref('base.model_res_partner').id,
default_mailing_domain=domain,
),
)
return mass_mailing_action
<?xml version="1.0"?>
<odoo>
<record id="slide_channel_view_form" model="ir.ui.view">
<field name="name">slide.channel.view.form.inherit.mass.mailing</field>
<field name="model">slide.channel</field>
<field name="inherit_id" ref="website_slides.view_slide_channel_form"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_redirect_to_members']" position="before">
<button class="oe_stat_button" type="object"
name="action_mass_mailing_attendees"
icon="fa-envelope-o"
attrs="{'invisible': [('members_count', '=', 0)]}">
<div class="o_field_widget o_stat_info">
<span class="o_stat_text">Mail Attendees</span>
</div>
</button>
</xpath>
</field>
</record>
<record id="slide_channel_view_kanban" model="ir.ui.view">
<field name="name">slide.channel.view.kanban.inherit.mass.mailing</field>
<field name="model">slide.channel</field>
<field name="inherit_id" ref="website_slides.slide_channel_view_kanban"/>
<field name="arch" type="xml">
<xpath expr="//a[@name='action_channel_invite']" position="after">
<a class="dropdown-item" name="action_mass_mailing_attendees" role="menuitem" type="object">
Mail Attendees
</a>
</xpath>
</field>
</record>
</odoo>
...@@ -10,4 +10,4 @@ from . import res_config_settings ...@@ -10,4 +10,4 @@ from . import res_config_settings
from . import website from . import website
from . import res_users from . import res_users
from . import res_groups from . import res_groups
from . import res_partner from . import res_partner
\ No newline at end of file
...@@ -11,3 +11,4 @@ class ResConfigSettings(models.TransientModel): ...@@ -11,3 +11,4 @@ class ResConfigSettings(models.TransientModel):
module_website_sale_slides = fields.Boolean(string="Sell on eCommerce") module_website_sale_slides = fields.Boolean(string="Sell on eCommerce")
module_website_slides_forum = fields.Boolean(string="Forum") module_website_slides_forum = fields.Boolean(string="Forum")
module_website_slides_survey = fields.Boolean(string="Certifications") module_website_slides_survey = fields.Boolean(string="Certifications")
module_mass_mailing_slides = fields.Boolean(string="Mailing")
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details. # Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models from odoo import api, fields, models, _
class ResPartner(models.Model): class ResPartner(models.Model):
_inherit = 'res.partner' _inherit = 'res.partner'
slide_channels_count = fields.Integer('Course Count', compute='_compute_slide_channels_count') slide_channel_ids = fields.Many2many(
slide_channels_company_count = fields.Integer('Company Course Count', compute='_compute_slide_channels_company_count') 'slide.channel', 'slide_channel_partner', 'partner_id', 'channel_id',
string='eLearning Courses')
slide_channel_count = fields.Integer('Course Count', compute='_compute_slide_channel_count')
slide_channel_company_count = fields.Integer('Company Course Count', compute='_compute_slide_channel_company_count')
@api.depends('is_company') @api.depends('is_company')
def _compute_slide_channels_count(self): def _compute_slide_channel_count(self):
read_group_res = self.env['slide.channel.partner'].sudo().read_group( read_group_res = self.env['slide.channel.partner'].sudo().read_group(
[('partner_id', 'in', self.ids)], [('partner_id', 'in', self.ids)],
['partner_id'], 'partner_id' ['partner_id'], 'partner_id'
) )
data = dict((res['partner_id'][0], res['partner_id_count']) for res in read_group_res) data = dict((res['partner_id'][0], res['partner_id_count']) for res in read_group_res)
for partner in self: for partner in self:
partner.slide_channels_count = data.get(partner.id, 0) partner.slide_channel_count = data.get(partner.id, 0)
@api.depends('is_company', 'child_ids.slide_channels_count') @api.depends('is_company', 'child_ids.slide_channel_count')
def _compute_slide_channels_company_count(self): def _compute_slide_channel_company_count(self):
for partner in self: for partner in self:
if partner.is_company: if partner.is_company:
partner.slide_channels_company_count = self.env['slide.channel'].sudo().search_count( partner.slide_channel_company_count = self.env['slide.channel'].sudo().search_count(
[('partner_ids', 'in', partner.child_ids.ids)] [('partner_ids', 'in', partner.child_ids.ids)]
) )
else: else:
partner.slide_channels_company_count = 0 partner.slide_channel_company_count = 0
def action_view_courses(self): def action_view_courses(self):
action = self.env.ref('website_slides.res_partner_action_courses').read()[0] action = self.env.ref('website_slides.slide_channel_action_overview').read()[0]
action['view_mode'] = 'tree' action['name'] = _('Followed Courses')
action['domain'] = ['|', ('partner_ids', 'in', self.ids), ('partner_ids', 'in', self.child_ids.ids)] action['domain'] = ['|', ('partner_ids', 'in', self.ids), ('partner_ids', 'in', self.child_ids.ids)]
return action return action
...@@ -43,6 +43,18 @@ ...@@ -43,6 +43,18 @@
</div> </div>
</div> </div>
<div class="col-12 col-lg-6"></div> <div class="col-12 col-lg-6"></div>
<div class="col-12 col-lg-6 o_setting_box" id="website_slides_install_mass_mailing_slides">
<div class="o_setting_left_pane">
<field name="module_mass_mailing_slides"/>
</div>
<div class="o_setting_right_pane">
<label for="module_mass_mailing_slides"/>
<div class="text-muted">
Contact all the members of a course via mass mailing
</div>
</div>
</div>
<div class="col-12 col-lg-6"></div>
<div class="col-12 col-lg-6 o_setting_box" id="elearning_install_certif"> <div class="col-12 col-lg-6 o_setting_box" id="elearning_install_certif">
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
<field name="module_website_slides_survey"/> <field name="module_website_slides_survey"/>
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo><data> <odoo><data>
<record id="res_partner_action_courses" model="ir.actions.act_window">
<field name="name">Followed Courses</field>
<field name="res_model">slide.channel</field>
<field name="view_mode">tree</field>
</record>
<record id="res_partner_view_form" model="ir.ui.view"> <record id="res_partner_view_form" model="ir.ui.view">
<field name="name">res.partner.view.form.inherit.slides</field> <field name="name">res.partner.view.form.inherit.slides</field>
<field name="model">res.partner</field> <field name="model">res.partner</field>
...@@ -16,20 +10,18 @@ ...@@ -16,20 +10,18 @@
<xpath expr="//div[@name='button_box']" position="inside"> <xpath expr="//div[@name='button_box']" position="inside">
<button class="oe_stat_button" type="object" <button class="oe_stat_button" type="object"
icon="fa-graduation-cap" name="action_view_courses" icon="fa-graduation-cap" name="action_view_courses"
attrs="{'invisible': ['|', ('slide_channels_count', '=', 0), ('is_company', '=', True)]}"> attrs="{'invisible': ['|', ('slide_channel_count', '=', 0), ('is_company', '=', True)]}">
<div class="o_field_widget o_stat_info"> <div class="o_field_widget o_stat_info">
<span class="o_stat_value"><field name="slide_channels_count" /></span> <span class="o_stat_value"><field name="slide_channel_count"/></span>
<span class="o_stat_text" attrs="{'invisible': [('slide_channels_count', '&lt;', 2)]}">Courses</span> <span class="o_stat_text">Courses</span>
<span class="o_stat_text" attrs="{'invisible': [('slide_channels_count', '&gt;', 1)]}">Course</span>
</div> </div>
</button> </button>
<button class="oe_stat_button" type="object" <button class="oe_stat_button" type="object"
icon="fa-graduation-cap" name="action_view_courses" icon="fa-graduation-cap" name="action_view_courses"
attrs="{'invisible': ['|', ('slide_channels_company_count', '=', 0), ('is_company', '=', False)]}"> attrs="{'invisible': ['|', ('slide_channel_company_count', '=', 0), ('is_company', '=', False)]}">
<div class="o_field_widget o_stat_info"> <div class="o_field_widget o_stat_info">
<span class="o_stat_value"><field name="slide_channels_company_count" /></span> <span class="o_stat_value"><field name="slide_channel_company_count" /></span>
<span class="o_stat_text" attrs="{'invisible': [('slide_channels_company_count', '&lt;', 2)]}">Courses</span> <span class="o_stat_text">Courses</span>
<span class="o_stat_text" attrs="{'invisible': [('slide_channels_company_count', '&gt;', 1)]}">Course</span>
</div> </div>
</button> </button>
</xpath> </xpath>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment