Skip to content
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
20 changes: 10 additions & 10 deletions .github/workflows/style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.11
- uses: actions/cache@v4
with:
path: ~/.cache/pip
Expand All @@ -39,10 +39,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.11
- uses: actions/cache@v4
with:
path: ~/.cache/pip
Expand All @@ -61,10 +61,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.11
- uses: actions/cache@v4
with:
path: ~/.cache/pip
Expand All @@ -83,10 +83,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.11
- uses: actions/cache@v4
with:
path: ~/.cache/pip
Expand All @@ -105,10 +105,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.11
- uses: actions/cache@v4
with:
path: ~/.cache/pip
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:
name: Tests
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.11
- uses: actions/cache@v4
with:
path: ~/.cache/pip
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ recursive-include pretix_roomsharing/templates *
recursive-include pretix_roomsharing/locale *
include LICENSE
exclude .gitlab-ci.yml
exclude renovate.json
2 changes: 1 addition & 1 deletion pretix_roomsharing/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.1.13"
__version__ = "0.1.14"
84 changes: 72 additions & 12 deletions pretix_roomsharing/checkoutflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ class RoomCreateForm(forms.Form):
password = forms.CharField(
max_length=190,
label=_("Room password"),
min_length=3,
min_length=3,
widget=forms.PasswordInput,
required=False
required=False,
)

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -205,10 +205,12 @@ def create_form(self):
prefix="create",
initial=initial,
current=current,
data=self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "create"
else None,
data=(
self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "create"
else None
),
)

@cached_property
Expand All @@ -232,10 +234,12 @@ def join_form(self):
event=self.event,
prefix="join",
initial=initial,
data=self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "join"
else None,
data=(
self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "join"
else None
),
)

@cached_property
Expand Down Expand Up @@ -269,6 +273,64 @@ def is_completed(self, request, warn=False):
room = Room.objects.get(
event=self.event, pk=cart_session(request)["room_join"]
)
# Validation of max people
if self.request.event.settings.roomsharing__check_max_people:
max_people = None
for cartPosition in self.get_cart()["positions"]:
item_id = str(cartPosition.item.id)
max_people_setting_key = f"roomsharing__max_people_{item_id}"
if max_people_setting_key in self.request.event.settings:
max_people = self.request.event.settings[
max_people_setting_key
]
break

if max_people is not None and len(room.orderrooms.all()) >= int(
max_people
):
if warn:
messages.warning(
request,
_(
"""
The room you requested to join is already full.
Please choose a different room.
"""
),
)
return False
# Validation of ticket type
if self.request.event.settings.roomsharing__check_ticket_type:
room_ticket_types = set(
c["order__all_positions__item"]
for c in room.orderrooms.filter(
order__all_positions__canceled=False
)
.values("order__all_positions__item")
.distinct()
)
cart_ticket_types = set(
c["item"] for c in get_cart(request).values("item").distinct()
)
if any(c not in room_ticket_types for c in cart_ticket_types):
if warn:
messages.warning(
request,
_(
"""
You requested to join a room that participates in "{room_ticket_type}",
while you chose to participate in "{cart_ticket_type}".
Please choose a different room.
"""
).format(
room_ticket_type=room.name,
cart_ticket_type=SubEvent.objects.get(
pk=list(cart_ticket_types)[0]
).name,
),
)
return False

