Skip to content

Commit

Permalink
[WIP][ADD] reintroduced seat calculations, added security for new
Browse files Browse the repository at this point in the history
models, coverage increased
  • Loading branch information
ntsirintanis committed Jan 15, 2019
1 parent fabaf8c commit 2553aad
Show file tree
Hide file tree
Showing 12 changed files with 365 additions and 17 deletions.
1 change: 0 additions & 1 deletion event_session/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import models
from . import wizards
from . import tests
1 change: 0 additions & 1 deletion event_session/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import event
from . import event_session
from . import event_mail
Expand Down
74 changes: 73 additions & 1 deletion event_session/models/event.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Copyright 2017 David Vidal<david.vidal@tecnativa.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError


class EventEvent(models.Model):
Expand All @@ -17,13 +18,63 @@ class EventEvent(models.Model):
string='Total event sessions',
store=True,
)
seats_expected = fields.Integer(store=True)
seats_available_expected = fields.Integer(
compute='_compute_seats_available_expected',
string='Available expected seats',
readonly=True,
store=True,
)
draft_state = fields.Integer(
compute='_compute_state_numbers',
string=' # No of Draft Registrations',
store=True,
)
cancel_state = fields.Integer(
compute='_compute_state_numbers',
string=' # No of Cancelled Registrations',
store=True,
)
confirm_state = fields.Integer(
compute='_compute_state_numbers',
string=' # No of Confirmed Registrations',
store=True,
)

@api.multi
@api.depends('session_ids')
def _compute_sessions_count(self):
for event in self:
event.sessions_count = len(event.session_ids)

@api.multi
@api.constrains('seats_max', 'seats_available')
def _check_seats_limit(self):
for event in self:
if not event.session_ids:
return super(EventEvent, event)._check_seats_limit()

@api.multi
@api.depends('seats_max', 'seats_expected')
def _compute_seats_available_expected(self):
for this in self:
seats = this.seats_max - this.seats_expected
this.seats_available_expected = seats

@api.multi
@api.depends('registration_ids.state')
def _compute_state_numbers(self):
for this in self:
this.draft_state = len(this.registration_ids.filtered(
lambda x: x.state == 'draft'
))
this.cancel_state = len(this.registration_ids.filtered(
lambda x: x.state == 'cancel'
))
this.confirm_state = len(this.registration_ids.filtered(
lambda x: x.state == 'confirm'
))


class EventRegistration(models.Model):
_inherit = 'event.registration'
Expand All @@ -37,3 +88,24 @@ class EventRegistration(models.Model):
string='Session',
ondelete='restrict',
)

@api.multi
@api.constrains('event_id', 'session_id', 'state')
def _check_seats_limit(self):
for registration in self.filtered('session_id'):
if (registration.session_id.seats_availability == 'limited' and
registration.session_id.seats_available < 1 and
registration.state == 'open'):
raise ValidationError(
_('No more seats available for this event.'))

@api.multi
def confirm_registration(self):
for reg in self:
if not reg.event_id.session_ids:
super(EventRegistration, reg).confirm_registration()
reg.state = 'open'
onsubscribe_schedulers = \
reg.session_id.event_mail_ids.filtered(
lambda s: s.interval_type == 'after_sub')
onsubscribe_schedulers.execute()
3 changes: 1 addition & 2 deletions event_session/models/event_mail.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright 2017 David Vidal<david.vidal@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models
import logging
Expand Down
95 changes: 95 additions & 0 deletions event_session/models/event_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,42 @@ class EventSession(models.Model):
comodel_name='event.event',
string='Event',
)
seats_min = fields.Integer(
string='Minimum seats',
)
seats_max = fields.Integer(
string="Maximum seats",
)
seats_availability = fields.Selection(
[('limited', 'Limited'), ('unlimited', 'Unlimited')],
'Maximum Attendees', required=True, default='unlimited',
)
seats_reserved = fields.Integer(
string='Reserved Seats', store=True, readonly=True,
compute='_compute_seats',
)
seats_available = fields.Integer(
oldname='register_avail', string='Available Seats',
store=True, readonly=True, compute='_compute_seats')
seats_unconfirmed = fields.Integer(
oldname='register_prospect', string='Unconfirmed Seat Reservations',
store=True, readonly=True, compute='_compute_seats')
seats_used = fields.Integer(
oldname='register_attended', string='Number of Participants',
store=True, readonly=True, compute='_compute_seats')
seats_expected = fields.Integer(
string='Number of Expected Attendees',
readonly=True, compute='_compute_seats',
store=True)
seats_available_expected = fields.Integer(
string='Available Expected Seats',
readonly=True, compute='_compute_seats',
store=True)
seats_available_pc = fields.Float(
string='Full %',
readonly=True,
compute='_compute_seats',
)
date_tz = fields.Selection(
string='Timezone', related="event_id.date_tz",
)
Expand Down Expand Up @@ -110,13 +146,60 @@ def name_get(self):

