summaryrefslogtreecommitdiff
path: root/addons/event/models
diff options
context:
space:
mode:
Diffstat (limited to 'addons/event/models')
-rw-r--r--addons/event/models/__init__.py3
-rw-r--r--addons/event/models/event_event.py (renamed from addons/event/models/event.py)198
-rw-r--r--addons/event/models/event_mail.py1
-rw-r--r--addons/event/models/event_registration.py202
-rw-r--r--addons/event/models/event_stage.py1
5 files changed, 207 insertions, 198 deletions
diff --git a/addons/event/models/__init__.py b/addons/event/models/__init__.py
index 750d7b5de79..727b34645d7 100644
--- a/addons/event/models/__init__.py
+++ b/addons/event/models/__init__.py
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from . import event
+from . import event_event
from . import event_mail
+from . import event_registration
from . import event_stage
from . import res_config_settings
from . import res_partner
diff --git a/addons/event/models/event.py b/addons/event/models/event_event.py
index d49b79d369a..4f366871155 100644
--- a/addons/event/models/event.py
+++ b/addons/event/models/event_event.py
@@ -1,16 +1,15 @@
# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import pytz
from odoo import _, api, fields, models
from odoo.tools import format_datetime
-from odoo.exceptions import AccessError, UserError, ValidationError
+from odoo.exceptions import ValidationError
from odoo.tools.translate import html_translate
from odoo.tools.misc import _format_time_ago
-from dateutil.relativedelta import relativedelta
-
_logger = logging.getLogger(__name__)
try:
@@ -395,196 +394,3 @@ class EventEvent(models.Model):
result[event.id] = cal.serialize().encode('utf-8')
return result
-
-
-class EventRegistration(models.Model):
- _name = 'event.registration'
- _description = 'Event Registration'
- _inherit = ['mail.thread', 'mail.activity.mixin']
- _order = 'id desc'
-
- # event
- origin = fields.Char(
- string='Source Document', readonly=True,
- help="Reference of the document that created the registration, for example a sales order")
- event_id = fields.Many2one(
- 'event.event', string='Event', required=True,
- readonly=True, states={'draft': [('readonly', False)]})
- # attendee
- partner_id = fields.Many2one(
- 'res.partner', string='Contact',
- states={'done': [('readonly', True)]})
- name = fields.Char(string='Attendee Name', index=True)
- email = fields.Char(string='Email')
- phone = fields.Char(string='Phone')
- mobile = fields.Char(string='Mobile')
- # organization
- date_open = fields.Datetime(string='Registration Date', readonly=True, default=lambda self: fields.Datetime.now()) # weird crash is directly now
- date_closed = fields.Datetime(string='Attended Date', readonly=True)
- event_begin_date = fields.Datetime(string="Event Start Date", related='event_id.date_begin', readonly=True)
- event_end_date = fields.Datetime(string="Event End Date", related='event_id.date_end', readonly=True)
- company_id = fields.Many2one(
- 'res.company', string='Company', related='event_id.company_id',
- store=True, readonly=True, states={'draft': [('readonly', False)]})
- state = fields.Selection([
- ('draft', 'Unconfirmed'), ('cancel', 'Cancelled'),
- ('open', 'Confirmed'), ('done', 'Attended')],
- string='Status', default='draft', readonly=True, copy=False, tracking=True)
-
- @api.constrains('event_id', 'state')
- def _check_seats_limit(self):
- for registration in self:
- if registration.event_id.seats_availability == 'limited' and registration.event_id.seats_max and registration.event_id.seats_available < (1 if registration.state == 'draft' else 0):
- raise ValidationError(_('No more seats available for this event.'))
-
- def _check_auto_confirmation(self):
- if self._context.get('registration_force_draft'):
- return False
- if any(not registration.event_id.auto_confirm or
- (not registration.event_id.seats_available and registration.event_id.seats_availability == 'limited') for registration in self):
- return False
- return True
-
- @api.model
- def create(self, vals):
- registration = super(EventRegistration, self).create(vals)
- if registration._check_auto_confirmation():
- registration.sudo().confirm_registration()
- return registration
-
- @api.model
- def _prepare_attendee_values(self, registration):
- """ Method preparing the values to create new attendees based on a
- sales order line. It takes some registration data (dict-based) that are
- optional values coming from an external input like a web page. This method
- is meant to be inherited in various addons that sell events. """
- partner_id = registration.pop('partner_id', self.env.user.partner_id)
- event_id = registration.pop('event_id', False)
- data = {
- 'name': registration.get('name', partner_id.name),
- 'phone': registration.get('phone', partner_id.phone),
- 'mobile': registration.get('mobile', partner_id.mobile),
- 'email': registration.get('email', partner_id.email),
- 'partner_id': partner_id.id,
- 'event_id': event_id and event_id.id or False,
- }
- data.update({key: value for key, value in registration.items() if key in self._fields})
- return data
-
- def do_draft(self):
- self.write({'state': 'draft'})
-
- def confirm_registration(self):
- self.write({'state': 'open'})
-
- # auto-trigger after_sub (on subscribe) mail schedulers, if needed
- onsubscribe_schedulers = self.event_id.event_mail_ids.filtered(
- lambda s: s.interval_type == 'after_sub')
- onsubscribe_schedulers.execute()
-
- def button_reg_close(self):
- """ Close Registration """
- for registration in self:
- registration.write({'state': 'done', 'date_closed': fields.Datetime.now()})
-
- def button_reg_cancel(self):
- self.write({'state': 'cancel'})
-
- @api.onchange('partner_id')
- def _onchange_partner(self):
- if self.partner_id:
- contact_id = self.partner_id.address_get().get('contact', False)
- if contact_id:
- contact = self.env['res.partner'].browse(contact_id)
- self.name = contact.name or self.name
- self.email = contact.email or self.email
- self.phone = contact.phone or self.phone
- self.mobile = contact.mobile or self.mobile
-
- def _message_get_suggested_recipients(self):
- recipients = super(EventRegistration, self)._message_get_suggested_recipients()
- public_users = self.env['res.users'].sudo()
- public_groups = self.env.ref("base.group_public", raise_if_not_found=False)
- if public_groups:
- public_users = public_groups.sudo().with_context(active_test=False).mapped("users")
- try:
- for attendee in self:
- is_public = attendee.sudo().with_context(active_test=False).partner_id.user_ids in public_users if public_users else False
- if attendee.partner_id and not is_public:
- attendee._message_add_suggested_recipient(recipients, partner=attendee.partner_id, reason=_('Customer'))
- elif attendee.email:
- attendee._message_add_suggested_recipient(recipients, email=attendee.email, reason=_('Customer Email'))
- except AccessError: # no read access rights -> ignore suggested recipients
- pass
- return recipients
-
- def _message_get_default_recipients(self):
- # Prioritize registration email over partner_id, which may be shared when a single
- # partner booked multiple seats
- return {r.id: {
- 'partner_ids': [],
- 'email_to': r.email,
- 'email_cc': False}
- for r in self}
-
- def _message_post_after_hook(self, message, msg_vals):
- if self.email and not self.partner_id:
- # we consider that posting a message with a specified recipient (not a follower, a specific one)
- # on a document without customer means that it was created through the chatter using
- # suggested recipients. This heuristic allows to avoid ugly hacks in JS.
- new_partner = message.partner_ids.filtered(lambda partner: partner.email == self.email)
- if new_partner:
- self.search([
- ('partner_id', '=', False),
- ('email', '=', new_partner.email),
- ('state', 'not in', ['cancel']),
- ]).write({'partner_id': new_partner.id})
- return super(EventRegistration, self)._message_post_after_hook(message, msg_vals)
-
- def action_send_badge_email(self):
- """ Open a window to compose an email, with the template - 'event_badge'
- message loaded by default
- """
- self.ensure_one()
- template = self.env.ref('event.event_registration_mail_template_badge')
- compose_form = self.env.ref('mail.email_compose_message_wizard_form')
- ctx = dict(
- default_model='event.registration',
- default_res_id=self.id,
- default_use_template=bool(template),
- default_template_id=template.id,
- default_composition_mode='comment',
- custom_layout="mail.mail_notification_light",
- )
- return {
- 'name': _('Compose Email'),
- 'type': 'ir.actions.act_window',
- 'view_mode': 'form',
- 'res_model': 'mail.compose.message',
- 'views': [(compose_form.id, 'form')],
- 'view_id': compose_form.id,
- 'target': 'new',
- 'context': ctx,
- }
-
- def get_date_range_str(self):
- self.ensure_one()
- today = fields.Datetime.now()
- event_date = self.event_begin_date
- diff = (event_date.date() - today.date())
- if diff.days <= 0:
- return _('today')
- elif diff.days == 1:
- return _('tomorrow')
- elif (diff.days < 7):
- return _('in %d days') % (diff.days, )
- elif (diff.days < 14):
- return _('next week')
- elif event_date.month == (today + relativedelta(months=+1)).month:
- return _('next month')
- else:
- return _('on ') + format_datetime(self.env, self.event_begin_date, tz=self.event_id.date_tz, dt_format='medium')
-
- def summary(self):
- self.ensure_one()
- return {'information': []}
diff --git a/addons/event/models/event_mail.py b/addons/event/models/event_mail.py
index fd53adbb0bc..4f2407609f9 100644
--- a/addons/event/models/event_mail.py
+++ b/addons/event/models/event_mail.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import datetime
from dateutil.relativedelta import relativedelta
diff --git a/addons/event/models/event_registration.py b/addons/event/models/event_registration.py
new file mode 100644
index 00000000000..8f940a2812e
--- /dev/null
+++ b/addons/event/models/event_registration.py
@@ -0,0 +1,202 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+
+from odoo import _, api, fields, models
+from odoo.tools import format_datetime
+from odoo.exceptions import AccessError, ValidationError
+
+from dateutil.relativedelta import relativedelta
+
+
+class EventRegistration(models.Model):
+ _name = 'event.registration'
+ _description = 'Event Registration'
+ _inherit = ['mail.thread', 'mail.activity.mixin']
+ _order = 'id desc'
+
+ # event
+ origin = fields.Char(
+ string='Source Document', readonly=True,
+ help="Reference of the document that created the registration, for example a sales order")
+ event_id = fields.Many2one(
+ 'event.event', string='Event', required=True,
+ readonly=True, states={'draft': [('readonly', False)]})
+ # attendee
+ partner_id = fields.Many2one(
+ 'res.partner', string='Contact',
+ states={'done': [('readonly', True)]})
+ name = fields.Char(string='Attendee Name', index=True)
+ email = fields.Char(string='Email')
+ phone = fields.Char(string='Phone')
+ mobile = fields.Char(string='Mobile')
+ # organization
+ date_open = fields.Datetime(string='Registration Date', readonly=True, default=lambda self: fields.Datetime.now()) # weird crash is directly now
+ date_closed = fields.Datetime(string='Attended Date', readonly=True)
+ event_begin_date = fields.Datetime(string="Event Start Date", related='event_id.date_begin', readonly=True)
+ event_end_date = fields.Datetime(string="Event End Date", related='event_id.date_end', readonly=True)
+ company_id = fields.Many2one(
+ 'res.company', string='Company', related='event_id.company_id',
+ store=True, readonly=True, states={'draft': [('readonly', False)]})
+ state = fields.Selection([
+ ('draft', 'Unconfirmed'), ('cancel', 'Cancelled'),
+ ('open', 'Confirmed'), ('done', 'Attended')],
+ string='Status', default='draft', readonly=True, copy=False, tracking=True)
+
+ @api.constrains('event_id', 'state')
+ def _check_seats_limit(self):
+ for registration in self:
+ if registration.event_id.seats_availability == 'limited' and registration.event_id.seats_max and registration.event_id.seats_available < (1 if registration.state == 'draft' else 0):
+ raise ValidationError(_('No more seats available for this event.'))
+
+ def _check_auto_confirmation(self):
+ if self._context.get('registration_force_draft'):
+ return False
+ if any(not registration.event_id.auto_confirm or
+ (not registration.event_id.seats_available and registration.event_id.seats_availability == 'limited') for registration in self):
+ return False
+ return True
+
+ @api.model
+ def create(self, vals):
+ registration = super(EventRegistration, self).create(vals)
+ if registration._check_auto_confirmation():
+ registration.sudo().confirm_registration()
+ return registration
+
+ @api.model
+ def _prepare_attendee_values(self, registration):
+ """ Method preparing the values to create new attendees based on a
+ sales order line. It takes some registration data (dict-based) that are
+ optional values coming from an external input like a web page. This method
+ is meant to be inherited in various addons that sell events. """
+ partner_id = registration.pop('partner_id', self.env.user.partner_id)
+ event_id = registration.pop('event_id', False)
+ data = {
+ 'name': registration.get('name', partner_id.name),
+ 'phone': registration.get('phone', partner_id.phone),
+ 'mobile': registration.get('mobile', partner_id.mobile),
+ 'email': registration.get('email', partner_id.email),
+ 'partner_id': partner_id.id,
+ 'event_id': event_id and event_id.id or False,
+ }
+ data.update({key: value for key, value in registration.items() if key in self._fields})
+ return data
+
+ def do_draft(self):
+ self.write({'state': 'draft'})
+
+ def confirm_registration(self):
+ self.write({'state': 'open'})
+
+ # auto-trigger after_sub (on subscribe) mail schedulers, if needed
+ onsubscribe_schedulers = self.event_id.event_mail_ids.filtered(
+ lambda s: s.interval_type == 'after_sub')
+ onsubscribe_schedulers.execute()
+
+ def button_reg_close(self):
+ """ Close Registration """
+ for registration in self:
+ registration.write({'state': 'done', 'date_closed': fields.Datetime.now()})
+
+ def button_reg_cancel(self):
+ self.write({'state': 'cancel'})
+
+ @api.onchange('partner_id')
+ def _onchange_partner(self):
+ if self.partner_id:
+ contact_id = self.partner_id.address_get().get('contact', False)
+ if contact_id:
+ contact = self.env['res.partner'].browse(contact_id)
+ self.name = contact.name or self.name
+ self.email = contact.email or self.email
+ self.phone = contact.phone or self.phone
+ self.mobile = contact.mobile or self.mobile
+
+ def _message_get_suggested_recipients(self):
+ recipients = super(EventRegistration, self)._message_get_suggested_recipients()
+ public_users = self.env['res.users'].sudo()
+ public_groups = self.env.ref("base.group_public", raise_if_not_found=False)
+ if public_groups:
+ public_users = public_groups.sudo().with_context(active_test=False).mapped("users")
+ try:
+ for attendee in self:
+ is_public = attendee.sudo().with_context(active_test=False).partner_id.user_ids in public_users if public_users else False
+ if attendee.partner_id and not is_public:
+ attendee._message_add_suggested_recipient(recipients, partner=attendee.partner_id, reason=_('Customer'))
+ elif attendee.email:
+ attendee._message_add_suggested_recipient(recipients, email=attendee.email, reason=_('Customer Email'))
+ except AccessError: # no read access rights -> ignore suggested recipients
+ pass
+ return recipients
+
+ def _message_get_default_recipients(self):
+ # Prioritize registration email over partner_id, which may be shared when a single
+ # partner booked multiple seats
+ return {r.id: {
+ 'partner_ids': [],
+ 'email_to': r.email,
+ 'email_cc': False}
+ for r in self}
+
+ def _message_post_after_hook(self, message, msg_vals):
+ if self.email and not self.partner_id:
+ # we consider that posting a message with a specified recipient (not a follower, a specific one)
+ # on a document without customer means that it was created through the chatter using
+ # suggested recipients. This heuristic allows to avoid ugly hacks in JS.
+ new_partner = message.partner_ids.filtered(lambda partner: partner.email == self.email)
+ if new_partner:
+ self.search([
+ ('partner_id', '=', False),
+ ('email', '=', new_partner.email),
+ ('state', 'not in', ['cancel']),
+ ]).write({'partner_id': new_partner.id})
+ return super(EventRegistration, self)._message_post_after_hook(message, msg_vals)
+
+ def action_send_badge_email(self):
+ """ Open a window to compose an email, with the template - 'event_badge'
+ message loaded by default
+ """
+ self.ensure_one()
+ template = self.env.ref('event.event_registration_mail_template_badge')
+ compose_form = self.env.ref('mail.email_compose_message_wizard_form')
+ ctx = dict(
+ default_model='event.registration',
+ default_res_id=self.id,
+ default_use_template=bool(template),
+ default_template_id=template.id,
+ default_composition_mode='comment',
+ custom_layout="mail.mail_notification_light",
+ )
+ return {
+ 'name': _('Compose Email'),
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'form',
+ 'res_model': 'mail.compose.message',
+ 'views': [(compose_form.id, 'form')],
+ 'view_id': compose_form.id,
+ 'target': 'new',
+ 'context': ctx,
+ }
+
+ def get_date_range_str(self):
+ self.ensure_one()
+ today = fields.Datetime.now()
+ event_date = self.event_begin_date
+ diff = (event_date.date() - today.date())
+ if diff.days <= 0:
+ return _('today')
+ elif diff.days == 1:
+ return _('tomorrow')
+ elif (diff.days < 7):
+ return _('in %d days') % (diff.days, )
+ elif (diff.days < 14):
+ return _('next week')
+ elif event_date.month == (today + relativedelta(months=+1)).month:
+ return _('next month')
+ else:
+ return _('on ') + format_datetime(self.env, self.event_begin_date, tz=self.event_id.date_tz, dt_format='medium')
+
+ def summary(self):
+ self.ensure_one()
+ return {'information': []}
diff --git a/addons/event/models/event_stage.py b/addons/event/models/event_stage.py
index d4064e3f9d4..e985df62c68 100644
--- a/addons/event/models/event_stage.py
+++ b/addons/event/models/event_stage.py
@@ -16,7 +16,6 @@ class EventStage(models.Model):
pipe_end = fields.Boolean(
string='End Stage', default=False,
help='Events will be automatically be moved into this stage their are passed and event moved in the stage will be automatically greened')
-
legend_blocked = fields.Char(
'Red Kanban Label', default=lambda s: _('Blocked'), translate=True, required=True,
help='Override the default value displayed for the blocked state for kanban selection.')