Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

14.0 prepare website event attendee fields #2

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 140 additions & 0 deletions website_event_attendee_fields/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
========================
Event guest Custom Field
========================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:5752548864e6f30053221647419af2ddae7179fdf0e47376b5a8025259af0a86
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-it--projects--llc%2Fwebsite--addons-lightgray.png?logo=github
:target: https://github.com/it-projects-llc/website-addons/tree/14.0/website_event_attendee_fields
:alt: it-projects-llc/website-addons

|badge1| |badge2| |badge3|

By default ``website_event`` module asks only three fields to fill about
attendees (name, email, phone). This module allows to customize any set
of fields.

Also,

- if total bootstrap width of field columns is more that 12

- hides Header at Attendee form
- shows field name above each input

- If user is authenticated:

- first attendee at the form will have autofilled values (if person
is not registered yet)

- Modifies behaviour of ``partner_event`` module:

- always updates Registration's name and phone to corresponded
values of Attendee Partner, because they may be taken from Partner
record (e.g. Public User)

- If attendee partner exists and current (authenticated) user is the
attendee partner himself: update partner values. (We don't update
fields always, because it leads to security issue: anyone can
change partner name, passport, etc. just knowing his email).
Default behaviour: only create partner if one doesn't exist.

- Prevents changing qty for event lines (TODO: move this to a separate
module)

- Custom redirection after filling ticket form, e.g. to cart page to
ask for coupons (TODO: move this to a separate module). Create System
Parameter ``website_event_sale.redirection`` to configure it.

**Table of contents**

.. contents::
:local:

Configuration
=============

- Open menu ``Event``
- Select or create Event
- At ``Website Fields`` tab update list of fields

Usage
=====

- Open ``/event`` page
- Select desired Event
- Select quantity of tickets and click ``[Order Now]``
- RESULT: specified fields are shown
- Fill the fields and proceed checkout
- Go back to backend. Open menu ``Event``
- Check new attendee(s) of the Event
- Result: Attendee(s) fields are stored in **Contact** record

Email field at the form
-----------------------

- When email column is presented and there is a partner with that
email:

- if partner has confirmed registration for the event:

- registration is blocked. Warning is shown

- if partner has some of fields

- grey them out with a message "This email address already has an
account. Data will be taken from this account"

- Registration form doesn't allow to register two attendees with the
same email

- When partner record exists before purchasing the module and current
user is not that partner, then new partner's details are posted under
registration form as a message. Such cases has to be handled
manually, because we cannot update them automatically to partner for
security reasons.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/it-projects-llc/website-addons/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/it-projects-llc/website-addons/issues/new?body=module:%20website_event_attendee_fields%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* IT-Projects LLC

Contributors
------------