@api.model
def create(self, vals):
# Config availabilities based on event
if vals.get('event_id', False):
event = self.env['event.event'].browse(vals.get('event_id'))
vals['seats_availability'] = event.seats_availability
vals['seats_max'] = event.seats_max
if not vals.get('event_mail_ids', False):
vals.update({
'event_mail_ids':
self._session_mails_from_template(vals['event_id'])
})
return super(EventSession, self).create(vals)

@api.multi
def unlink(self):
for this in self:
if this.registration_ids:
raise ValidationError(_("You are trying to delete one or more \
sessions with active registrations"))
return super(EventSession, self).unlink()

@api.multi
@api.depends('seats_max', 'registration_ids.state')
def _compute_seats(self):
"""Determine reserved, available, reserved but unconfirmed and used
seats by session.
"""
# aggregate registrations by event session and by state
if len(self.ids) > 0:
state_field = {
'draft': 'seats_unconfirmed',
'open': 'seats_reserved',
'done': 'seats_used',
}
result = self.env['event.registration'].read_group([
('session_id', 'in', self.ids),
('state', 'in', ['draft', 'open', 'done'])
], ['state', 'session_id'], ['session_id', 'state'], lazy=False)
for res in result:
session = self.browse(res['session_id'][0])
session[state_field[res['state']]] += res['__count']
# compute seats_available
for session in self:
if session.seats_max > 0:
session.seats_available = session.seats_max - (
session.seats_reserved + session.seats_used)
session.seats_expected = (
session.seats_unconfirmed + session.seats_reserved +
session.seats_used)
session.seats_available_expected = (
session.seats_max - session.seats_expected)
if session.seats_max > 0:
session.seats_available_pc = (
session.seats_expected * 100 / float(session.seats_max))

@api.multi
@api.depends('date_tz', 'date_begin')
def _compute_date_begin_located(self):
Expand Down Expand Up @@ -144,10 +227,22 @@ def _compute_date_end_located(self):
@api.onchange('event_id')
def onchange_event_id(self):
self.update({
'seats_min': self.event_id.seats_min,
'seats_max': self.event_id.seats_max,
'seats_availability': self.event_id.seats_availability,
'date_begin': self.event_id.date_begin,
'date_end': self.event_id.date_end,
})

@api.multi
@api.constrains('seats_max', 'seats_available')
def _check_seats_limit(self):
for session in self:
if (session.seats_availability == 'limited' and
session.seats_max and session.seats_available < 0):
raise ValidationError(
_('No more available seats for this session.'))

@api.multi
@api.constrains('date_begin', 'date_end')
def _check_dates(self):
Expand Down
5 changes: 2 additions & 3 deletions event_session/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Sergio Teruel <sergio.teruel@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# Copyright 2016 Sergio Teruel <sergio.teruel@tecnativa.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import api, fields, models

Expand Down
1 change: 1 addition & 0 deletions event_session/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_event_session_user,event.session.user,event_session.model_event_session,event.group_event_user,1,0,0,0
access_event_session_admin,event.session.admin,event_session.model_event_session,event.group_event_manager,1,1,1,1
access_event_mail_template,access_event_mail_template,model_event_mail_template,base.group_user,1,0,0,0
1 change: 0 additions & 1 deletion event_session/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import test_session
Loading

0 comments on commit 2553aad

Please sign in to comment.