diff --git a/addons/event/__openerp__.py b/addons/event/__openerp__.py index 7ac32912056..6d82badeb0a 100644 --- a/addons/event/__openerp__.py +++ b/addons/event/__openerp__.py @@ -26,6 +26,7 @@ Key Features 'report/report_event_registration_view.xml', 'event_view.xml', 'event_data.xml', + 'event_tip_data.xml', 'res_config_view.xml', 'email_template.xml', 'views/event.xml', diff --git a/addons/event/email_template.xml b/addons/event/email_template.xml index e36256dbad6..26a9341b756 100644 --- a/addons/event/email_template.xml +++ b/addons/event/email_template.xml @@ -7,6 +7,7 @@ ${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe} ${object.email|safe} + ${object.event_id.reply_to|safe} Your subscription at ${object.event_id.name} Hello ${object.name},

We confirm that your subscription to the event ${object.event_id.name} has been recorded. @@ -20,6 +21,7 @@ You will automatically receive an email providing you more practical information ${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe} ${object.partner_id.email or object.email|safe} + ${object.event_id.reply_to|safe} Reminder of event ${object.event_id.name} Hello ${object.name},

This is a reminder for ${object.event_id.name} that you registered for is confirmed and will be held from ${object.event_id.date_begin_located} to ${object.event_id.date_end_located}. @@ -33,6 +35,7 @@ For any further information please contact our event department.

${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe} ${object.partner_id.email or object.email|safe} + ${object.event_id.reply_to|safe} Thanks for attending ${object.event_id.name} Hello ${object.name},