- Ivan Yelizariev (https://github.com/yelizariev)
- Alexandr Kolushov (https://github.com/KolushovAlexandr)
- Denis Mudarisov (https://github.com/trojikman)
- Eugene Molotov (https://github.com/em230418)
- Victor Bykov (https://github.com/BykovVik)

Maintainers
-----------

This module is part of the `it-projects-llc/website-addons <https://github.com/it-projects-llc/website-addons/tree/14.0/website_event_attendee_fields>`_ project on GitHub.

You are welcome to contribute.
2 changes: 2 additions & 0 deletions website_event_attendee_fields/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import controllers
25 changes: 25 additions & 0 deletions website_event_attendee_fields/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": """Event guest Custom Field""",
"summary": """Do you need more information about attendees than three default fields (name, email, phone)?""", # noqa: E501
"category": "Marketing",
"images": ["images/banner.jpg"],
"version": "14.0.2.0.1",
"application": False,
"author": "IT-Projects LLC",
"support": "[email protected]",
"website": "https://github.com/it-projects-llc/website-addons",
"license": "AGPL-3",
"depends": ["website_event_sale", "partner_event"],
"data": [
"views/website_event_templates.xml",
"views/event_event_views.xml",
"security/ir.model.access.csv",
"views/assets.xml",
],
"qweb": [],
"demo": [
"data/event_event_attendee_field_demo.xml",
"data/event_event_demo.xml",
"views/assets_demo.xml",
],
}
1 change: 1 addition & 0 deletions website_event_attendee_fields/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
147 changes: 147 additions & 0 deletions website_event_attendee_fields/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# ruff: noqa: E501
import re

from odoo import http
from odoo.http import request
from odoo.models import BaseModel

from odoo.addons.website_event.controllers.main import (
UserError,
WebsiteEventController,
_,
fields,
)


# fmt: off
def _process_attendees_form(self, event, form_details):
""" Process data posted from the attendee details form.

:param form_details: posted data from frontend registration form, like
{'1-name': 'r', '1-email': '[email protected]', '1-phone': '', '1-event_ticket_id': '1'}
"""
allowed_fields = request.env['event.registration']._get_website_registration_allowed_fields()
registration_fields = {key: v for key, v in request.env['event.registration']._fields.items() if key in allowed_fields}
# change: added res.partner fields
registration_fields.update({key: v for key, v in request.env['res.partner']._fields.items() if key in allowed_fields})
for ticket_id in list(filter(lambda x: x is not None, [form_details[field] if 'event_ticket_id' in field else None for field in form_details.keys()])):
if int(ticket_id) not in event.event_ticket_ids.ids and len(event.event_ticket_ids.ids) > 0:
raise UserError(_("This ticket is not available for sale for this event"))
registrations = {}
global_values = {}
for key, value in form_details.items():
counter, attr_name = key.split('-', 1)
field_name = attr_name.split('-')[0]
if field_name not in registration_fields:
continue
elif isinstance(registration_fields[field_name], (fields.Many2one, fields.Integer)):
value = int(value) or False # 0 is considered as a void many2one aka False
else:
value = value

if counter == '0':
global_values[attr_name] = value
else:
registrations.setdefault(counter, dict())[attr_name] = value
for key, value in global_values.items():
for registration in registrations.values():
registration[key] = value

return list(registrations.values())
# fmt: on

WebsiteEventController._process_attendees_form = _process_attendees_form


class WebsiteEventControllerExtended(WebsiteEventController):
@http.route()
def registration_confirm(self, event, **post):
"""Check that threre are no email duplicates.
There is a check on frontend, but that is easy to get around."""
registrations = self._process_attendees_form(event, post)
emails = [r.get("email", "").strip() for r in registrations]
assert len(emails) == len(set(emails))
res = super(WebsiteEventControllerExtended, self).registration_confirm(
event, **post
)
if res.location:
# If super redirect (to /shop/checkout)
url = (
event.sudo()
.env["ir.config_parameter"]
.get_param("website_event_sale.redirection")
or res.location
)
return request.redirect(url)
else:
return res

def _process_attendees_form(self, event, form_details):
"""Remove spaces in emails"""
res = super(WebsiteEventControllerExtended, self)._process_attendees_form(
event, form_details
)
for registration in res:
if registration.get("email"):
registration["email"] = registration.get("email").strip()
return res

@http.route(
["/website_event_attendee_fields/check_email"],
type="json",
auth="public",
methods=["POST"],
website=True,
)
def check_email(self, event_id, email):
partner = (
request.env["res.partner"].sudo().search([("email", "=", email)], limit=1)
)
if not partner:

def remove_spaces(s):
s = re.sub(r"^\s*", "", s)
s = re.sub(r"\s*$", "", s)
return s

email = remove_spaces(email)
partner = (
request.env["res.partner"]
.sudo()
.search(
[
"|",
"|",
("email", "=ilike", "% " + email),
("email", "=ilike", "% " + email + " %"),
("email", "=ilike", email + " %"),
],
limit=1,
)
)
if not partner:
return {}
partner_email = remove_spaces(partner.email)
# It's a workaround in order to prevent duplicating partner accounts when buying a ticket
partner.write({"email": partner_email})

event = request.env["event.event"].sudo().browse(event_id)
error_msg = event.check_partner_for_new_ticket(partner.id)
if error_msg:
return {"email_not_allowed": error_msg}

known_fields = {}
for f in event.attendee_field_ids:
if f.field_name == "email":
continue
if getattr(partner, f.field_name):
if partner != request.env.user.partner_id:
known_fields[f.field_name] = ""
else:
value = partner[f.field_name]
if isinstance(value, BaseModel):
known_fields[f.field_name] = value.id or ""
else:
known_fields[f.field_name] = value

return {"known_fields": known_fields}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="attendee_field_name" model="event.event.attendee_field">
<field name="field_id" ref="event.field_event_registration__name" />
<field name="form_type">text</field>
<field name="width">4</field>
</record>
<record id="attendee_field_email" model="event.event.attendee_field">
<field name="field_id" ref="event.field_event_registration__email" />
<field name="form_type">email</field>
<field name="width">5</field>
</record>
<record id="attendee_field_phone" model="event.event.attendee_field">
<field name="field_id" ref="event.field_event_registration__phone" />
<field name="form_type">tel</field>
<field name="width">3</field>
<field name="is_required" eval="False" />
</record>
<record id="attendee_field_country_id" model="event.event.attendee_field">
<field name="field_id" ref="base.field_res_partner__country_id" />
<field name="form_type">many2one</field>
<field name="width">3</field>
</record>
<record id="attendee_field_function" model="event.event.attendee_field">
<field name="field_id" ref="base.field_res_partner__function" />
<field name="form_type">text</field>
<field name="width">3</field>
<field name="is_required" eval="False" />
</record>
</odoo>
17 changes: 17 additions & 0 deletions website_event_attendee_fields/data/event_event_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<function model="event.event" name="write">
<value model="event.event" eval="obj().search([]).ids" />
<value
eval="{
'create_partner': True,
'attendee_field_ids': [(6, 0, [
ref('website_event_attendee_fields.attendee_field_name'),
ref('website_event_attendee_fields.attendee_field_email'),
ref('website_event_attendee_fields.attendee_field_phone'),
ref('website_event_attendee_fields.attendee_field_country_id'),
ref('website_event_attendee_fields.attendee_field_function'),
])]}"
/>
</function>
</odoo>
Loading
Loading