diff options
| author | Paramjit Singh Sahota <psa@openerp.com> | 2014-07-16 14:38:10 +0530 |
|---|---|---|
| committer | Thibault Delavallée <tde@openerp.com> | 2014-10-09 10:09:06 +0200 |
| commit | ca862e7b852996cb44c444b5725beca8a5d8ae65 (patch) | |
| tree | 57f6aa7f5de2da399c3469c14220e236d84d5453 /addons/event | |
| parent | b7eb97c39ebd7b667e1691eeea72f716fa11b420 (diff) | |
[IMP] event: Split Ticket: registration are now for one attendee only.
Registration are now for one attendee only. When buying several seats for an event
you have now one registration for each attendee.
event: nb_register field is removed; as well as unnecessary user_id and it subscribe /
unsubscribe behavior. Also slighly cleaned some views.
event_sale: do not auto confirm registrations linked to a draft sale order. Note: strange
origin is a char field, not a sale_order_id. Added a small wizard to edit attendees
data when confirming a sale order containing event related lines.
website_event: when buying free tickets, ask for attendee details. Added template,
controllers to handle that behavior.
website_event_sale: when buying tickets, ask for attendee details. Events ecommerce
should be better integrated with online events, using inheritance to add details
instead of being very different.
Diffstat (limited to 'addons/event')
| -rw-r--r-- | addons/event/__openerp__.py | 2 | ||||
| -rw-r--r-- | addons/event/event.py | 67 | ||||
| -rw-r--r-- | addons/event/event_demo.xml | 3 | ||||
| -rw-r--r-- | addons/event/event_report.xml | 30 | ||||
| -rw-r--r-- | addons/event/event_view.xml | 46 | ||||
| -rw-r--r-- | addons/event/report/report_event_registration.py | 12 | ||||
| -rw-r--r-- | addons/event/tests/test_event_flow.py | 14 | ||||
| -rw-r--r-- | addons/event/views/report_registrationbadge.xml | 39 |
8 files changed, 113 insertions, 100 deletions
diff --git a/addons/event/__openerp__.py b/addons/event/__openerp__.py index b98f9d4e5ae..f6336e72c34 100644 --- a/addons/event/__openerp__.py +++ b/addons/event/__openerp__.py @@ -29,6 +29,8 @@ Key Features 'res_config_view.xml', 'email_template.xml', 'views/event.xml', + 'event_report.xml', + 'views/report_registrationbadge.xml', ], 'demo': [ 'event_demo.xml', diff --git a/addons/event/event.py b/addons/event/event.py index 322d7d6bcca..454454b0f9a 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -81,7 +81,7 @@ class event_event(models.Model): store=True, readonly=True, compute='_compute_seats') @api.multi - @api.depends('seats_max', 'registration_ids.state', 'registration_ids.nb_register') + @api.depends('seats_max', 'registration_ids.state') def _compute_seats(self): """ Determine reserved, available, reserved but unconfirmed and used seats. """ # initialize fields to 0 @@ -94,7 +94,7 @@ class event_event(models.Model): 'open': 'seats_reserved', 'done': 'seats_used', } - query = """ SELECT event_id, state, sum(nb_register) + query = """ SELECT event_id, state, count(event_id) FROM event_registration WHERE event_id IN %s AND state IN ('draft', 'open', 'done') GROUP BY event_id, state @@ -110,7 +110,7 @@ class event_event(models.Model): # Registration fields registration_ids = fields.One2many( - 'event.registration', 'event_id', string='Registrations', + 'event.registration', 'event_id', string='Attendees', readonly=False, states={'done': [('readonly', True)]}) count_registrations = fields.Integer(string='Registrations', compute='_count_registrations') @@ -245,36 +245,6 @@ class event_event(models.Model): """ Confirm Event and send confirmation email to all register peoples """ self.confirm_event() - @api.one - def subscribe_to_event(self): - """ Subscribe the current user to a given event """ - user = self.env.user - num_of_seats = int(self._context.get('ticket', 1)) - regs = self.registration_ids.filtered(lambda reg: reg.user_id == user) - # the subscription is done as SUPERUSER_ID because in case we share the - # kanban view, we want anyone to be able to subscribe - if not regs: - regs = regs.sudo().create({ - 'event_id': self.id, - 'email': user.email, - 'name': user.name, - 'user_id': user.id, - 'nb_register': num_of_seats, - }) - else: - regs.write({'nb_register': num_of_seats}) - if regs._check_auto_confirmation(): - regs.sudo().confirm_registration() - - @api.one - def unsubscribe_to_event(self): - """ Unsubscribe the current user from a given event """ - # the unsubscription is done as SUPERUSER_ID because in case we share - # the kanban view, we want anyone to be able to unsubscribe - user = self.env.user - regs = self.sudo().registration_ids.filtered(lambda reg: reg.user_id == user) - regs.button_reg_cancel() - @api.onchange('type') def _onchange_type(self): if self.type: @@ -289,35 +259,31 @@ class event_event(models.Model): res = self.env['ir.actions.act_window'].for_xml_id('event', 'action_report_event_registration') res['context'] = { "search_default_event_id": self.id, - "group_by": ['event_date:day'], + "group_by": ['create_date:day'], } return res class event_registration(models.Model): _name = 'event.registration' - _description = 'Event Registration' + _description = 'Attendee' _inherit = ['mail.thread', 'ir.needaction_mixin'] _order = 'name, create_date desc' origin = fields.Char( string='Source Document', readonly=True, - help="Reference of the sales order which created the registration") # funny we refer sale orders... event is not sale related - nb_register = fields.Integer( - string='Number of Participants', required=True, default=1, - readonly=True, states={'draft': [('readonly', False)]}) + help="Reference of the document that created the registration, for example a sale order") event_id = fields.Many2one( 'event.event', string='Event', required=True, readonly=True, states={'draft': [('readonly', False)]}) partner_id = fields.Many2one( - 'res.partner', string='Partner', + 'res.partner', string='Contact', states={'done': [('readonly', True)]}) date_open = fields.Datetime(string='Registration Date', readonly=True) date_closed = fields.Datetime(string='Attended Date', readonly=True) reply_to = fields.Char(string='Reply-to Email', related='event_id.reply_to', 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) - user_id = fields.Many2one('res.users', string='User', states={'done': [('readonly', True)]}) company_id = fields.Many2one( 'res.company', string='Company', related='event_id.company_id', store=True, readonly=True, states={'draft': [('readonly', False)]}) @@ -327,17 +293,18 @@ class event_registration(models.Model): string='Status', default='draft', readonly=True, copy=False, track_visibility='onchange') email = fields.Char(string='Email') phone = fields.Char(string='Phone') - name = fields.Char(string='Name', select=True) + name = fields.Char(string='Attendee Name', select=True) @api.one - @api.constrains('event_id', 'state', 'nb_register') + @api.constrains('event_id', 'state') def _check_seats_limit(self): - if self.event_id.seats_max and \ - self.event_id.seats_available < (self.nb_register if self.state == 'draft' else 0): - raise Warning(_('Only %s seats available for this event') % self.event_id.seats_available if self.event_id.seats_available > 0 else _('No more seats available for this event.')) + if self.event_id.seats_max and self.event_id.seats_available < (1 if self.state == 'draft' else 0): + raise Warning(_('No more seats available for this event.')) @api.one def _check_auto_confirmation(self): + if self._context.get('registration_force_draft'): + return False if self.event_id and self.event_id.state == 'confirm' and self.event_id.auto_confirm and self.event_id.seats_available: return True return False @@ -345,7 +312,7 @@ class event_registration(models.Model): @api.model def create(self, vals): res = super(event_registration, self).create(vals) - if res._check_auto_confirmation(): + if res._check_auto_confirmation()[0]: res.sudo().confirm_registration() return res @@ -402,6 +369,6 @@ class event_registration(models.Model): contact_id = self.partner_id.address_get().get('default', False) if contact_id: contact = self.env['res.partner'].browse(contact_id) - self.name = contact.name - self.email = contact.email - self.phone = contact.phone + self.name = self.name or contact.name + self.email = self.email or contact.email + self.phone = self.phone or contact.phone diff --git a/addons/event/event_demo.xml b/addons/event/event_demo.xml index 41aeaf2f2fd..8e2bccf0d08 100644 --- a/addons/event/event_demo.xml +++ b/addons/event/event_demo.xml @@ -217,7 +217,6 @@ <field name="phone">003281588558</field> <field name="event_id" ref="event_1"/> <field name="partner_id" ref="base.res_partner_2"/> - <field name="nb_register">5</field> </record> <record id="reg_1_2" model="event.registration"> @@ -226,7 +225,6 @@ <field name="phone">+ 1 64 61 04 01</field> <field name="partner_id" ref="base.res_partner_1"/> <field name="event_id" ref="event_1"/> - <field name="nb_register">10</field> </record> <record id="reg_0_2" model="event.registration"> @@ -235,7 +233,6 @@ <field name="phone">+41 21 619 10 04 </field> <field name="event_id" ref="event_2"/> <field name="partner_id" ref="base.res_partner_12"/> - <field name="nb_register">5</field> </record> </data> diff --git a/addons/event/event_report.xml b/addons/event/event_report.xml new file mode 100644 index 00000000000..cdbc36cc3d8 --- /dev/null +++ b/addons/event/event_report.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + + <record id="paperformat_euro_lowmargin" model="report.paperformat"> + <field name="name">European A4 low margin</field> + <field name="default" eval="True" /> + <field name="format">A4</field> + <field name="page_height">0</field> + <field name="page_width">0</field> + <field name="orientation">Portrait</field> + <field name="margin_top">5</field> + <field name="margin_bottom">5</field> + <field name="margin_left">5</field> + <field name="margin_right">5</field> + <field name="header_line" eval="False" /> + <field name="header_spacing">0</field> + <field name="dpi">80</field> + </record> + + <report id="action_report_registration_badge" model="event.registration" + string="Badge" report_type="qweb-html" + name="event.report_registration_badge" + file="event.report_registration_badge"/> + <record model="ir.actions.report.xml" id="event.action_report_registration_badge"> + <field name="paperformat_id" ref="event.paperformat_euro_lowmargin"/> + </record> + + </data> +</openerp> diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml index 891a6da5fe5..9371dbe25e9 100644 --- a/addons/event/event_view.xml +++ b/addons/event/event_view.xml @@ -46,7 +46,7 @@ <record id="act_event_registration_from_event" model="ir.actions.act_window"> <field name="res_model">event.registration</field> <field name="view_type">form</field> - <field name="name">Registrations</field> + <field name="name">Attendees</field> <field name="view_mode">tree,form,calendar,graph</field> <field name="context">{'search_default_event_id': active_id, 'default_event_id': active_id}</field> </record> @@ -75,7 +75,7 @@ class="oe_stat_button oe_inline" icon="fa-github" help="Register with this event"> - <field name="count_registrations" widget="statinfo" string="Registrations"/> + <field name="count_registrations" widget="statinfo" string="Attendees"/> </button> </div> <group name="main_field_group"> @@ -190,11 +190,9 @@ <h4> <a name="%(act_event_registration_from_event)d" type="action"> <t t-esc="record.seats_reserved.raw_value" > Attendees</t> - <t t-if="(record.seats_reserved.raw_value + record.seats_unconfirmed.raw_value) > 0 ">/ - <t t-esc="record.seats_reserved.raw_value + record.seats_unconfirmed.raw_value"/> Expected - </t> </a> - <t t-if="record.seats_reserved.raw_value > 0"> + <t t-if="(record.seats_reserved.raw_value + record.seats_unconfirmed.raw_value) > 0 ">/ + <t t-esc="record.seats_reserved.raw_value + record.seats_unconfirmed.raw_value"/> Expected <a name="action_event_registration_report" type="object" >(Report)</a> </t> </h4> @@ -273,7 +271,7 @@ <menuitem name="Events" id="menu_event_event" action="action_event_view" parent="event.event_main_menu" /> - <!-- EVENTS/REGISTRATIONS/EVENTS --> + <!-- EVENT.REGISTRATION VIEWS --> <record model="ir.ui.view" id="view_event_registration_tree"> <field name="name">event.registration.tree</field> <field name="model">event.registration</field> @@ -284,14 +282,8 @@ <field name="name"/> <field name="email"/> <field name="event_id" /> - <field name="nb_register"/> - <field name="user_id" invisible="1"/> - <field name="origin"/> <field name="state"/> <field name="message_unread" invisible="1"/> - <button name="registration_open" string="Confirm Registration" states="draft" type="object" icon="gtk-apply"/> - <button name="button_reg_close" string="Attended the Event" states="open" type="object" icon="gtk-jump-to"/> - <button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object" icon="gtk-cancel"/> </tree> </field> </record> @@ -309,22 +301,17 @@ <field name="state" nolabel="1" colspan="2" widget="statusbar" statusbar_visible="draft,open,done"/> </header> <sheet string="Registration"> - <label for="event_id" class="oe_edit_only"/> - <h1> - <field name="event_id" domain="[('state','in',('draft','confirm'))]"/> - </h1> <group> - <group> - <field name="partner_id" attrs="{'readonly':[('state','!=', 'draft')]}"/> + <group string="Attendee Information"> <field name="name"/> <field name="phone"/> <field name="email"/> + <field name="partner_id" attrs="{'readonly':[('state', '!=', 'draft')]}"/> </group> - <group> - <field name="create_date" groups="base.group_no_one"/> + <group string="Event Information"> + <field name="event_id" readonly="1"/> + <field name="date_open" groups="base.group_no_one"/> <field name="date_closed" groups="base.group_no_one"/> - <field name="nb_register"/> - <field name="user_id" attrs="{'readonly':[('state','!=', 'draft')]}" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'event.group_event_user']}"/> </group> </group> </sheet> @@ -354,7 +341,6 @@ <field name="arch" type="xml"> <graph string="Registration" type="bar"> <field name="event_id" type="row"/> - <field name= "nb_register" type="measure"/> </graph> </field> </record> @@ -364,15 +350,11 @@ <field name="model">event.registration</field> <field name="arch" type="xml"> <search string="Event Registration"> - <field name="name" string="Participant" filter_domain="['|','|',('name','ilike',self),('email','ilike',self),('origin','ilike',self)]"/> + <field name="id" string="Registration ID"/> + <field name="name" string="Participant" filter_domain="['|', '|', ('name', 'ilike', self), ('email', 'ilike', self), ('origin', 'ilike', self)]"/> <filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]"/> <separator/> - <filter string="New" name="draft" domain="[('state','=','draft')]" help="Registrations in unconfirmed state"/> - <filter string="Confirmed" domain="[('state','=','open')]" help="Confirmed registrations"/> - <separator/> - <filter string="My Registrations" help="My Registrations" domain="[('user_id','=',uid)]"/> <field name="event_id"/> - <field name="user_id"/> <field name="partner_id"/> <group expand="0" string="Group By"> <filter string="Responsible" domain="[]" context="{'group_by':'user_id'}"/> @@ -387,7 +369,7 @@ </record> <record model="ir.actions.act_window" id="action_registration"> - <field name="name">Registrations</field> + <field name="name">Attendees</field> <field name="res_model">event.registration</field> <field name="view_type">form</field> <field name="domain"></field> @@ -396,7 +378,7 @@ <field name="search_view_id" ref="view_registration_search"/> </record> - <menuitem name="Registrations" + <menuitem name="Attendees" id="menu_action_registration" parent="event.event_main_menu" action="action_registration" groups="event.group_event_manager,event.group_event_user"/> diff --git a/addons/event/report/report_event_registration.py b/addons/event/report/report_event_registration.py index 5e56ce5cb2f..d1a9b5c40b8 100644 --- a/addons/event/report/report_event_registration.py +++ b/addons/event/report/report_event_registration.py @@ -29,6 +29,7 @@ class report_event_registration(models.Model): _order = 'event_date desc' _auto = False + create_date = fields.Datetime('Creation Date', readonly=True) 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') @@ -40,7 +41,6 @@ class report_event_registration(models.Model): registration_state = fields.Selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Attended'), ('cancel', 'Cancelled')], 'Registration State', readonly=True, required=True) event_state = fields.Selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Event State', readonly=True, required=True) user_id = fields.Many2one('res.users', 'Event Responsible', readonly=True) - user_id_registration = fields.Many2one('res.users', 'Register', readonly=True) name_registration = fields.Char('Participant / Contact Name', readonly=True) company_id = fields.Many2one('res.company', 'Company', readonly=True) @@ -54,14 +54,14 @@ class report_event_registration(models.Model): e.id::varchar || '/' || coalesce(r.id::varchar,'') AS id, e.id AS event_id, e.user_id AS user_id, - r.user_id AS user_id_registration, r.name AS name_registration, + r.create_date AS create_date, e.company_id AS company_id, e.date_begin AS event_date, count(r.id) AS nbevent, - sum(r.nb_register) AS nbregistration, - CASE WHEN r.state IN ('draft') THEN r.nb_register ELSE 0 END AS draft_state, - CASE WHEN r.state IN ('open','done') THEN r.nb_register ELSE 0 END AS confirm_state, + 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, e.type AS event_type, e.seats_max AS seats_max, e.state AS event_state, @@ -72,10 +72,8 @@ class report_event_registration(models.Model): GROUP BY event_id, - user_id_registration, r.id, registration_state, - r.nb_register, event_type, e.id, e.date_begin, diff --git a/addons/event/tests/test_event_flow.py b/addons/event/tests/test_event_flow.py index 59f2970d37b..3af0fb9185c 100644 --- a/addons/event/tests/test_event_flow.py +++ b/addons/event/tests/test_event_flow.py @@ -20,7 +20,7 @@ class TestEventFlow(TestEventCommon): 'name': 'TestEvent', 'date_begin': datetime.datetime.now() + relativedelta(days=-1), 'date_end': datetime.datetime.now() + relativedelta(days=1), - 'seats_max': 10, + 'seats_max': 2, }) self.assertEqual(test_event.state, 'confirm', 'Event: auto_confirmation of event failed') @@ -28,33 +28,30 @@ class TestEventFlow(TestEventCommon): test_reg1 = self.Registration.sudo(self.user_eventuser).create({ 'name': 'TestReg1', 'event_id': test_event.id, - 'nb_register': 7, }) self.assertEqual(test_reg1.state, 'open', 'Event: auto_confirmation of registration failed') - self.assertEqual(test_event.seats_reserved, 7, 'Event: wrong number of reserved seats after confirmed registration') + self.assertEqual(test_event.seats_reserved, 1, 'Event: wrong number of reserved seats after confirmed registration') test_reg2 = self.Registration.sudo(self.user_eventuser).create({ 'name': 'TestReg2', 'event_id': test_event.id, - 'nb_register': 3, }) self.assertEqual(test_reg2.state, 'open', 'Event: auto_confirmation of registration failed') - self.assertEqual(test_event.seats_reserved, 10, 'Event: wrong number of reserved seats after confirmed registration') + self.assertEqual(test_event.seats_reserved, 2, 'Event: wrong number of reserved seats after confirmed registration') # EventUser create registrations for this event: too much registrations with self.assertRaises(ValidationError): self.Registration.sudo(self.user_eventuser).create({ 'name': 'TestReg3', 'event_id': test_event.id, - 'nb_register': 1, }) # EventUser validates registrations test_reg1.button_reg_close() self.assertEqual(test_reg1.state, 'done', 'Event: wrong state of attended registration') - self.assertEqual(test_event.seats_used, 7, 'Event: incorrect number of attendees after closing registration') + self.assertEqual(test_event.seats_used, 1, 'Event: incorrect number of attendees after closing registration') test_reg2.button_reg_close() self.assertEqual(test_reg1.state, 'done', 'Event: wrong state of attended registration') - self.assertEqual(test_event.seats_used, 10, 'Event: incorrect number of attendees after closing registration') + self.assertEqual(test_event.seats_used, 2, 'Event: incorrect number of attendees after closing registration') # EventUser closes the event test_event.button_done() @@ -63,6 +60,7 @@ class TestEventFlow(TestEventCommon): with self.assertRaises(Warning): test_event.button_cancel() + @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models') def test_10_advanced_event_flow(self): """ Avanced event flow: no auto confirmation, manage minimum / maximum diff --git a/addons/event/views/report_registrationbadge.xml b/addons/event/views/report_registrationbadge.xml new file mode 100644 index 00000000000..69156f4a184 --- /dev/null +++ b/addons/event/views/report_registrationbadge.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + <template id="report_registration_badge"> + <t t-call="report.html_container"> + <t t-foreach="docs" t-as="o"> + <div class="page"> + <div class="row" style="border-bottom:1px dashed black;"> + <div class="col-xs-6 text-center" style="padding-right:7mm; border-right:1px dashed black; height: 147mm; padding-top: 7mm"> + <div class="row"> + <div class="col-xs-12"> + <span t-if="o.event_id.organizer_id.company_id.logo_web and o.event_id.organizer_id.is_company"> + <img t-att-src="'data:image/png;base64,%s' % o.event_id.organizer_id.company_id.logo_web" style="max-height:1cm; max-width:4cm;"/> + </span> + <h4 t-field="o.event_id.name"/> + <h5>( <i class="fa fa-clock-o"></i> <span itemprop="startDate" t-field="o.event_id.date_begin" t-field-options='{"hide_seconds":"True"}'> </span> <i>to</i> <span itemprop="endDate" t-field="o.event_id.date_end" t-field-options='{"hide_seconds":"True"}'> </span> )</h5> + </div> + </div> + <div class="row"> + <div class="col-xs-12 text-center"> + <small><h3 t-if="o.partner_id.is_company == True" t-field="o.partner_id.name"/><h5 t-field="o.name"/></small> + </div> + </div> + <div class="row"> + <div class="col-xs-12 mt32 text-center" style="background: lightgrey;"> + <h3>FREE TICKET</h3> + </div> + </div> + </div> + <!-- Inner right --> + <div class="col-xs-6 text-center" style="padding-left:7mm; height: 149mm; padding-top: 2mm;"> + </div> + </div> + </div> + </t> + </t> + </template> + </data> +</openerp> |