We would like to thank you for your presence at our event ${object.event_id.name}. diff --git a/addons/event/event.py b/addons/event/event.py index ec05901d4cd..8efd1eb2942 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -183,7 +183,7 @@ class event_event(models.Model): @api.one @api.constrains('seats_max', 'seats_available') def _check_seats_limit(self): - if self.seats_max and self.seats_available < 0: + if self.seats_availability == 'limited' and self.seats_max and self.seats_available < 0: raise UserError(_('No more available seats.')) @api.one @@ -283,7 +283,7 @@ class event_registration(models.Model): @api.one @api.constrains('event_id', 'state') def _check_seats_limit(self): - if self.event_id.seats_max and self.event_id.seats_available < (1 if self.state == 'draft' else 0): + if self.event_id.seats_availability == 'limited' and self.event_id.seats_max and self.event_id.seats_available < (1 if self.state == 'draft' else 0): raise UserError(_('No more seats available for this event.')) @api.multi @@ -292,7 +292,7 @@ class event_registration(models.Model): return False if any(registration.event_id.state != 'confirm' or not registration.event_id.auto_confirm or - not registration.event_id.seats_available for registration in self): + (not registration.event_id.seats_available and registration.event_id.seats_availability == 'limited') for registration in self): return False return True diff --git a/addons/event/event_mail.py b/addons/event/event_mail.py index 548e05aa2c4..565b40c8914 100644 --- a/addons/event/event_mail.py +++ b/addons/event/event_mail.py @@ -21,8 +21,9 @@ class EventMailScheduler(models.Model): that periodically checks for mailing to run. """ _name = 'event.mail' - event_id = fields.Many2one('event.event', string='Event', required=True, readonly=True, ondelete='cascade') - interval_nbr = fields.Integer('Timing', default=1) + event_id = fields.Many2one('event.event', string='Event', required=True, ondelete='cascade') + sequence = fields.Integer('Display order') + interval_nbr = fields.Integer('Interval', default=1) interval_unit = fields.Selection([ ('now', 'Immediately'), ('hours', 'Hour(s)'), ('days', 'Day(s)'), @@ -108,4 +109,7 @@ class EventMailRegistration(models.Model): @api.one @api.depends('registration_id', 'scheduler_id.interval_unit', 'scheduler_id.interval_type') def _compute_scheduled_date(self): - self.scheduled_date = datetime.strptime(self.registration_id.date_open, tools.DEFAULT_SERVER_DATETIME_FORMAT) + _INTERVALS[self.scheduler_id.interval_unit](self.scheduler_id.interval_nbr) + if self.registration_id: + self.scheduled_date = datetime.strptime(self.registration_id.date_open, tools.DEFAULT_SERVER_DATETIME_FORMAT) + _INTERVALS[self.scheduler_id.interval_unit](self.scheduler_id.interval_nbr) + else: + self.scheduled_date = False diff --git a/addons/event/event_tip_data.xml b/addons/event/event_tip_data.xml new file mode 100644 index 00000000000..f7c6a66064c --- /dev/null +++ b/addons/event/event_tip_data.xml @@ -0,0 +1,13 @@ + + + + + By clicking here, you can create and manage registration(s) for this event, send emails to attendee(s) and print identification badges. + + event.event + form + .oe_form_buttons_view:visible,div.oe_right.oe_button_box > button + div.oe_right.oe_button_box:visible > button:nth-child(1) + bottom + + diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml index 2f8a7ac3bf7..df7622a5845 100644 --- a/addons/event/event_view.xml +++ b/addons/event/event_view.xml @@ -102,11 +102,14 @@ - + + + + - + @@ -312,7 +315,7 @@ - + @@ -407,7 +410,7 @@ - + diff --git a/addons/event/report/report_event_registration.py b/addons/event/report/report_event_registration.py index f30ddbf5785..b0d9c82a0b6 100644 --- a/addons/event/report/report_event_registration.py +++ b/addons/event/report/report_event_registration.py @@ -33,6 +33,7 @@ class report_event_registration(models.Model): event_date = fields.Datetime('Event Date', readonly=True) event_id = fields.Many2one('event.event', 'Event', required=True) draft_state = fields.Integer(' # No of Draft Registrations') + cancel_state = fields.Integer(' # No of Cancelled Registrations') confirm_state = fields.Integer(' # No of Confirmed Registrations') seats_max = fields.Integer('Max Seats') nbevent = fields.Integer('Number of Events') @@ -62,6 +63,7 @@ class report_event_registration(models.Model): count(r.event_id) AS nbregistration, CASE WHEN r.state IN ('draft') THEN count(r.event_id) ELSE 0 END AS draft_state, CASE WHEN r.state IN ('open','done') THEN count(r.event_id) ELSE 0 END AS confirm_state, + CASE WHEN r.state IN ('cancel') THEN count(r.event_id) ELSE 0 END AS cancel_state, e.type AS event_type, e.seats_max AS seats_max, e.state AS event_state, diff --git a/addons/event/report/report_event_registration_view.xml b/addons/event/report/report_event_registration_view.xml index 16e9fbef562..454073671d2 100644 --- a/addons/event/report/report_event_registration_view.xml +++ b/addons/event/report/report_event_registration_view.xml @@ -7,7 +7,7 @@ report.event.registration - + @@ -19,7 +19,7 @@ report.event.registration - + diff --git a/addons/event/res_config.py b/addons/event/res_config.py index e2d8e5621ce..6686f495920 100644 --- a/addons/event/res_config.py +++ b/addons/event/res_config.py @@ -7,10 +7,10 @@ class event_config_settings(osv.TransientModel): _inherit='marketing.config.settings' _columns = { 'module_event_sale': fields.boolean( - 'Sale different type of ticket', + 'Sell events tickets', help='Install the event_sale module'), 'module_website_event_track': fields.boolean( - 'Organize few days event with track,full agenda,own menu in website'), + 'Organize few days event with track, full agenda, own menu in website'), 'auto_confirmation': fields.boolean( 'Automate events and subscription confirmation', help='Unselect this option to manually manage draft event and draft subscription'), } diff --git a/addons/event/static/src/css/event.css b/addons/event/static/src/css/event.css index 2d64b4f50b5..87e346d0ddf 100644 --- a/addons/event/static/src/css/event.css +++ b/addons/event/static/src/css/event.css @@ -5,9 +5,6 @@ /* End of customize */ cursor: default; } -.openerp .oe_kanban_view .oe_event_kanban_view .oe_event_fontend_link { - /*padding-top: 2px;*/ -} .openerp .oe_kanban_view .oe_event_kanban_view .oe_event_date_thumb { border-top-left-radius:3px; border-top-right-radius:3px; diff --git a/addons/event/tests/test_event_flow.py b/addons/event/tests/test_event_flow.py index ccddd11e00b..27b05333799 100644 --- a/addons/event/tests/test_event_flow.py +++ b/addons/event/tests/test_event_flow.py @@ -21,6 +21,7 @@ class TestEventFlow(TestEventCommon): 'date_begin': datetime.datetime.now() + relativedelta(days=-1), 'date_end': datetime.datetime.now() + relativedelta(days=1), 'seats_max': 2, + 'seats_availability': 'limited', }) self.assertEqual(test_event.state, 'confirm', 'Event: auto_confirmation of event failed') diff --git a/addons/event_sale/models/event.py b/addons/event_sale/models/event.py index 9f710fa0f07..47140340203 100644 --- a/addons/event_sale/models/event.py +++ b/addons/event_sale/models/event.py @@ -12,11 +12,6 @@ class event_event(models.Model): event_ticket_ids = fields.One2many( 'event.event.ticket', 'event_id', string='Event Ticket', default=lambda rec: rec._default_tickets(), copy=True) - seats_max = fields.Integer( - string='Maximum Available Seats', - help="The maximum registration level is equal to the sum of the maximum registration of event ticket. " + - "If you have too much registrations you are not able to confirm your event. (0 to ignore this rule )", - store=True, readonly=True, compute='_compute_seats_max') badge_back = fields.Html('Badge Back', translate=True, states={'done': [('readonly', True)]}) badge_innerleft = fields.Html('Badge Innner Left', translate=True, states={'done': [('readonly', True)]}) @@ -34,11 +29,6 @@ class event_event(models.Model): except ValueError: return self.env['event.event.ticket'] - @api.one - @api.depends('event_ticket_ids.seats_max') - def _compute_seats_max(self): - self.seats_max = sum(ticket.seats_max for ticket in self.event_ticket_ids) - class event_ticket(models.Model): _name = 'event.event.ticket' @@ -70,8 +60,11 @@ class event_ticket(models.Model): # be considered in the timezone of the event, not the timezone of the user! # Until we add a TZ on the event we'll use the context's current date, more accurate # than using UTC all the time. - current_date = fields.Date.context_today(self.with_context({'tz': self.event_id.date_tz})) - self.is_expired = self.deadline < current_date + if self.deadline: + current_date = fields.Date.context_today(self.with_context({'tz': self.event_id.date_tz})) + self.is_expired = self.deadline < current_date + else: + self.is_expired = False # FIXME non-stored fields wont ends up in _columns (and thus _all_columns), which forbid them # to be used in qweb views. Waiting a fix, we create an old function field directly. @@ -99,7 +92,12 @@ class event_ticket(models.Model): } # seats fields - seats_max = fields.Integer('Maximum Available Seats', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )") + seats_availability = fields.Selection( + [('limited', 'Limited'), ('unlimited', 'Unlimited')], + 'Available Seat', required=True, store=True, compute='_compute_seats', default="limited") + seats_max = fields.Integer('Maximum Available Seats', + help="Define the number of available tickets. If you have too much registrations you will" + "not BE able to sell tickets anymore. Set 0 to ignore this rule set as unlimited.") seats_reserved = fields.Integer(string='Reserved Seats', compute='_compute_seats', store=True) seats_available = fields.Integer(string='Available Seats', compute='_compute_seats', store=True) seats_unconfirmed = fields.Integer(string='Unconfirmed Seat Reservations', compute='_compute_seats', store=True) @@ -109,8 +107,9 @@ class event_ticket(models.Model): @api.depends('seats_max', 'registration_ids.state') def _compute_seats(self): """ Determine reserved, available, reserved but unconfirmed and used seats. """ - # initialize fields to 0 + # initialize fields to 0 + compute seats availability for ticket in self: + ticket.seats_availability = 'unlimited' if ticket.seats_max == 0 else 'limited' ticket.seats_unconfirmed = ticket.seats_reserved = ticket.seats_used = ticket.seats_available = 0 # aggregate registrations by ticket and by state if self.ids: diff --git a/addons/event_sale/views/event.xml b/addons/event_sale/views/event.xml index b63006f10bb..0d540463d49 100644 --- a/addons/event_sale/views/event.xml +++ b/addons/event_sale/views/event.xml @@ -43,49 +43,31 @@ - - view_event_form + + view_event_form_inherit_tichet event.event - - + + + + + + + + + + - + - - - - - - - - - - - - - view_event_form - event.event - - - - - - - - - - - - - - + + diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index 595aa9e4cd2..53bde6f2753 100644 --- a/addons/website_event/views/website_event.xml +++ b/addons/website_event/views/website_event.xml @@ -398,18 +398,18 @@ Free - + - Sold Out + Sold Out - - + + diff --git a/addons/website_event/views/website_event_backend.xml b/addons/website_event/views/website_event_backend.xml index e2f13da8258..a1300e5f607 100644 --- a/addons/website_event/views/website_event_backend.xml +++ b/addons/website_event/views/website_event_backend.xml @@ -21,18 +21,5 @@ - - event.event.kanban - event.event - - - - - event - - - - - diff --git a/addons/website_event_sale/__openerp__.py b/addons/website_event_sale/__openerp__.py index d259d0f6a99..9138955eb98 100644 --- a/addons/website_event_sale/__openerp__.py +++ b/addons/website_event_sale/__openerp__.py @@ -14,7 +14,6 @@ Online Event's Tickets 'author': 'OpenERP SA', 'depends': ['website_event', 'event_sale', 'website_sale'], 'data': [ - 'views/website_event_sale_backend.xml', 'views/website_event_sale.xml', 'security/ir.model.access.csv', 'security/website_event_sale.xml', diff --git a/addons/website_event_sale/views/website_event_sale.xml b/addons/website_event_sale/views/website_event_sale.xml index 0660b87dcb9..6cb91ae8443 100644 --- a/addons/website_event_sale/views/website_event_sale.xml +++ b/addons/website_event_sale/views/website_event_sale.xml @@ -11,15 +11,15 @@ -