241 lines
11 KiB
Python
241 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from datetime import datetime, timedelta
|
|
from pytz import timezone, utc
|
|
|
|
from odoo import api, fields, models, _
|
|
from odoo.addons.http_routing.models.ir_http import slug
|
|
from odoo.addons.resource.models.utils import float_to_time
|
|
from odoo.tools import is_html_empty
|
|
from odoo.tools.translate import html_translate
|
|
|
|
|
|
class Sponsor(models.Model):
|
|
_name = "event.sponsor"
|
|
_description = 'Event Sponsor'
|
|
_order = "sequence, sponsor_type_id"
|
|
# _order = 'sponsor_type_id, sequence' TDE FIXME
|
|
_rec_name = 'name'
|
|
_inherit = [
|
|
'mail.thread',
|
|
'mail.activity.mixin',
|
|
'website.published.mixin',
|
|
'chat.room.mixin'
|
|
]
|
|
|
|
def _default_sponsor_type_id(self):
|
|
return self.env['event.sponsor.type'].search([], order="sequence desc", limit=1).id
|
|
|
|
event_id = fields.Many2one('event.event', 'Event', required=True)
|
|
sponsor_type_id = fields.Many2one(
|
|
'event.sponsor.type', 'Sponsorship Level',
|
|
default=lambda self: self._default_sponsor_type_id(), required=True, auto_join=True)
|
|
url = fields.Char('Sponsor Website', compute='_compute_url', readonly=False, store=True)
|
|
sequence = fields.Integer('Sequence')
|
|
active = fields.Boolean(default=True)
|
|
# description
|
|
subtitle = fields.Char('Slogan')
|
|
exhibitor_type = fields.Selection(
|
|
[('sponsor', 'Footer Logo Only'), ('exhibitor', 'Exhibitor'), ('online', 'Online Exhibitor')],
|
|
string="Sponsor Type", default="sponsor")
|
|
website_description = fields.Html(
|
|
'Description', compute='_compute_website_description',
|
|
sanitize_overridable=True,
|
|
sanitize_attributes=False, sanitize_form=True, translate=html_translate,
|
|
readonly=False, store=True)
|
|
# contact information
|
|
partner_id = fields.Many2one('res.partner', 'Partner', required=True, auto_join=True)
|
|
partner_name = fields.Char('Name', related='partner_id.name')
|
|
partner_email = fields.Char('Email', related='partner_id.email')
|
|
partner_phone = fields.Char('Phone', related='partner_id.phone')
|
|
partner_mobile = fields.Char('Mobile', related='partner_id.mobile')
|
|
name = fields.Char('Sponsor Name', compute='_compute_name', readonly=False, store=True)
|
|
email = fields.Char('Sponsor Email', compute='_compute_email', readonly=False, store=True)
|
|
phone = fields.Char('Sponsor Phone', compute='_compute_phone', readonly=False, store=True)
|
|
mobile = fields.Char('Sponsor Mobile', compute='_compute_mobile', readonly=False, store=True)
|
|
# image
|
|
image_512 = fields.Image(
|
|
string="Logo", max_width=512, max_height=512,
|
|
compute='_compute_image_512', readonly=False, store=True)
|
|
image_256 = fields.Image("Image 256", related="image_512", max_width=256, max_height=256, store=False)
|
|
image_128 = fields.Image("Image 128", related="image_512", max_width=128, max_height=128, store=False)
|
|
website_image_url = fields.Char(
|
|
string='Image URL',
|
|
compute='_compute_website_image_url', compute_sudo=True, store=False)
|
|
# live mode
|
|
hour_from = fields.Float('Opening hour', default=8.0)
|
|
hour_to = fields.Float('End hour', default=18.0)
|
|
event_date_tz = fields.Selection(string='Timezone', related='event_id.date_tz', readonly=True)
|
|
is_in_opening_hours = fields.Boolean(
|
|
'Within opening hours', compute='_compute_is_in_opening_hours')
|
|
# chat room
|
|
chat_room_id = fields.Many2one(readonly=False)
|
|
room_name = fields.Char(readonly=False)
|
|
# country information (related to ease frontend templates)
|
|
country_id = fields.Many2one(
|
|
'res.country', string='Country',
|
|
related='partner_id.country_id', readonly=True)
|
|
country_flag_url = fields.Char(
|
|
string='Country Flag',
|
|
compute='_compute_country_flag_url', compute_sudo=True)
|
|
|
|
@api.depends('partner_id')
|
|
def _compute_url(self):
|
|
for sponsor in self:
|
|
if sponsor.partner_id.website or not sponsor.url:
|
|
sponsor.url = sponsor.partner_id.website
|
|
|
|
@api.depends('partner_id')
|
|
def _compute_name(self):
|
|
self._synchronize_with_partner('name')
|
|
|
|
@api.depends('partner_id')
|
|
def _compute_email(self):
|
|
self._synchronize_with_partner('email')
|
|
|
|
@api.depends('partner_id')
|
|
def _compute_phone(self):
|
|
self._synchronize_with_partner('phone')
|
|
|
|
@api.depends('partner_id')
|
|
def _compute_mobile(self):
|
|
self._synchronize_with_partner('mobile')
|
|
|
|
@api.depends('partner_id')
|
|
def _compute_image_512(self):
|
|
self._synchronize_with_partner('image_512')
|
|
|
|
@api.depends('image_512', 'partner_id.image_256')
|
|
def _compute_website_image_url(self):
|
|
for sponsor in self:
|
|
if sponsor.image_512:
|
|
# image_512 is stored, image_256 is derived from it dynamically
|
|
sponsor.website_image_url = self.env['website'].image_url(sponsor, 'image_256', size=256)
|
|
elif sponsor.partner_id.image_256:
|
|
sponsor.website_image_url = self.env['website'].image_url(sponsor.partner_id, 'image_256', size=256)
|
|
else:
|
|
sponsor.website_image_url = 'website_event_exhibitor/static/src/img/event_sponsor_default_0.jpeg'
|
|
|
|
def _synchronize_with_partner(self, fname):
|
|
""" Synchronize with partner if not set. Setting a value does not write
|
|
on partner as this may be event-specific information. """
|
|
for sponsor in self:
|
|
if not sponsor[fname]:
|
|
sponsor[fname] = sponsor.partner_id[fname]
|
|
|
|
@api.onchange('exhibitor_type')
|
|
def _onchange_exhibitor_type(self):
|
|
""" Keep an explicit onchange to allow configuration of room names, even
|
|
if this field is normally a related on chat_room_id.name. It is not a real
|
|
computed field, an onchange used in form view is sufficient. """
|
|
for sponsor in self:
|
|
if sponsor.exhibitor_type == 'online' and not sponsor.room_name:
|
|
if sponsor.name:
|
|
room_name = "odoo-exhibitor-%s" % sponsor.name
|
|
else:
|
|
room_name = self.env['chat.room']._default_name(objname='exhibitor')
|
|
sponsor.room_name = self._jitsi_sanitize_name(room_name)
|
|
if sponsor.exhibitor_type == 'online' and not sponsor.room_max_capacity:
|
|
sponsor.room_max_capacity = '8'
|
|
|
|
@api.depends('partner_id')
|
|
def _compute_website_description(self):
|
|
for sponsor in self:
|
|
if is_html_empty(sponsor.website_description):
|
|
sponsor.website_description = sponsor.partner_id.website_description
|
|
|
|
@api.depends('event_id.is_ongoing', 'hour_from', 'hour_to', 'event_id.date_begin', 'event_id.date_end')
|
|
def _compute_is_in_opening_hours(self):
|
|
""" Opening hours: hour_from and hour_to are given within event TZ or UTC.
|
|
Now() must therefore be computed based on that TZ. """
|
|
for sponsor in self:
|
|
if not sponsor.event_id.is_ongoing:
|
|
sponsor.is_in_opening_hours = False
|
|
elif sponsor.hour_from is False or sponsor.hour_to is False:
|
|
sponsor.is_in_opening_hours = True
|
|
else:
|
|
event_tz = timezone(sponsor.event_id.date_tz)
|
|
# localize now, begin and end datetimes in event tz
|
|
dt_begin = sponsor.event_id.date_begin.astimezone(event_tz)
|
|
dt_end = sponsor.event_id.date_end.astimezone(event_tz)
|
|
now_utc = utc.localize(fields.Datetime.now().replace(microsecond=0))
|
|
now_tz = now_utc.astimezone(event_tz)
|
|
|
|
# compute opening hours
|
|
opening_from_tz = event_tz.localize(datetime.combine(now_tz.date(), float_to_time(sponsor.hour_from)))
|
|
opening_to_tz = event_tz.localize(datetime.combine(now_tz.date(), float_to_time(sponsor.hour_to)))
|
|
if sponsor.hour_to == 0:
|
|
# when closing 'at midnight', we consider it's at midnight the next day
|
|
opening_to_tz = opening_to_tz + timedelta(days=1)
|
|
|
|
opening_from = max([dt_begin, opening_from_tz])
|
|
opening_to = min([dt_end, opening_to_tz])
|
|
|
|
sponsor.is_in_opening_hours = opening_from <= now_tz < opening_to
|
|
|
|
@api.depends('partner_id.country_id.image_url')
|
|
def _compute_country_flag_url(self):
|
|
for sponsor in self:
|
|
if sponsor.partner_id.country_id:
|
|
sponsor.country_flag_url = sponsor.partner_id.country_id.image_url
|
|
else:
|
|
sponsor.country_flag_url = False
|
|
|
|
# ------------------------------------------------------------
|
|
# MIXINS
|
|
# ---------------------------------------------------------
|
|
|
|
@api.depends('name', 'event_id.name')
|
|
def _compute_website_url(self):
|
|
super(Sponsor, self)._compute_website_url()
|
|
for sponsor in self:
|
|
if sponsor.id: # avoid to perform a slug on a not yet saved record in case of an onchange.
|
|
base_url = sponsor.event_id.get_base_url()
|
|
sponsor.website_url = '%s/event/%s/exhibitor/%s' % (base_url, slug(sponsor.event_id), slug(sponsor))
|
|
|
|
# ------------------------------------------------------------
|
|
# CRUD
|
|
# ------------------------------------------------------------
|
|
|
|
@api.model_create_multi
|
|
def create(self, values_list):
|
|
for values in values_list:
|
|
if values.get('is_exhibitor') and not values.get('room_name'):
|
|
exhibitor_name = values['name'] if values.get('name') else self.env['res.partner'].browse(values['partner_id']).name
|
|
name = 'odoo-exhibitor-%s' % exhibitor_name or 'sponsor'
|
|
values['room_name'] = name
|
|
return super(Sponsor, self).create(values_list)
|
|
|
|
def write(self, values):
|
|
toupdate = self.env['event.sponsor']
|
|
if values.get('is_exhibitor') and not values.get('chat_room_id') and not values.get('room_name'):
|
|
toupdate = self.filtered(lambda exhibitor: not exhibitor.chat_room_id)
|
|
# go into sequential update in order to create a custom room name for each sponsor
|
|
for exhibitor in toupdate:
|
|
values['room_name'] = 'odoo-exhibitor-%s' % exhibitor.name
|
|
super(Sponsor, exhibitor).write(values)
|
|
return super(Sponsor, self - toupdate).write(values)
|
|
|
|
# ------------------------------------------------------------
|
|
# ACTIONS
|
|
# ---------------------------------------------------------
|
|
|
|
def get_backend_menu_id(self):
|
|
return self.env.ref('event.event_main_menu').id
|
|
|
|
# ------------------------------------------------------------
|
|
# MESSAGING
|
|
# ------------------------------------------------------------
|
|
|
|
def _message_get_suggested_recipients(self):
|
|
recipients = super(Sponsor, self)._message_get_suggested_recipients()
|
|
for sponsor in self:
|
|
if sponsor.partner_id:
|
|
sponsor._message_add_suggested_recipient(
|
|
recipients,
|
|
partner=sponsor.partner_id,
|
|
reason=_('Sponsor')
|
|
)
|
|
return recipients
|