room_subevents = set(
c["order__all_positions__subevent"]
for c in room.orderrooms.filter(
Expand All @@ -277,8 +339,6 @@ def is_completed(self, request, warn=False):
.values("order__all_positions__subevent")
.distinct()
)
# TODO: Validation of same room type
# TODO: Validation of max room quantity?
if room_subevents:
cart_subevents = set(
c["subevent"]
Expand Down
7 changes: 2 additions & 5 deletions pretix_roomsharing/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,7 @@ def order_info(sender: Event, order: Order, **kwargs):
# Show link for user to change room
order_has_room = False
for orderPosition in order.positions.all():
if (
str(orderPosition.item.id)
in sender.settings.roomsharing__products
):
if str(orderPosition.item.id) in sender.settings.roomsharing__products:
order_has_room = True
ctx["order_has_room"] = order_has_room

Expand Down Expand Up @@ -237,4 +234,4 @@ def control_order_search(sender, request, **kwargs):
except ImportError:
pass

settings_hierarkey.add_default('roomsharing__products', None, list)
settings_hierarkey.add_default("roomsharing__products", None, list)
10 changes: 9 additions & 1 deletion pretix_roomsharing/templates/pretix_roomsharing/settings.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{% extends "pretixcontrol/event/settings_base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% load room_tags %}
{% block title %} {% trans "Roomsharing Settings" %} {% endblock %}
{% block inside %}
<h1>{% trans "Roomsharing Settings" %}</h1>
Expand All @@ -11,7 +12,14 @@ <h1>{% trans "Roomsharing Settings" %}</h1>
{% bootstrap_form_errors form %}
<p>{% trans "Selecting a product here requires room shares to be the same product. You can get around this by using bundled products and selecting one of those here." %}</p>
{% bootstrap_field form.roomsharing__products layout="control" %}
</fieldset>
{% for field in form %}
{% if field.name|startswith:"roomsharing__max_people_" %}
{% bootstrap_field field layout="control" %}
{% endif %}
{% endfor %}
{% bootstrap_field form.roomsharing__check_max_people layout="control" %}
{% bootstrap_field form.roomsharing__check_ticket_type layout="control" %}
</fieldset>
<div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %}
Expand Down
5 changes: 5 additions & 0 deletions pretix_roomsharing/templatetags/room_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ def sum_filter(value):
)

return sum(value)


@register.filter(name="startswith")
def startswith(value, prefix):
return value.startswith(prefix)
81 changes: 59 additions & 22 deletions pretix_roomsharing/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,49 @@ class RoomsharingSettingsForm(SettingsForm):
widget=CheckboxSelectMultiple,
)

roomsharing__check_max_people = forms.BooleanField(
label=_("Check if the room has the same maximum number of people"),
required=False,
)

roomsharing__check_ticket_type = forms.BooleanField(
label=_("Check if the room type is the same ticket type"),
required=False,
)

def __init__(self, *args, **kwargs):
event = kwargs.get("obj")
super().__init__(*args, **kwargs)

choices = (
choices = [
(str(i["id"]), i["name"]) for i in event.items.values("name", "id").all()
)

]
self.fields["roomsharing__products"].choices = choices
#self.initial["roomsharing__products"] = event.settings.roomsharing__products

for item_id, item_name in choices:
field_name = f"roomsharing__max_people_{item_id}"
self.fields[field_name] = forms.IntegerField(
label=f"Max people for {item_name}",
required=False,
initial=1,
)

def clean(self):
cleaned_data = super().clean()
selected_products = cleaned_data.get("roomsharing__products", [])

for item_id in selected_products:
field_name = f"roomsharing__max_people_{item_id}"
max_people = cleaned_data.get(field_name)

if max_people is not None:
if max_people <= 0:
self.add_error(
field_name,
"The maximum number of people must be a positive integer.",
)

return cleaned_data


class SettingsView(EventSettingsViewMixin, EventSettingsFormView):
Expand Down Expand Up @@ -80,6 +113,7 @@ class RoomChangePasswordForm(forms.Form):
label=_("New room password"),
help_text=_("Optional"),
min_length=3,
widget=forms.PasswordInput,
required=False,
)

Expand Down Expand Up @@ -198,32 +232,38 @@ def change_form(self):
return RoomChangePasswordForm(
event=self.request.event,
prefix="change",
data=self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "change"
else None,
data=(
self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "change"
else None
),
)

@cached_property
def create_form(self):
return RoomCreateForm(
event=self.request.event,
prefix="create",
data=self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "create"
else None,
data=(
self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "create"
else None
),
)

@cached_property
def join_form(self):
return RoomJoinForm(
event=self.request.event,
prefix="join",
data=self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "join"
else None,
data=(
self.request.POST
if self.request.method == "POST"
and self.request.POST.get("room_mode") == "join"
else None
),
)

def get_context_data(self, **kwargs):
Expand All @@ -242,11 +282,6 @@ def get_context_data(self, **kwargs):

return ctx

def dispatch(self, request, *args, **kwargs):
self.request = request

return super().dispatch(request, *args, **kwargs)


class ControlRoomForm(forms.ModelForm):
class Meta:
Expand Down Expand Up @@ -396,7 +431,9 @@ def delete(self, request, *args, **kwargs):

class StatsMixin:
def get_ticket_stats(self, event):
qs = OrderPosition.objects.filter(order__event=event,).annotate(
qs = OrderPosition.objects.filter(
order__event=event,
).annotate(
has_room=Exists(OrderRoom.objects.filter(order_id=OuterRef("order_id")))
)
return [
Expand Down