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

[17.0][MIG] website_event_attendee_fields #12

Draft
wants to merge 12 commits into
base: 17.0
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ parserOptions:

overrides:
- files:
- "website_event_attendee_fields/static/src/js/test_tour.js"
- "**/*.esm.js"
parserOptions:
sourceType: module
Expand Down
148 changes: 148 additions & 0 deletions website_event_attendee_fields/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
========================
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/17.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 info: name, email, phone. This module allows to customize any
set of fields.

Also,

- 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 ``Question`` tab add question:

- Question type: Contact's field

- Contact field: choose any

- Contact field domain (if shown): input domain or leave default

- Ask once per order:

- To store value in attendee contact: leave unchecked
- To store value in "booked by contact": set checked

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:%2017.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/17.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
30 changes: 30 additions & 0 deletions website_event_attendee_fields/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"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": "17.0.1.0.0",
"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",
"views/event_templates_page_registration.xml",
"views/ir_model_views.xml",
],
"demo": [
"data/event_event_demo.xml",
],
"assets": {
"web.assets_frontend": [
"website_event_attendee_fields/static/src/js/registration_form.js",
],
"web.assets_tests": [
"website_event_attendee_fields/static/src/js/test_tour.js",
],
},
}
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
129 changes: 129 additions & 0 deletions website_event_attendee_fields/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# ruff: noqa: E501
import re

from odoo import _, http
from odoo.http import request
from odoo.tools.mail import email_normalize

from odoo.addons.website_event.controllers.main import WebsiteEventController


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))
return super().registration_confirm(event, **post)

def _process_attendees_form(self, event, form_details):
res = super()._process_attendees_form(event, form_details)

specific_question_ids = event.specific_question_ids.ids

for registration in res:
if registration.get("email"):
# Remove spaces in emails
registration["email"] = registration.get("email").strip()

partner_vals = request.env[
"event.registration"
]._parse_answers_for_partner_questions(registration, specific_question_ids)

if partner_vals:
registration.update(partner_vals)

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):
if not email:
return {}

Partners = request.env["res.partner"].sudo()
email = email_normalize(email, True)

if not email:
return {"email_not_allowed": _("Invalid email")}

current_user = request.env.user
if email == current_user.email:
partner = current_user.partner_id
else:
partner = Partners.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 = Partners.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 = {}
do_not_disable_fields = {}

for q in event.specific_question_ids:
if q.question_type == "email":
continue

fname = None
value = None
if q.question_type == "partner_field":
fname = q.partner_field_name
value = q.get_value(partner) or ""
elif q.question_type in ["name", "phone", "company_name"]:
fname = q.question_type
value = getattr(partner, fname) or ""

if fname and value:
if partner == current_user.partner_id:
known_fields[fname] = value
else:
known_fields[fname] = ""

# Special case for firstname and lastname fields
# If one of the is given and not the other,
# then we consider that we name is not fully known
# and we add mark not to disable them
if partner == request.env.user.partner_id:
firstname = known_fields.get("firstname")
lastname = known_fields.get("lastname")

if (lastname and not firstname) or (firstname and not lastname):
do_not_disable_fields["firstname"] = True
do_not_disable_fields["lastname"] = True

return {
"known_fields": known_fields,
"do_not_disable_fields": do_not_disable_fields,
}
31 changes: 31 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,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="base.field_res_partner__country_id" model="ir.model.fields">
<field name="attendee_field" eval="True" />
</record>

<record id="base.field_res_partner__function" model="ir.model.fields">
<field name="attendee_field" eval="True" />
</record>

<function model="event.event" name="write">
<value
model="event.event"
eval="obj().search([('create_partner', '=', False)]).ids"
/>
<value
eval="{
'create_partner': True,
'question_ids': [(0, 0, {
'title': 'Country',
'question_type': 'partner_field',
'partner_field': ref('base.field_res_partner__country_id'),
}), (0, 0, {
'title': 'Function',
'question_type': 'partner_field',
'partner_field': ref('base.field_res_partner__function'),
})],
}"
/>
</function>
</odoo>
Loading
Loading