summaryrefslogtreecommitdiff
path: root/addons/website_event
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2020-08-18 13:56:08 +0000
committerThibault Delavallée <tde@odoo.com>2020-08-21 17:30:13 +0000
commit77d7a3cf6a2cf07e18804a2d9b59e3697b11006e (patch)
tree435ca546a4b8eb5867dcd756e940b14e67513479 /addons/website_event
parent8da7288453d43ff6ccfd6cb6d8332eec998d3927 (diff)
[MOV] website_event(_track): move website event menu into website event
PURPOSE Clean organization and models linked to Event Online feature introduced in semi stable saas-13.3 at odoo/odoo@981f95bbf46658eda9f2d33751b9310cc67d86aa and odoo/enterprise@14722028ae0773c3710ea48ce48ff44703e83b5a Also clean website event menu not being available in website event but only in website event track, which implies some extra-code to manage it. In short: merge website_event_online in website_event, website_event_track _(online/session) in website_event_track. RATIONALE _online modules have been added to extend content of website_event and website_event_track without having any impact on those module. First step of cleaning is to move this content directly in base module. track_session module is mainly a rewrite of track module. Second step of cleaning is to move its content directly in website_event_track. SPECIFICATIONS Move website event menu model directly into website event. Website event menu model has been introduced to help dealing with event-specific menus and website menus. This is some kind of glue to synchronize both of them as people could either * update an event (website_menu, website_track) that updates website menus availability; * update menus through website that should update event field value and menu computation; Having a model introduced in website event track forces to have override and code split across website_event, website_event_track, and now also in both _online version of those two as menu management was improved. In this commit we simplify all this code by moving most of menu management code in website_event, leaving only business-specific code (fields and their menus) to sub modules. SPECIFICATIONS: WEBSITE EVENT MENU Make type required as we don't support entries without type. Indeed this model is used to automate menus generation / destruction, and not for hand-made menus. We therefore set type as required and add a cascade ondelete for selection. SPECIFCIATIONS: COMMUNITY MENU Doing this change allows to define community menu in website_event and re-use it in website_event_meet and website_event_track_quiz, removing some unnecessary dependencies. This menu is void in website_event, and displays either meeting rooms (in meet) or quiz points leaderboard (in quiz), or a mix of both if the two features are installed. LINKS Task ID-2319779 COM odoo/odoo#56067 ENT odoo/enterprise#12520 UPG odoo/upgrade#165
Diffstat (limited to 'addons/website_event')
-rw-r--r--addons/website_event/__manifest__.py2
-rw-r--r--addons/website_event/controllers/__init__.py1
-rw-r--r--addons/website_event/controllers/community.py13
-rw-r--r--addons/website_event/models/__init__.py2
-rw-r--r--addons/website_event/models/event_event.py99
-rw-r--r--addons/website_event/models/event_type.py11
-rw-r--r--addons/website_event/models/website_event_menu.py15
-rw-r--r--addons/website_event/models/website_menu.py29
-rw-r--r--addons/website_event/security/ir.model.access.csv2
-rw-r--r--addons/website_event/tests/test_event_internals.py2
-rw-r--r--addons/website_event/views/event_event_views.xml8
-rw-r--r--addons/website_event/views/event_menus.xml11
-rw-r--r--addons/website_event/views/event_type_views.xml3
-rw-r--r--addons/website_event/views/website_event_menu_views.xml51
14 files changed, 234 insertions, 15 deletions
diff --git a/addons/website_event/__manifest__.py b/addons/website_event/__manifest__.py
index 54df14666d4..41fb932b683 100644
--- a/addons/website_event/__manifest__.py
+++ b/addons/website_event/__manifest__.py
@@ -28,6 +28,8 @@
'views/website_templates.xml',
'views/event_event_views.xml',
'views/event_type_views.xml',
+ 'views/website_event_menu_views.xml',
+ 'views/event_menus.xml',
'security/ir.model.access.csv',
'security/event_security.xml',
],
diff --git a/addons/website_event/controllers/__init__.py b/addons/website_event/controllers/__init__.py
index 65a8c12013d..88cf7794fab 100644
--- a/addons/website_event/controllers/__init__.py
+++ b/addons/website_event/controllers/__init__.py
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from . import main
+from . import community
diff --git a/addons/website_event/controllers/community.py b/addons/website_event/controllers/community.py
new file mode 100644
index 00000000000..57a8cc4694d
--- /dev/null
+++ b/addons/website_event/controllers/community.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import http
+from odoo.http import request
+
+
+class EventCommunityController(http.Controller):
+
+ @http.route('/event/<model("event.event"):event>/community', type="http", auth="public", website=True)
+ def community(self, event, lang=None, **kwargs):
+ """ This skeleton route will be overriden in website_event_track_quiz, website_event_meet and website_event_meet_quiz. """
+ return request.render('website.page_404')
diff --git a/addons/website_event/models/__init__.py b/addons/website_event/models/__init__.py
index cf46b000f81..f49b644b04f 100644
--- a/addons/website_event/models/__init__.py
+++ b/addons/website_event/models/__init__.py
@@ -3,3 +3,5 @@
from . import event_event
from . import event_type
from . import website
+from . import website_event_menu
+from . import website_menu
diff --git a/addons/website_event/models/event_event.py b/addons/website_event/models/event_event.py
index e796b916705..7cf5f4e6b05 100644
--- a/addons/website_event/models/event_event.py
+++ b/addons/website_event/models/event_event.py
@@ -36,6 +36,13 @@ class Event(models.Model):
help="Creates menus Introduction, Location and Register on the page "
"of the event on the website.")
menu_id = fields.Many2one('website.menu', 'Event Menu', copy=False)
+ community_menu = fields.Boolean(
+ "Community Menu", compute="_compute_community_menu",
+ readonly=False, store=True,
+ help="Display community tab on website")
+ community_menu_ids = fields.One2many(
+ "website.event.menu", "event_id", string="Event Community Menus",
+ domain=[("menu_type", "=", "community")])
def _compute_is_participating(self):
# we don't allow public user to see participating label
@@ -47,13 +54,6 @@ class Event(models.Model):
else:
self.is_participating = False
- @api.depends('name')
- def _compute_website_url(self):
- super(Event, self)._compute_website_url()
- for event in self:
- if event.id: # avoid to perform a slug on a not yet saved record in case of an onchange.
- event.website_url = '/event/%s' % slug(event)
-
@api.depends('event_type_id')
def _compute_website_menu(self):
""" Also ensure a value for website_menu as it is a trigger notably for
@@ -64,6 +64,24 @@ class Event(models.Model):
elif not event.website_menu:
event.website_menu = False
+ @api.depends("event_type_id", "website_menu", "community_menu")
+ def _compute_community_menu(self):
+ """ At type onchange: synchronize. At website_menu update: synchronize. """
+ for event in self:
+ if event.event_type_id and event.event_type_id != event._origin.event_type_id:
+ event.community_menu = event.event_type_id.community_menu
+ elif event.website_menu and event.website_menu != event._origin.website_menu or not event.community_menu:
+ event.community_menu = True
+ elif not event.website_menu:
+ event.community_menu = False
+
+ @api.depends('name')
+ def _compute_website_url(self):
+ super(Event, self)._compute_website_url()
+ for event in self:
+ if event.id: # avoid to perform a slug on a not yet saved record in case of an onchange.
+ event.website_url = '/event/%s' % slug(event)
+
@api.model
def create(self, vals):
res = super(Event, self).create(vals)
@@ -91,7 +109,10 @@ class Event(models.Model):
:return list: list of fields, each of which triggering a menu update
like website_menu, website_track, ... """
- return ['website_menu']
+ return ['website_menu', 'community_menu']
+
+ def _get_menu_type_field_matching(self):
+ return {'community': 'community_menu'}
def _split_menus_state_by_field(self):
""" For each field linked to a menu, get the set of events having this
@@ -135,7 +156,7 @@ class Event(models.Model):
menus_update_by_field[fname] |= menus_state_by_field[fname]['deactivated'].filtered(lambda event: event[fname])
return menus_update_by_field
- def _get_menu_entries(self):
+ def _get_website_menu_entries(self):
""" Method returning menu entries to display on the website view of the
event, possibly depending on some options in inheriting modules.
@@ -143,14 +164,22 @@ class Event(models.Model):
* name: menu item name
* url: if set, url to a route (do not use xml_id in that case);
* xml_id: template linked to the page (do not use url in that case);
+ * sequence: specific sequence of menu entry to be set on the menu;
+ * menu_type: type of menu entry (used in inheriting modules to ease
+ menu management; not used in this module in 13.3 due to technical
+ limitations);
"""
self.ensure_one()
return [
- (_('Introduction'), False, 'website_event.template_intro'),
- (_('Location'), False, 'website_event.template_location'),
- (_('Register'), '/event/%s/register' % slug(self), False),
+ (_('Introduction'), False, 'website_event.template_intro', 1, False),
+ (_('Location'), False, 'website_event.template_location', 50, False),
+ (_('Register'), '/event/%s/register' % slug(self), False, 100, False),
]
+ def _get_community_menu_entries(self):
+ self.ensure_one()
+ return [(_('Community'), '/event/%s/community' % slug(self), False, 80, 'community')]
+
def _update_website_menus(self, menus_update_by_field=None):
""" Synchronize event configuration and its menu entries for frontend.
@@ -161,8 +190,44 @@ class Event(models.Model):
elif event.website_menu and not event.menu_id:
root_menu = self.env['website.menu'].sudo().create({'name': event.name, 'website_id': event.website_id.id})
event.menu_id = root_menu
- for sequence, (name, url, xml_id) in enumerate(event._get_menu_entries()):
- event._create_menu(sequence, name, url, xml_id)
+ if event.website_menu and (not menus_update_by_field or event in menus_update_by_field.get('website_menu')):
+ for name, url, xml_id, menu_sequence, menu_type in event._get_website_menu_entries():
+ event._create_menu(menu_sequence, name, url, xml_id, menu_type=menu_type)
+ if event.menu_id and (not menus_update_by_field or event in menus_update_by_field.get('community_menu')):
+ event._update_website_menu_entry('community_menu', 'community_menu_ids', '_get_community_menu_entries')
+
+ def _update_website_menu_entry(self, fname_bool, fname_o2m, method_name):
+ """ Generic method to create menu entries based on a flag on event. This
+ method is a bit obscure, but is due to preparation of adding new menus
+ entries and pages for event in a stable version, leading to some constraints
+ while developing.
+
+ :param fname_bool: field name (e.g. website_track)
+ :param fname_o2m: o2m linking towards website.event.menu matching the
+ boolean fields (normally an entry ot website.event.menu with type matching
+ the boolean field name)
+ :param method_name: method returning menu entries information: url, sequence, ...
+ """
+ self.ensure_one()
+ new_menu = None
+
+ if self[fname_bool] and not self[fname_o2m]:
+ # menus not found but boolean True: get menus to create
+ for sequence, menu_data in enumerate(getattr(self, method_name)()):
+ # some modules have 4 data: name, url, xml_id, menu_type; however we
+ # plan to support sequence in future modules, so this hackish code is
+ # necessary to avoid crashing. Not nice, but stable target = meh.
+ if len(menu_data) == 4:
+ (name, url, xml_id, menu_type) = menu_data
+ menu_sequence = sequence
+ elif len(menu_data) == 5:
+ (name, url, xml_id, menu_sequence, menu_type) = menu_data
+ new_menu = self._create_menu(menu_sequence, name, url, xml_id, menu_type=menu_type)
+ elif not self[fname_bool]:
+ # will cascade delete to the website.event.menu
+ self[fname_o2m].mapped('menu_id').sudo().unlink()
+
+ return new_menu
def _create_menu(self, sequence, name, url, xml_id, menu_type=False):
""" If url: create a website menu. Menu leads directly to the URL that
@@ -184,6 +249,12 @@ class Event(models.Model):
'sequence': sequence,
'website_id': self.website_id.id,
})
+ if menu_type:
+ self.env['website.event.menu'].create({
+ 'menu_id': website_menu.id,
+ 'event_id': self.id,
+ 'menu_type': menu_type,
+ })
return website_menu
# ------------------------------------------------------------
diff --git a/addons/website_event/models/event_type.py b/addons/website_event/models/event_type.py
index 6aee644c7d3..b89d3af9518 100644
--- a/addons/website_event/models/event_type.py
+++ b/addons/website_event/models/event_type.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo import fields, models
+from odoo import api, fields, models
class EventType(models.Model):
@@ -9,3 +9,12 @@ class EventType(models.Model):
_inherit = ['event.type']
website_menu = fields.Boolean('Display a dedicated menu on Website')
+ community_menu = fields.Boolean(
+ "Community Menu", compute="_compute_community_menu",
+ readonly=False, store=True,
+ help="Display community tab on website")
+
+ @api.depends('website_menu')
+ def _compute_community_menu(self):
+ for event_type in self:
+ event_type.community_menu = event_type.website_menu
diff --git a/addons/website_event/models/website_event_menu.py b/addons/website_event/models/website_event_menu.py
new file mode 100644
index 00000000000..b19c7d8ca75
--- /dev/null
+++ b/addons/website_event/models/website_event_menu.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+
+class EventMenu(models.Model):
+ _name = "website.event.menu"
+ _description = "Website Event Menu"
+
+ menu_id = fields.Many2one('website.menu', string='Menu', ondelete='cascade')
+ event_id = fields.Many2one('event.event', string='Event', ondelete='cascade')
+ menu_type = fields.Selection([
+ ('community', 'Community Menu')], string="Menu Type",
+ ondelete={'community': 'cascade'}, required=True)
diff --git a/addons/website_event/models/website_menu.py b/addons/website_event/models/website_menu.py
new file mode 100644
index 00000000000..1b96cd8552c
--- /dev/null
+++ b/addons/website_event/models/website_menu.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models
+
+
+class WebsiteMenu(models.Model):
+ _inherit = "website.menu"
+
+ def unlink(self):
+ """ Override to synchronize event configuration fields with menu deletion.
+ This should be cleaned in upcoming versions. """
+ event_updates = {}
+ website_event_menus = self.env['website.event.menu'].search([('menu_id', 'in', self.ids)])
+ for event_menu in website_event_menus:
+ to_update = event_updates.setdefault(event_menu.event_id, list())
+ for menu_type, fname in event_menu.event_id._get_menu_type_field_matching().items():
+ if event_menu.menu_type == menu_type:
+ to_update.append(fname)
+
+ # call super that resumes the unlink of menus entries (including website event menus)
+ res = super(WebsiteMenu, self).unlink()
+
+ # update events
+ for event, to_update in event_updates.items():
+ if to_update:
+ event.write(dict((fname, False) for fname in to_update))
+
+ return res
diff --git a/addons/website_event/security/ir.model.access.csv b/addons/website_event/security/ir.model.access.csv
index 985c14e5190..e865d4a1581 100644
--- a/addons/website_event/security/ir.model.access.csv
+++ b/addons/website_event/security/ir.model.access.csv
@@ -6,3 +6,5 @@ access_event_event_ticket_public,event.event.ticket.public,event.model_event_eve
access_event_event_ticket_portal,event.event.ticket.portal,event.model_event_event_ticket,base.group_portal,1,0,0,0
access_event_category_public,event.tag.category.public,event.model_event_tag_category,,1,0,0,0
access_event_tag_public,event.tag.public,event.model_event_tag,,1,0,0,0
+access_website_event_menu_public,website.event.menu,model_website_event_menu,,1,0,0,0
+access_website_event_menu_manager,website.event.menu,model_website_event_menu,event.group_event_manager,1,1,1,1
diff --git a/addons/website_event/tests/test_event_internals.py b/addons/website_event/tests/test_event_internals.py
index 9e99815fd67..9339da20e6a 100644
--- a/addons/website_event/tests/test_event_internals.py
+++ b/addons/website_event/tests/test_event_internals.py
@@ -17,6 +17,7 @@ class TestEventWebsite(TestWebsiteEventCommon):
'date_begin': fields.Datetime.to_string(datetime.today() + timedelta(days=1)),
'date_end': fields.Datetime.to_string(datetime.today() + timedelta(days=15)),
'website_menu': True,
+ 'community_menu': False,
})
self._assert_website_menus(event)
@@ -27,6 +28,7 @@ class TestEventWebsite(TestWebsiteEventCommon):
'date_begin': fields.Datetime.to_string(datetime.today() + timedelta(days=1)),
'date_end': fields.Datetime.to_string(datetime.today() + timedelta(days=15)),
'website_menu': True,
+ 'community_menu': False,
})
self.assertTrue(event.website_menu)
self._assert_website_menus(event)
diff --git a/addons/website_event/views/event_event_views.xml b/addons/website_event/views/event_event_views.xml
index 40b949e23bc..6b03966b5aa 100644
--- a/addons/website_event/views/event_event_views.xml
+++ b/addons/website_event/views/event_event_views.xml
@@ -19,6 +19,14 @@
type="object"
string="Preview Badges"/>
</xpath>
+ <xpath expr="//div[hasclass('oe_title')]" position="after">
+ <div name="event_menu_configuration" groups="base.group_no_one">
+ <label for="website_menu" string="Website Submenu"/>
+ <field name="website_menu"/>
+ <label for="community_menu" string="Community"/>
+ <field name="community_menu"/>
+ </div>
+ </xpath>
</field>
</record>
diff --git a/addons/website_event/views/event_menus.xml b/addons/website_event/views/event_menus.xml
new file mode 100644
index 00000000000..623a223679b
--- /dev/null
+++ b/addons/website_event/views/event_menus.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<odoo><data>
+
+ <menuitem id="menu_website_event_menu"
+ name="Website Menus"
+ action="website_event_menu_action"
+ parent="event.menu_event_configuration"
+ groups="base.group_no_one"
+ sequence="99"/>
+
+</data></odoo>
diff --git a/addons/website_event/views/event_type_views.xml b/addons/website_event/views/event_type_views.xml
index 8ace9ddc2d7..e35070a93ab 100644
--- a/addons/website_event/views/event_type_views.xml
+++ b/addons/website_event/views/event_type_views.xml
@@ -19,6 +19,9 @@
website: registrations, schedule, map, ...
</div>
</div>
+ <div id="community-menu" class="row mt16" groups="base.group_no_one" attrs="{'invisible': [('website_menu', '=', False)]}">
+ <label class="col-lg-4" for="community_menu"/> <field name="community_menu"/>
+ </div>
</div>
</div>
</div>
diff --git a/addons/website_event/views/website_event_menu_views.xml b/addons/website_event/views/website_event_menu_views.xml
new file mode 100644
index 00000000000..ff93dff1796
--- /dev/null
+++ b/addons/website_event/views/website_event_menu_views.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<odoo><data>
+
+ <record id="website_event_menu_view_search" model="ir.ui.view">
+ <field name="name">website.event.menu.view.search</field>
+ <field name="model">website.event.menu</field>
+ <field name="arch" type="xml">
+ <search string="Website Event Menus">
+ <field name="menu_id"/>
+ <field name="event_id"/>
+ <field name="menu_type"/>
+ </search>
+ </field>
+ </record>
+
+ <record id="website_event_menu_view_form" model="ir.ui.view">
+ <field name="name">website.event.menu.view.form</field>
+ <field name="model">website.event.menu</field>
+ <field name="arch" type="xml">
+ <form string="Website Event Menu">
+ <sheet>
+ <group>
+ <field name="menu_id"/>
+ <field name="event_id"/>
+ <field name="menu_type"/>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="website_event_menu_view_tree" model="ir.ui.view">
+ <field name="name">website.event.menu.view.tree</field>
+ <field name="model">website.event.menu</field>
+ <field name="arch" type="xml">
+ <tree string="Website Event Menus">
+ <field name="menu_id"/>
+ <field name="event_id"/>
+ <field name="menu_type"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="website_event_menu_action" model="ir.actions.act_window">
+ <field name="name">Menus</field>
+ <field name="res_model">website.event.menu</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+</data>
+</odoo>