mirror of
https://github.com/pretix/pretix.git
synced 2026-11-14 01:57:08 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f346acb0d2 | ||
|
|
0478559fd7 | ||
|
|
137059dd4e | ||
|
|
bd0b55bdd3 |
No files matched your search
@@ -197,6 +197,8 @@ class ReusableMediaSerializer(I18nAwareModelSerializer):
|
||||
'linked_giftcard',
|
||||
'info',
|
||||
'notes',
|
||||
# When adding fields, check if they should be hidden in ReusableMediaViewSet
|
||||
# for cross-organizer lookups
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ class TransmissionInfoSerializer(serializers.Serializer):
|
||||
super().__init__(*args, **kwargs)
|
||||
for k, v in transmission_type.invoice_address_form_fields.items():
|
||||
self.fields[k] = form_field_to_serializer_field(v)
|
||||
self.fields[k].required = False # invoice_address_form_fields_required is checked by parent serializer
|
||||
|
||||
|
||||
class InvoiceAddressSerializer(I18nAwareModelSerializer):
|
||||
|
||||
@@ -183,9 +183,18 @@ class ReusableMediaViewSet(viewsets.ModelViewSet):
|
||||
type=s.validated_data["type"],
|
||||
identifier=s.validated_data["identifier"],
|
||||
)
|
||||
m.customer = None # not relevant for cross-organizer
|
||||
s = self.get_serializer(m)
|
||||
return Response({"result": s.data})
|
||||
data = s.data
|
||||
# Remove fields that are not relevant for cross-organizer usage
|
||||
data["customer"] = None
|
||||
data["linked_orderposition"] = None
|
||||
data["linked_orderpositions"] = []
|
||||
data["info"] = {}
|
||||
data["notes"] = None
|
||||
data["claim_token"] = None
|
||||
data["label"] = None
|
||||
|
||||
return Response({"result": data})
|
||||
except ReusableMedium.DoesNotExist:
|
||||
mt = MEDIA_TYPES.get(s.validated_data["type"])
|
||||
if mt:
|
||||
|
||||
@@ -27,6 +27,7 @@ from decimal import Decimal
|
||||
|
||||
from django import forms
|
||||
from django.db.models import F, Sum
|
||||
from django.db.models.aggregates import Min
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.html import escape
|
||||
@@ -41,7 +42,8 @@ from reportlab.platypus import (
|
||||
|
||||
from pretix.base.exporter import BaseExporter
|
||||
from pretix.base.models import (
|
||||
GiftCardTransaction, OrderFee, OrderPayment, OrderRefund, Transaction,
|
||||
GiftCardTransaction, Order, OrderFee, OrderPayment, OrderRefund,
|
||||
Transaction,
|
||||
)
|
||||
from pretix.base.templatetags.money import money_filter, tax_rate_format
|
||||
from pretix.base.timeframes import (
|
||||
@@ -116,25 +118,34 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
|
||||
dt_start, df_end = resolve_timeframe_to_datetime_start_inclusive_end_exclusive(
|
||||
now(), form_data["date_range"], self.timezone
|
||||
)
|
||||
if dt_start:
|
||||
filters.append(
|
||||
_("Begin")
|
||||
+ ": "
|
||||
+ date_format(
|
||||
else:
|
||||
dt_start = Order.objects.filter(
|
||||
event__in=self.events,
|
||||
).aggregate(min_datetime=Min('datetime'))['min_datetime']
|
||||
df_end = now()
|
||||
|
||||
if dt_start:
|
||||
filters.append(
|
||||
"{label}: {value}{hint}".format(
|
||||
label=_("Begin"),
|
||||
value=date_format(
|
||||
dt_start.astimezone(self.timezone), "SHORT_DATETIME_FORMAT"
|
||||
)
|
||||
),
|
||||
hint="" if form_data["date_range"] else " ({})".format(_("first order received"))
|
||||
)
|
||||
if df_end:
|
||||
filters.append(
|
||||
_("End")
|
||||
+ ": "
|
||||
+ date_format(
|
||||
(df_end - datetime.timedelta.resolution).astimezone(
|
||||
self.timezone
|
||||
),
|
||||
"SHORT_DATETIME_FORMAT",
|
||||
)
|
||||
)
|
||||
|
||||
if df_end:
|
||||
filters.append(
|
||||
_("End")
|
||||
+ ": "
|
||||
+ date_format(
|
||||
(df_end - datetime.timedelta.resolution).astimezone(
|
||||
self.timezone
|
||||
),
|
||||
"SHORT_DATETIME_FORMAT",
|
||||
)
|
||||
)
|
||||
|
||||
if not form_data["no_testmode"]:
|
||||
filters.append(_("Report includes test orders which may be deleted later!"))
|
||||
|
||||
@@ -75,6 +75,7 @@ class AuthenticationForm(forms.Form):
|
||||
'unverified': _("You have not yet activated your account and set a password. Please click the link in the "
|
||||
"email we sent you. In case you cannot find it, click \"Forgot your password?\" to receive "
|
||||
"a new email."),
|
||||
'rate_limit': _("For security reasons, please wait 5 minutes before you try again."),
|
||||
}
|
||||
|
||||
def __init__(self, request=None, *args, **kwargs):
|
||||
@@ -93,6 +94,12 @@ class AuthenticationForm(forms.Form):
|
||||
email = self.cleaned_data.get('email')
|
||||
password = self.cleaned_data.get('password')
|
||||
|
||||
if rate_limit("customer_login", include_ip_from_request=self.request, max_num=10, expire_time=300):
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['rate_limit'],
|
||||
code='rate_limit',
|
||||
)
|
||||
|
||||
if email is not None and password:
|
||||
try:
|
||||
u = self.request.organizer.customers.get(email=email.lower(), provider__isnull=True)
|
||||
|
||||
@@ -333,7 +333,6 @@ def test_order_update_transmission_validation(token_client, organizer, event, or
|
||||
assert resp.status_code == 400
|
||||
assert resp.data == {"invoice_address": {"transmission_info": {
|
||||
"transmission_it_sdi_pec": ["Enter a valid email address.", "Enter a valid email address."],
|
||||
"transmission_it_sdi_recipient_code": ["This field is required."]
|
||||
}}}
|
||||
|
||||
resp = token_client.patch(
|
||||
|
||||
@@ -696,7 +696,7 @@ def test_medium_autocreate_giftcard(token_client, organizer, team):
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_medium_lookup_cross_organizer(token_client, organizer, organizer2, org2_event, medium2, giftcard2):
|
||||
def test_medium_lookup_cross_organizer(token_client, organizer, customer, organizer2, org2_event, medium2, giftcard2):
|
||||
with scopes_disabled():
|
||||
o = Order.objects.create(
|
||||
code='FOO', event=org2_event, email='dummy@dummy.test',
|
||||
@@ -708,7 +708,12 @@ def test_medium_lookup_cross_organizer(token_client, organizer, organizer2, org2
|
||||
personalized=True)
|
||||
op = o.positions.create(item=ticket, price=Decimal("14"))
|
||||
medium2.linked_orderpositions.add(op)
|
||||
medium2.customer = customer
|
||||
medium2.linked_giftcard = giftcard2
|
||||
medium2.claim_token = "1234"
|
||||
medium2.info = {"foo": "bar"}
|
||||
medium2.notes = "Internal notes"
|
||||
medium2.label = "Max Muster"
|
||||
medium2.save()
|
||||
|
||||
resp = token_client.post(
|
||||
@@ -755,3 +760,9 @@ def test_medium_lookup_cross_organizer(token_client, organizer, organizer2, org2
|
||||
assert resp.data["result"]["organizer"] == "partner"
|
||||
assert resp.data["result"]["linked_giftcard"] is not None
|
||||
assert resp.data["result"]["linked_orderposition"] is None
|
||||
assert resp.data["result"]["linked_orderpositions"] == []
|
||||
assert resp.data["result"]["customer"] is None
|
||||
assert resp.data["result"]["info"] == {}
|
||||
assert resp.data["result"]["notes"] is None
|
||||
assert resp.data["result"]["claim_token"] is None
|
||||
assert resp.data["result"]["label"] is None
|
||||
Reference in new issue
Block a user