remove order.subevent variants

This commit is contained in:
Lukas Bockstaller
2026-06-23 15:40:23 +02:00
parent b9e10251bc
commit 5e55f53650
3 changed files with 45 additions and 157 deletions
+8 -48
View File
@@ -46,9 +46,8 @@ if TYPE_CHECKING:
@dataclass(frozen=True)
class BaseChoice:
base: Literal["event", "order", "order.subevents"]
base: Literal["event", "order"]
attribute: str
modifier: str
text: Promise
supports_before: bool
supports_after: bool
@@ -56,8 +55,6 @@ class BaseChoice:
@property
def key(self) -> str:
key = f"{self.base}__{self.attribute}"
if self.modifier:
key += f"__{self.modifier}"
return key
@staticmethod
@@ -75,19 +72,13 @@ class BaseChoice:
BASE_CHOICES: List[BaseChoice] = [
BaseChoice('event', 'date_from', "", _('Event start'), True, True),
BaseChoice('event', 'date_to', "", _('Event end'), True, True),
BaseChoice('event', 'date_admission', "", _('Event admission'), True, True),
BaseChoice('event', 'presale_start', "", _('Presale start'), True, True),
BaseChoice('event', 'presale_end', "", _('Presale end'), True, True),
BaseChoice('order', 'datetime', "", _('Order creation'), False, True),
BaseChoice('order', 'expires', "", _('Order expiry'), True, True),
BaseChoice('order.subevents', 'date_from', "first", _('Subevent start (first subevent in order)'), True, True),
BaseChoice('order.subevents', 'date_from', "last", _('Subevent start (last subevent in order)'), True, True),
BaseChoice('order.subevents', 'date_to', "first", _('Subevent end (first subevent in order)'), True, True),
BaseChoice('order.subevents', 'date_to', "last", _('Subevent end (last subevent in order)'), True, True),
BaseChoice('order.subevents', 'date_admission', "first", _('Subevent admission (first subevent in order)'), True, True),
BaseChoice('order.subevents', 'date_admission', "last", _('Subevent admission (last subevent in order)'), True, True),
BaseChoice('event', 'date_from', _('Event start'), True, True),
BaseChoice('event', 'date_to', _('Event end'), True, True),
BaseChoice('event', 'date_admission', _('Event admission'), True, True),
BaseChoice('event', 'presale_start', _('Presale start'), True, True),
BaseChoice('event', 'presale_end', _('Presale end'), True, True),
BaseChoice('order', 'datetime', _('Order creation'), False, True),
BaseChoice('order', 'expires', _('Order expiry'), True, True),
]
LIMIT_FALLBACKS = ['date_from', 'date_to', 'date_admission', 'presale_start', 'presale_end']
@@ -100,10 +91,6 @@ ORDER_BASE_CHOICES = [
x for x in BASE_CHOICES if x.base == 'order'
]
SUBEVENT_BASE_CHOICES = [
x for x in BASE_CHOICES if x.base == 'order.subevents'
]
@dataclass(frozen=True)
class RelativeDate:
@@ -157,23 +144,6 @@ class RelativeDate:
if choice.base == "order" and isinstance(base, Order):
event = base.event
base_date = getattr(base, choice.attribute)
elif choice.base == "order.subevents" and isinstance(base, Order):
if not base.event.has_subevents:
raise ValueError("The order is for an event without subevents")
if choice.modifier == "first":
op = base.all_positions.order_by(f"subevent__{choice.attribute}").first()
if op is None:
raise ValueError("The order has no positions for subevents")
event = op.event
base_date = getattr(op.subevent, choice.attribute)
elif choice.modifier == "last":
op = base.all_positions.order_by(f"subevent__{choice.attribute}").last()
if op is None:
raise ValueError("The order has no positions for subevents")
event = op.event
base_date = getattr(op.subevent, choice.attribute)
else:
raise ValueError("The selected modifier does not exist")
elif choice.base == "event" and isinstance(base, SubEvent):
event = base.event
base_date = (getattr(base, choice.attribute) or
@@ -470,13 +440,10 @@ class RelativeDateTimeField(forms.MultiValueField):
('relative_minutes', _('Relative time:')),
]
self.relative_to_order = kwargs.pop('relative_to_order', False)
self.relative_to_subevent_positions = kwargs.pop('relative_to_subevent_positions', False)
possible_choices = copy.deepcopy(EVENT_BASE_CHOICES)
if self.relative_to_order:
possible_choices.extend(ORDER_BASE_CHOICES)
if self.relative_to_subevent_positions:
possible_choices.extend(SUBEVENT_BASE_CHOICES)
if kwargs.get('limit_choices'):
limit = kwargs.pop('limit_choices')
@@ -548,8 +515,6 @@ class RelativeDateTimeField(forms.MultiValueField):
possible_choices = copy.deepcopy(EVENT_BASE_CHOICES)
if self.relative_to_order:
possible_choices.extend(ORDER_BASE_CHOICES)
if self.relative_to_subevent_positions and event.has_subevents:
possible_choices.extend(SUBEVENT_BASE_CHOICES)
possible_choices = possible_choices
choices = _get_choices(possible_choices)
@@ -685,13 +650,10 @@ class RelativeDateField(RelativeDateTimeField):
status_choices.insert(0, ('unset', _('Not set')))
self.relative_to_order = kwargs.pop('relative_to_order', False)
self.relative_to_subevent_positions = kwargs.pop('relative_to_subevent_positions', False)
possible_choices = copy.deepcopy(EVENT_BASE_CHOICES)
if self.relative_to_order:
possible_choices.extend(ORDER_BASE_CHOICES)
if self.relative_to_subevent_positions:
possible_choices.extend(SUBEVENT_BASE_CHOICES)
choices = _get_choices(possible_choices)
@@ -728,8 +690,6 @@ class RelativeDateField(RelativeDateTimeField):
]
if self.relative_to_order:
choices += [(c.key, c.text) for c in ORDER_BASE_CHOICES]
if self.relative_to_subevent_positions and event.has_subevents:
choices += [(c.key, c.text) for c in SUBEVENT_BASE_CHOICES]
self.widget.widgets[reldateparts.indizes.rel_days_relationto].choices = choices
def compress(self, data_list):
+37 -39
View File
@@ -1,47 +1,45 @@
if (!window.__reldateInitialized) {
window.__reldateInitialized = true;
document.addEventListener('DOMContentLoaded', () => {
window.__reldateInitialized = true
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.reldatetime, .reldate').forEach(container => {
const groups = container.querySelectorAll('.radio')
document.querySelectorAll('.reldatetime, .reldate').forEach(container => {
const groups = container.querySelectorAll('.radio');
groups.forEach(group => {
const referenceSelect = group.querySelector('select[data-relative-choice]')
const beforeAfterSelect = group.querySelector('select[data-relation-choice]')
if (!referenceSelect || !beforeAfterSelect) return
groups.forEach(group => {
const referenceSelect = group.querySelector('select[data-relative-choice]');
const beforeAfterSelect = group.querySelector('select[data-relation-choice]');
if (!referenceSelect || !beforeAfterSelect) return;
const beforeOption = beforeAfterSelect.querySelector('option[value="before"]')
const afterOption = beforeAfterSelect.querySelector('option[value="after"]')
const beforeOption = beforeAfterSelect.querySelector('option[value="before"]');
const afterOption = beforeAfterSelect.querySelector('option[value="after"]');
const updateBeforeOption = () => {
let supportsBefore = referenceSelect.selectedOptions[0].hasAttribute('data-supports-before')
if (beforeOption) {
beforeOption.disabled = !beforeOption.disabled && !supportsBefore
}
const updateBeforeOption = () => {
let supportsBefore = referenceSelect.selectedOptions[0].hasAttribute('data-supports-before')
if (beforeOption){
beforeOption.disabled = !beforeOption.disabled && !supportsBefore;
}
let supportsAfter = referenceSelect.selectedOptions[0].hasAttribute('data-supports-after')
if (afterOption) {
afterOption.disabled = !afterOption.disabled && !supportsAfter
}
let supportsAfter = referenceSelect.selectedOptions[0].hasAttribute('data-supports-after')
if (afterOption){
afterOption.disabled = !afterOption.disabled && !supportsAfter;
}
let dirty = false
if (beforeOption.disabled && beforeAfterSelect.value === 'before') {
beforeAfterSelect.value = 'after'
dirty = true
}
if (afterOption.disabled && beforeAfterSelect.value === 'after') {
beforeAfterSelect.value = 'before'
dirty = true
}
let dirty = false;
if (beforeOption.disabled && beforeAfterSelect.value === 'before') {
beforeAfterSelect.value = 'after';
dirty = true;
}
if (afterOption.disabled && beforeAfterSelect.value === 'after'){
beforeAfterSelect.value = 'before';
dirty = true;
}
if (dirty){
beforeAfterSelect.dispatchEvent(new Event('change', { bubbles: true }));
}
};
referenceSelect.addEventListener('change', updateBeforeOption);
updateBeforeOption();
});
});
});
if (dirty) {
beforeAfterSelect.dispatchEvent(new Event('change', { bubbles: true }))
}
}
referenceSelect.addEventListener('change', updateBeforeOption)
updateBeforeOption()
})
})
})
}
-70
View File
@@ -206,73 +206,3 @@ def test_relative_to_order(event):
rdw = RelativeDateWrapper(RelativeDate(days=1, time=None, base_date_name='order__datetime', minutes=None, is_after=True))
assert rdw.datetime(order).astimezone(TOKYO) == datetime(2020, 3, 30, 18, 0, 0, tzinfo=TOKYO)
assert rdw.to_string() == 'RELDATE/1/-/order__datetime/after'
@pytest.mark.django_db
@scopes_disabled()
def test_relative_to_subevent(event):
event.has_subevents = True
event.save()
se1 = event.subevents.create(
name="Foobar",
date_from=datetime(2023, 6, 27, 5, 0, 0, tzinfo=TOKYO),
date_to=datetime(2023, 7, 27, 5, 0, 0, tzinfo=TOKYO),
date_admission=datetime(2023, 6, 27, 6, 0, 0, tzinfo=TOKYO),
)
se2 = event.subevents.create(
name="Foobar1",
date_from=datetime(2024, 6, 27, 5, 0, 0, tzinfo=TOKYO),
date_to=datetime(2024, 7, 27, 5, 0, 0, tzinfo=TOKYO),
date_admission=datetime(2024, 6, 27, 6, 0, 0, tzinfo=TOKYO),
)
order_moment = datetime(2020, 3, 29, 18, 0, 0, tzinfo=TOKYO)
order = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=order_moment,
expires=order_moment + timedelta(days=10),
sales_channel=event.organizer.sales_channels.get(identifier="web"),
total=23, locale='en'
)
item = event.items.create(name="Budget Ticket", default_price=23)
OrderPosition.objects.create(
order=order,
subevent=se1,
item=item,
tax_value=Decimal("3"),
price=Decimal("23"),
attendee_name_parts={'full_name': "Peter"},
secret="z3fsn8jyufm5kpk768q69gkbyr5f4h6w"
)
OrderPosition.objects.create(
order=order,
subevent=se2,
item=item,
tax_value=Decimal("3"),
price=Decimal("23"),
attendee_name_parts={'full_name': "Peter"},
secret="z3fsn8jyufm5kpk768q69gkbyr5f4h6w"
)
rdw = RelativeDate(days=1, time=None, base_date_name='order.subevents__date_from__first', minutes=None, is_after=True)
assert rdw.datetime(order).astimezone(TOKYO) == datetime(2023, 6, 28, 5, 0, 0, tzinfo=TOKYO)
assert rdw.to_string() == 'RELDATE/1/-/order.subevents__date_from__first/after'
rdw = RelativeDate(days=1, time=None, base_date_name='order.subevents__date_from__last', minutes=None, is_after=True)
assert rdw.datetime(order).astimezone(TOKYO) == datetime(2024, 6, 28, 5, 0, 0, tzinfo=TOKYO)
assert rdw.to_string() == 'RELDATE/1/-/order.subevents__date_from__last/after'
rdw = RelativeDate(days=1, time=None, base_date_name='order.subevents__date_to__first', minutes=None, is_after=True)
assert rdw.datetime(order).astimezone(TOKYO) == datetime(2023, 7, 28, 5, 0, 0, tzinfo=TOKYO)
assert rdw.to_string() == 'RELDATE/1/-/order.subevents__date_to__first/after'
rdw = RelativeDate(days=1, time=None, base_date_name='order.subevents__date_to__last', minutes=None, is_after=True)
assert rdw.datetime(order).astimezone(TOKYO) == datetime(2024, 7, 28, 5, 0, 0, tzinfo=TOKYO)
assert rdw.to_string() == 'RELDATE/1/-/order.subevents__date_to__last/after'
rdw = RelativeDate(days=1, time=None, base_date_name='order.subevents__date_admission__first', minutes=None, is_after=True)
assert rdw.datetime(order).astimezone(TOKYO) == datetime(2023, 6, 28, 6, 0, 0, tzinfo=TOKYO)
assert rdw.to_string() == 'RELDATE/1/-/order.subevents__date_admission__first/after'
rdw = RelativeDate(days=1, time=None, base_date_name='order.subevents__date_admission__last', minutes=None, is_after=True)
assert rdw.datetime(order).astimezone(TOKYO) == datetime(2024, 6, 28, 6, 0, 0, tzinfo=TOKYO)
assert rdw.to_string() == 'RELDATE/1/-/order.subevents__date_admission__last/after'