diff options
| author | Mahendra Barad <mba@openerp.com> | 2015-01-29 15:32:43 +0100 |
|---|---|---|
| committer | Thibault Delavallée <tde@openerp.com> | 2015-01-29 17:39:41 +0100 |
| commit | d9fa702d5e6183bfe57c3de9cab869dc3fa79718 (patch) | |
| tree | 92eec376839edd3ed634306e3836e547e247636e | |
| parent | 5d53fbc8336ed1f13b999cc7b3699349ead818c9 (diff) | |
[IMP] event and event_* modules: onboarding improvements
event:
- added tip
- default subscription/reminder/thanks templates for registrations are now using
the reply_to defined on the event
- fixed check of available seats: use seats_availability field, unlimited events
should never trigger the constraint
- added a sequence on scheduled emails on events
- config: wording improvements
- various improvements in event, registration, event_mail and event_report views
event_sale:
- removed override of seats_max: should not depend on available seats in
tickets. Indeed you may have less available places than the sum of seats for
each ticket type, for example if you have 0-10 VIP and 0-20 Standard tickets
for a 20-seats event.
- removed a duplicated view override
- added a seats_availability field on tickets, same meaning as on event.
- improved event form view: registration tab is now replaced by the tickets tab
when tickets are used
website_event:
- better management of sold-out event in the front-end, when doing registrations
website_event_sale:
- removed register link on the event kanban view. There is no need to to from
the back-end to the front-end from the kanban view. The published button on the
event form view already allows to go to the front-end view on the event
- better management of sold-out event in the front-end, when doing registrations
- fixed a template that was in customize and should not
website_event_track:
- wording improvements
- small improvements in the front-end of tracks
20 files changed, 85 insertions, 118 deletions
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 @@ <field name="model_id" ref="event.model_event_registration"/> <field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field> <field name="email_to" >${object.email|safe}</field> + <field name="reply_to">${object.event_id.reply_to|safe}</field> <field name="subject">Your subscription at ${object.event_id.name}</field> <field name="body_html">< + 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<odoo> + <record model="web.tip" id="event_tip_1"> + <field name="title"></field> + <field name="description">By clicking here, you can create and manage registration(s) for this event, send emails to attendee(s) and print identification badges.</field> + <field name="action_id" ref="event.action_event_view"/> + <field name="model">event.event</field> + <field name="mode">form</field> + <field name="trigger_selector">.oe_form_buttons_view:visible,div.oe_right.oe_button_box > button</field> + <field name="highlight_selector">div.oe_right.oe_button_box:visible > button:nth-child(1)</field> + <field name="placement">bottom</field> + </record> +</odoo> 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 @@ </group> </page> <page string="Email Schedule"> - <field name="reply_to"/> + <group> + <field name="reply_to"/> + </group> <field name="event_mail_ids"> <tree string="Email Schedule" editable="bottom"> + <field name="sequence" widget="handle"/> <field name="template_id" /> - <field name="interval_nbr"/> + <field name="interval_nbr" attrs="{'readonly':[('interval_unit','=','now')]}"/> <field name="interval_unit"/> <field name="interval_type"/> <field name="done"/> @@ -312,7 +315,7 @@ <field name="partner_id" attrs="{'readonly':[('state', '!=', 'draft')]}"/> </group> <group string="Event Information" name="event"> - <field name="event_id" readonly="1"/> + <field name="event_id" attrs="{'readonly': [('state', '!=', 'draft')]}"/> <field name="date_open" groups="base.group_no_one"/> <field name="date_closed" groups="base.group_no_one"/> </group> @@ -407,7 +410,7 @@ <field name="mail_sent"/> </group> <group> - <field name="interval_nbr"/> + <field name="interval_nbr" attrs="{'readonly':[('interval_unit', '=', 'now')]}"/> <field name="interval_unit"/> <field name="interval_type"/> <field name="scheduled_date"/> 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 @@ <field name="model">report.event.registration</field> <field name="arch" type="xml"> <pivot string="Event on Registration" disable_linking="True"> - <field name="event_type" type="row"/> + <field name="event_id" type="row"/> <field name="event_date" interval="month" type="col"/> <field name="confirm_state" type="measure"/> </pivot> @@ -19,7 +19,7 @@ <field name="model">report.event.registration</field> <field name="arch" type="xml"> <graph string="Event on Registration"> - <field name="event_type"/> + <field name="event_id"/> <field name="event_date" interval="month"/> <field name="confirm_state" type="measure"/> </graph> 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 @@ </field> </record> - <record id="view_event_form" model="ir.ui.view"> - <field name="name">view_event_form</field> + <record model="ir.ui.view" id="view_event_form_inherit_ticket"> + <field name="name">view_event_form_inherit_tichet</field> <field name="model">event.event</field> <field name="inherit_id" ref="event.view_event_form"/> <field name="arch" type="xml"> <data> - <xpath expr="//page[@string='Registrations']" position="after"> - <page string="Ticket Types"> + <xpath expr="//page[@string='Registrations']" position="replace"> + <page string="Tickets"> + <group> + <group> + <field name="auto_confirm" invisible="1"/> + <field name="seats_min" attrs="{'invisible':[('auto_confirm','=', True)]}"/> + <field name="seats_availability" widget='radio'/> + <field name="seats_max" attrs="{'invisible':[('seats_availability','=','unlimited')]}"/> + </group> + </group> <field name="event_ticket_ids" context="{'default_name': name}"> - <tree string="Payments" editable="bottom"> + <tree string="Tickets" editable="bottom"> <field name="name"/> <field name="product_id"/> <field name="deadline"/> <field name="price"/> <field name="seats_max"/> - <field name="seats_reserved"/> - <field name="seats_unconfirmed"/> - </tree> - </field> - </page> - </xpath> - </data> - </field> - </record> - - <!-- Edit badge report form --> - <record id="view_event_form" model="ir.ui.view"> - <field name="name">view_event_form</field> - <field name="model">event.event</field> - <field name="inherit_id" ref="event.view_event_form"/> - <field name="arch" type="xml"> - <data> - <xpath expr="//notebook" position="inside"> - <page string="Ticket Types"> - <field name="event_ticket_ids" context="{'default_name': name}"> - <tree string="Payments" editable="bottom"> - <field name="name"/> - <field name="product_id"/> - <field name="deadline"/> - <field name="price"/> - <field name="seats_max"/> - <field name="seats_reserved"/> - <field name="seats_unconfirmed"/> + <field name="seats_reserved" readonly="1"/> + <field name="seats_unconfirmed" readonly="1"/> </tree> </field> </page> 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 @@ <td>Free</td> <td></td> <td> - <select t-if="event.seats_available" name="nb_register-0" class="form-control"> - <t t-foreach="range(0, event.seats_available > 9 and 10 or event.seats_available+1)" t-as="nb"> + <select t-if="event.seats_available or event.seats_availability == 'unlimited'" name="nb_register-0" class="form-control"> + <t t-foreach="range(0, (event.seats_availability == 'unlimited' or event.seats_available > 9) and 10 or event.seats_available+1)" t-as="nb"> <option t-esc="nb"/> </t> </select> - <span t-if="not event.seats_available">Sold Out</span> + <span t-if="event.seats_availability == 'limited' and not event.seats_available">Sold Out</span> </td> </tr> </tbody> </table> - <t t-if="event.seats_available"> - <button type="submit" t-if="event.seats_available" class="btn btn-primary btn-lg pull-right a-submit" t-attf-id="#{event.id}">Register Now</button> + <t t-if="event.seats_availability == 'unlimited' or event.seats_available"> + <button type="submit" class="btn btn-primary btn-lg pull-right a-submit" t-attf-id="#{event.id}">Register Now</button> </t> </form> </template> 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 @@ </field> </record> - <record model="ir.ui.view" id="view_event_kanban"> - <field name="name">event.event.kanban</field> - <field name="model">event.event</field> - <field name="inherit_id" ref="event.view_event_kanban"/> - <field name="arch" type="xml"> - <data> - <xpath expr="//t[@t-name='kanban-box']/div" position="attributes"> - <attribute name="data-routing">event</attribute> - </xpath> - </data> - </field> - </record> - </data> </openerp> 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 @@ <template id="index" inherit_id="website_event.index" name="Event's Ticket"> <xpath expr="//li[@t-foreach='event_ids']/div/h4" position="before"> <t t-if="event.state in ['draft', 'confirm'] and event.event_ticket_ids"> - <span t-if="not event.seats_available" class="label label-danger pull-right">Sold Out</span> - <span t-if="event.seats_available and event.seats_available <= ((event.seats_max or 0) / 4)" class="label pull-right label-info"> + <span t-if="event.seats_availability == 'limited' and not event.seats_available" class="label label-danger pull-right">Sold Out</span> + <span t-if="event.seats_availability == 'limited' and event.seats_available and event.seats_available <= ((event.seats_max or 0) / 4)" class="label pull-right label-info"> Only <t t-esc="event.seats_available"/> Remaining </span> </t> </xpath> </template> -<template id="registration_template" inherit_id="website_event.registration_template" customize_show="True" name="Event's Ticket form"> +<template id="registration_template" inherit_id="website_event.registration_template"> <xpath expr="//tbody" position="replace"> <tbody> <t t-foreach="event.event_ticket_ids" t-as="ticket"> @@ -62,19 +62,19 @@ </span> </td> <td> - <select t-if="ticket.seats_available" t-attf-name="nb_register-#{ticket.id}" class="form-control"> - <t t-foreach="range(0, ticket.seats_available > 9 and 10 or ticket.seats_available+1 )" t-as="nb"> + <select t-if="ticket.seats_available or ticket.seats_availability == 'unlimited'" t-attf-name="nb_register-#{ticket.id}" class="form-control"> + <t t-foreach="range(0, (ticket.seats_availability == 'unlimited' or ticket.seats_available > 9) and 10 or ticket.seats_available + 1)" t-as="nb"> <option t-esc="nb"/> </t> </select> - <span t-if="not ticket.seats_available">Sold Out</span> + <span t-if="ticket.seats_availability == 'limited' and not ticket.seats_available">Sold Out</span> </td> </tr> </t> </tbody> </xpath> <xpath expr="//button[@type='submit']" position="replace"> - <button type="submit" t-if="event.seats_available" class="btn btn-primary btn-lg pull-right a-submit" t-attf-id="#{event.id}">Order Now</button> + <button type="submit" t-if="event.seats_available or event.seats_availability == 'unlimited'" class="btn btn-primary btn-lg pull-right a-submit" t-attf-id="#{event.id}">Order Now</button> <form t-if="not event.event_ticket_ids"> <div class="alert alert-info"> Event registration not yet started. diff --git a/addons/website_event_sale/views/website_event_sale_backend.xml b/addons/website_event_sale/views/website_event_sale_backend.xml deleted file mode 100644 index da0b5b80f9c..00000000000 --- a/addons/website_event_sale/views/website_event_sale_backend.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<openerp> -<data> - - <record model="ir.ui.view" id="view_event_kanban"> - <field name="name">event.event.kanban</field> - <field name="model">event.event</field> - <field name="inherit_id" ref="event.view_event_kanban"/> - <field name="arch" type="xml"> - <data> - <xpath expr="//templates" position="before"> - <field name="website_url"/> - </xpath> - <xpath expr="//h4[last()]" position="after"> - <div class="oe_event_fontend_link"> - <a t-attf-href="#{record.website_url.raw_value}/register" type="url">Register</a> - </div> - </xpath> - </data> - </field> - </record> - - </data> -</openerp> diff --git a/addons/website_event_track/models/event.py b/addons/website_event_track/models/event.py index 06ba59e5444..cac8a1edc38 100644 --- a/addons/website_event_track/models/event.py +++ b/addons/website_event_track/models/event.py @@ -23,7 +23,7 @@ class event_track_location(models.Model): class event_track(models.Model): _name = "event.track" - _description = 'Event Tracks' + _description = 'Event Track' _order = 'priority, date' _inherit = ['mail.thread', 'ir.needaction_mixin', 'website.seo.metadata', 'website.published.mixin'] @@ -38,7 +38,7 @@ class event_track(models.Model): description = fields.Html('Track Description', translate=True) date = fields.Datetime('Track Date') duration = fields.Float('Duration', digits=(16, 2), default=1.5) - location_id = fields.Many2one('event.track.location', 'Location') + location_id = fields.Many2one('event.track.location', 'Room') event_id = fields.Many2one('event.event', 'Event', required=True) color = fields.Integer('Color Index') priority = fields.Selection([ diff --git a/addons/website_event_track/views/website_event.xml b/addons/website_event_track/views/website_event.xml index 3e866329aa0..b3f7f20d684 100644 --- a/addons/website_event_track/views/website_event.xml +++ b/addons/website_event_track/views/website_event.xml @@ -133,7 +133,7 @@ <li t-if="track.speaker_ids" class="text-muted fa fa-user"> <t t-esc="', '.join([speaker.name for speaker in track.speaker_ids])"></t> </li> - <li class="text-muted fa fa-calendar"> <span t-field="track.date" t-field-options='{"hide_seconds":"True"}'/></li> + <li t-if="track.date" class="text-muted fa fa-calendar"> <span t-field="track.date" t-field-options='{"hide_seconds":"True"}'/></li> <li class="text-muted fa fa-map-marker" t-if="track.location_id"> <span t-field="track.location_id"/> </li> @@ -145,7 +145,7 @@ </a> </li> </ul> - <p class="mt8"><t t-esc="html2text(track.description or '')[0:500]"/>...</p> + <p class="mt8"><t t-esc="html2text(track.description or '')[0:500]"/><t t-if="track.description">...</t></p> </div> </div> </div> |
