-
Notifications
You must be signed in to change notification settings - Fork 55
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
Hotel Lottery Forms #4360
base: main
Are you sure you want to change the base?
Hotel Lottery Forms #4360
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
[hotel_lottery] | ||
[[gaylord]] | ||
name = "Gaylord National Harbor" | ||
description = "The drive can't be that bad, can it?" | ||
[[[Double Queen]]] | ||
name = "Double Queen" | ||
description = "Two beds in a box" | ||
price = 10000 | ||
capacity = 4 | ||
[[[King]]] | ||
name = "King" | ||
description = "One bed in a box" | ||
price = 10000 | ||
capacity = 4 | ||
[[[Suite]]] | ||
name = "Suite" | ||
description = "Baller over here" | ||
price = 20000 | ||
capacity = 8 | ||
|
||
[[roof]] | ||
name = "Rooftop Room" | ||
description = "Camping out on the roof of the Donald E. Stephens Convention Center" | ||
[[[Double Queen]]] | ||
name = "Double Queen" | ||
description = "Two beds in a box" | ||
price = 10000 | ||
capacity = 4 | ||
[[[King]]] | ||
name = "King" | ||
description = "One bed in a box" | ||
price = 10000 | ||
capacity = 4 | ||
[[[Suite]]] | ||
name = "Suite" | ||
description = "Baller over here" | ||
price = 20000 | ||
capacity = 8 | ||
|
||
[[cardboard]] | ||
name = "Cardboard Box" | ||
description = "Literally a big box. Do you fits?" | ||
[[[Double Queen]]] | ||
name = "Double Queen" | ||
description = "Two beds in a box" | ||
price = 10000 | ||
capacity = 4 | ||
[[[King]]] | ||
name = "King" | ||
description = "One bed in a box" | ||
price = 10000 | ||
capacity = 4 | ||
[[[Suite]]] | ||
name = "Suite" | ||
description = "Baller over here" | ||
price = 20000 | ||
capacity = 8 | ||
|
||
[[mark_center]] | ||
name = "Hilton Mark Center" | ||
description = "The tall one" | ||
[[[Double Queen]]] | ||
name = "Double Queen" | ||
description = "Two beds in a box" | ||
price = 10000 | ||
capacity = 4 | ||
[[[King]]] | ||
name = "King" | ||
description = "One bed in a box" | ||
price = 10000 | ||
capacity = 4 | ||
[[[Suite]]] | ||
name = "Suite" | ||
description = "Baller over here" | ||
price = 20000 | ||
capacity = 8 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ | |
|
||
from uber.config import c | ||
from uber.forms import (AddressForm, MultiCheckbox, MagForm, SelectAvailableField, SwitchInput, NumberInputGroup, | ||
HiddenBoolField, HiddenIntField, CustomValidation) | ||
HiddenBoolField, HiddenIntField, CustomValidation, Ranking) | ||
from uber.custom_tags import popup_link | ||
from uber.badge_funcs import get_real_badge_type | ||
from uber.models import Attendee, Session, PromoCodeGroup | ||
|
@@ -18,7 +18,8 @@ | |
|
||
|
||
__all__ = ['AdminBadgeExtras', 'AdminBadgeFlags', 'AdminConsents', 'AdminStaffingInfo', 'BadgeExtras', | ||
'BadgeFlags', 'BadgeAdminNotes', 'PersonalInfo', 'PreregOtherInfo', 'OtherInfo', 'StaffingInfo', 'Consents'] | ||
'BadgeFlags', 'BadgeAdminNotes', 'PersonalInfo', 'PreregOtherInfo', 'OtherInfo', 'StaffingInfo', | ||
'LotteryApplication', 'Consents'] | ||
|
||
|
||
# TODO: turn this into a proper validation class | ||
|
@@ -28,6 +29,10 @@ def valid_cellphone(form, field): | |
'include a country code (e.g. +44) for international numbers.') | ||
|
||
|
||
class LotteryApplication(MagForm): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's move this into its own forms/hotel.py file, to more closely reflect where it is in models/. I'm sure we'll have plenty of lottery-related forms as we progress so it won't be a file with just one class in it. Also, just wondering, why is this a StringField and not a SelectMultipleField or similar? Is it because the choices have to be ordered? |
||
hotel_preference = StringField('Hotel Preference', widget=Ranking(c.HOTEL_LOTTERY_HOTEL_OPTS, id="hotel_preference"), | ||
validators=[validators.Regexp(r"^roof.*$", message="You didn't select the roof as your most preferred hotel. What, are you too good for the great outdoors?")]) | ||
|
||
class PersonalInfo(AddressForm, MagForm): | ||
field_validation, new_or_changed_validation = CustomValidation(), CustomValidation() | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,16 @@ | |
from wtforms.validators import ValidationError | ||
|
||
from uber.config import c | ||
from uber.forms import AddressForm, CustomValidation, MultiCheckbox, MagForm, IntSelect, NumberInputGroup | ||
from uber.forms import AddressForm, CustomValidation, MultiCheckbox, MagForm, IntSelect, NumberInputGroup, Ranking | ||
from uber.forms.attendee import valid_cellphone | ||
from uber.custom_tags import format_currency, pluralize | ||
from uber.model_checks import invalid_phone_number | ||
|
||
__all__ = ['GroupInfo', 'ContactInfo', 'TableInfo', 'AdminGroupInfo', 'AdminTableInfo'] | ||
__all__ = ['HotelLotteryApplication', 'GroupInfo', 'ContactInfo', 'TableInfo', 'AdminGroupInfo', 'AdminTableInfo'] | ||
|
||
|
||
class HotelLotteryApplication(MagForm): | ||
ranked_hotels = Ranking(c.HOTEL_LOTTERY.keys()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is Ranking() a widget or a field class? I see this form isn't being used, is it just left over from something else you were trying? |
||
|
||
|
||
class GroupInfo(MagForm): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,3 +102,59 @@ def render_option(cls, value, label, selected, **kwargs): | |
return Markup( | ||
"<option {}>{}</option>".format(html_params(**options), escape(label)) | ||
) | ||
|
||
class Ranking(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to double-check, should this be subclassing an existing WTForms widget? |
||
def __init__(self, choices=None, id=None, **kwargs): | ||
self.choices = choices | ||
self.id = id | ||
|
||
def __call__(self, field, choices=None, id=None, **kwargs): | ||
choices = choices or self.choices or [('', {"name": "Error", "description": "No choices are configured"})] | ||
id = id or self.id or "ranking" | ||
selected_choices = field.data.split(",") | ||
|
||
deselected_html = [] | ||
selected_html = [] | ||
choice_dict = {key: val for key, val in choices} | ||
for choice_id in selected_choices: | ||
try: | ||
choice_item = choice_dict[choice_id] | ||
el = f""" | ||
<li class="choice" value="{choice_id}"> | ||
<div class="choice-name"> | ||
{choice_item["name"]} | ||
</div> | ||
<div class="choice-description"> | ||
{choice_item["description"]} | ||
</div> | ||
</li>""" | ||
selected_html.append(el) | ||
except KeyError: | ||
continue | ||
for choice_id, choice_item in choices: | ||
if not choice_id in selected_choices: | ||
el = f""" | ||
<li class="choice" value="{choice_id}"> | ||
<div class="choice-name"> | ||
{choice_item["name"]} | ||
</div> | ||
<div class="choice-description"> | ||
{choice_item["description"]} | ||
</div> | ||
</li>""" | ||
deselected_html.append(el) | ||
|
||
html = [ | ||
'<div class="row">', | ||
'<div class="col-md-6">', | ||
'Available', | ||
f'<ul class="choice-list" id="deselected_{id}">', | ||
*deselected_html, | ||
'</ul></div><div class="col-md-6">', | ||
'Selected', | ||
f'<ul class="choice-list" id="selected_{id}">', | ||
*selected_html, | ||
f'</ul></div></div><input type="hidden" id="{id}" name="{id}" value="None" />' | ||
] | ||
|
||
return Markup(''.join(html)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from datetime import datetime | ||
|
||
from uber.config import c | ||
from uber.decorators import ajax, all_renderable | ||
from uber.errors import HTTPRedirect | ||
from uber.models import Attendee, Room, RoomAssignment, Shift, LotteryApplication | ||
from uber.forms import load_forms | ||
from uber.utils import validate_model | ||
|
||
|
||
@all_renderable() | ||
class Root: | ||
def index(self, session, **params): | ||
lottery_application = LotteryApplication() | ||
params['id'] = 'None' | ||
forms = load_forms(params, lottery_application, ['LotteryApplication']) | ||
return { | ||
"checkin_start": c.HOTEL_LOTTERY_CHECKIN_START, | ||
"checkin_end": c.HOTEL_LOTTERY_CHECKIN_END, | ||
"checkout_start": c.HOTEL_LOTTERY_CHECKOUT_START, | ||
"checkout_end": c.HOTEL_LOTTERY_CHECKOUT_END, | ||
"hotels": c.HOTEL_LOTTERY, | ||
"forms": forms | ||
} | ||
|
||
@ajax | ||
def validate_hotel_lottery(self, session, form_list=[], **params): | ||
if params.get('id') in [None, '', 'None']: | ||
application = LotteryApplication() | ||
else: | ||
application = LotteryApplication.get(id=params.get('id')) | ||
|
||
if not form_list: | ||
form_list = ["LotteryApplication"] | ||
elif isinstance(form_list, str): | ||
form_list = [form_list] | ||
forms = load_forms(params, application, form_list, get_optional=False) | ||
|
||
all_errors = validate_model(forms, application, LotteryApplication(**application.to_dict())) | ||
if all_errors: | ||
return {"error": all_errors} | ||
|
||
return {"success": True} | ||
|
||
def form(self, session, message="", **params): | ||
application = LotteryApplication() | ||
forms_list = ["LotteryApplication"] | ||
forms = load_forms(params, application, forms_list) | ||
for form in forms.values(): | ||
form.populate_obj(application) | ||
return { | ||
'forms': forms, | ||
'message': message, | ||
'application': application | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to double-check, is/was this a temporary statement for debugging?