diff --git a/doc/api/resources/checkinlists.rst b/doc/api/resources/checkinlists.rst index 29c33cd7df..0db56047d6 100644 --- a/doc/api/resources/checkinlists.rst +++ b/doc/api/resources/checkinlists.rst @@ -31,8 +31,6 @@ subevent integer ID of the date position_count integer Number of tickets that match this list (read-only). checkin_count integer Number of check-ins performed on this list (read-only). include_pending boolean If ``true``, the check-in list also contains tickets from orders in pending state. -auto_checkin_sales_channels list of strings All items on the check-in list will be automatically marked as checked-in when purchased through any of the listed sales channels. - **Deprecated, will be removed in pretix 2024.10.** Use :ref:`rest-autocheckinrules`: instead. allow_multiple_entries boolean If ``true``, subsequent scans of a ticket on this list should not show a warning but instead be stored as an additional check-in. allow_entry_after_exit boolean If ``true``, subsequent scans of a ticket on this list are valid if the last scan of the ticket was an exit scan. rules object Custom check-in logic. The contents of this field are currently not considered a stable API and modifications through the API are highly discouraged. @@ -91,10 +89,7 @@ Endpoints "allow_entry_after_exit": true, "exit_all_at": null, "rules": {}, - "addon_match": false, - "auto_checkin_sales_channels": [ - "pretixpos" - ] + "addon_match": false } ] } @@ -146,10 +141,7 @@ Endpoints "allow_entry_after_exit": true, "exit_all_at": null, "rules": {}, - "addon_match": false, - "auto_checkin_sales_channels": [ - "pretixpos" - ] + "addon_match": false } :param organizer: The ``slug`` field of the organizer to fetch @@ -246,10 +238,7 @@ Endpoints "subevent": null, "allow_multiple_entries": false, "allow_entry_after_exit": true, - "addon_match": false, - "auto_checkin_sales_channels": [ - "pretixpos" - ] + "addon_match": false } **Example response**: @@ -271,10 +260,7 @@ Endpoints "subevent": null, "allow_multiple_entries": false, "allow_entry_after_exit": true, - "addon_match": false, - "auto_checkin_sales_channels": [ - "pretixpos" - ] + "addon_match": false } :param organizer: The ``slug`` field of the organizer of the event/item to create a list for @@ -326,10 +312,7 @@ Endpoints "subevent": null, "allow_multiple_entries": false, "allow_entry_after_exit": true, - "addon_match": false, - "auto_checkin_sales_channels": [ - "pretixpos" - ] + "addon_match": false } :param organizer: The ``slug`` field of the organizer to modify diff --git a/src/pretix/api/serializers/checkin.py b/src/pretix/api/serializers/checkin.py index fea029dad1..c13a14a62e 100644 --- a/src/pretix/api/serializers/checkin.py +++ b/src/pretix/api/serializers/checkin.py @@ -26,31 +26,22 @@ from rest_framework.exceptions import ValidationError from pretix.api.serializers.event import SubEventSerializer from pretix.api.serializers.i18n import I18nAwareModelSerializer from pretix.base.media import MEDIA_TYPES -from pretix.base.models import Checkin, CheckinList, SalesChannel +from pretix.base.models import Checkin, CheckinList class CheckinListSerializer(I18nAwareModelSerializer): checkin_count = serializers.IntegerField(read_only=True) position_count = serializers.IntegerField(read_only=True) - auto_checkin_sales_channels = serializers.SlugRelatedField( - slug_field="identifier", - queryset=SalesChannel.objects.none(), - required=False, - allow_empty=True, - many=True, - ) class Meta: model = CheckinList fields = ('id', 'name', 'all_products', 'limit_products', 'subevent', 'checkin_count', 'position_count', - 'include_pending', 'auto_checkin_sales_channels', 'allow_multiple_entries', 'allow_entry_after_exit', + 'include_pending', 'allow_multiple_entries', 'allow_entry_after_exit', 'rules', 'exit_all_at', 'addon_match', 'ignore_in_statistics', 'consider_tickets_used') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['auto_checkin_sales_channels'].child_relation.queryset = self.context['event'].organizer.sales_channels.all() - if 'subevent' in self.context['request'].query_params.getlist('expand'): self.fields['subevent'] = SubEventSerializer(read_only=True) diff --git a/src/pretix/api/views/checkin.py b/src/pretix/api/views/checkin.py index eed32e5531..82f0eac191 100644 --- a/src/pretix/api/views/checkin.py +++ b/src/pretix/api/views/checkin.py @@ -116,7 +116,7 @@ class CheckinListViewSet(viewsets.ModelViewSet): if 'subevent' in self.request.query_params.getlist('expand'): qs = qs.prefetch_related( 'subevent', 'subevent__event', 'subevent__subeventitem_set', 'subevent__subeventitemvariation_set', - 'subevent__seat_category_mappings', 'subevent__meta_values', 'auto_checkin_sales_channels' + 'subevent__seat_category_mappings', 'subevent__meta_values', ) return qs diff --git a/src/pretix/base/migrations/0273_remove_checkinlist_auto_checkin_sales_channels.py b/src/pretix/base/migrations/0273_remove_checkinlist_auto_checkin_sales_channels.py new file mode 100644 index 0000000000..9517a882bc --- /dev/null +++ b/src/pretix/base/migrations/0273_remove_checkinlist_auto_checkin_sales_channels.py @@ -0,0 +1,48 @@ +# Generated by Django 4.2.16 on 2024-10-29 15:03 + +from django.db import migrations + + +def migrate_autocheckin(apps, schema_editor): + CheckinList = apps.get_model("pretixbase", "CheckinList") + AutoCheckinRule = apps.get_model("autocheckin", "AutoCheckinRule") + + for cl in CheckinList.objects.filter(auto_checkin_sales_channels__isnull=False).select_related("event", "event__organizer"): + sales_channels = cl.auto_checkin_sales_channels.all() + all_sales_channels = cl.event.organizer.sales_channels.all() + + if "pretix.plugins.autocheckin" not in cl.event.plugins: + cl.event.plugins = cl.event.plugins + ",pretix.plugins.autocheckin" + cl.event.save() + + r = AutoCheckinRule.objects.get_or_create( + list=cl, + event=cl.event, + all_products=True, + all_payment_methods=True, + defaults=dict( + mode="placed", + all_sales_channels=len(sales_channels) == len(all_sales_channels), + ) + )[0] + if len(sales_channels) != len(all_sales_channels): + r.limit_sales_channels.set(sales_channels) + + +class Migration(migrations.Migration): + + dependencies = [ + ("pretixbase", "0272_printlog"), + ("autocheckin", "0001_initial"), + ] + + operations = [ + migrations.RunPython( + migrate_autocheckin, + migrations.RunPython.noop, + ), + migrations.RemoveField( + model_name="checkinlist", + name="auto_checkin_sales_channels", + ), + ] diff --git a/src/pretix/base/models/checkin.py b/src/pretix/base/models/checkin.py index 4545649759..9f42a9844d 100644 --- a/src/pretix/base/models/checkin.py +++ b/src/pretix/base/models/checkin.py @@ -99,14 +99,6 @@ class CheckinList(LoggedModel): verbose_name=_('Automatically check out everyone at'), null=True, blank=True ) - auto_checkin_sales_channels = models.ManyToManyField( - "SalesChannel", - verbose_name=_('Sales channels to automatically check in'), - help_text=_('This option is deprecated and will be removed in the next months. As a replacement, our new plugin ' - '"Auto check-in" can be used. When we remove this option, we will automatically migrate your event ' - 'to use the new plugin.'), - blank=True, - ) rules = models.JSONField(default=dict, blank=True) objects = ScopedManager(organizer='event__organizer') diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index 7b2bec1e7a..caacf81922 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -1024,10 +1024,9 @@ class Event(EventMixin, LoggedModel): checkin_list_map = {} for cl in other.checkin_lists.filter(subevent__isnull=True).prefetch_related( - 'limit_products', 'auto_checkin_sales_channels' + 'limit_products' ): items = list(cl.limit_products.all()) - auto_checkin_sales_channels = list(cl.auto_checkin_sales_channels.all()) checkin_list_map[cl.pk] = cl cl.pk = None cl._prefetched_objects_cache = {} @@ -1039,8 +1038,6 @@ class Event(EventMixin, LoggedModel): cl.log_action('pretix.object.cloned') for i in items: cl.limit_products.add(item_map[i.pk]) - if auto_checkin_sales_channels: - cl.auto_checkin_sales_channels.set(self.organizer.sales_channels.filter(identifier__in=[s.identifier for s in auto_checkin_sales_channels])) if other.seating_plan: if other.seating_plan.organizer_id == self.organizer_id: diff --git a/src/pretix/base/services/checkin.py b/src/pretix/base/services/checkin.py index 9b5731ec51..7c2e6237fa 100644 --- a/src/pretix/base/services/checkin.py +++ b/src/pretix/base/services/checkin.py @@ -57,7 +57,7 @@ from pretix.base.models import ( Checkin, CheckinList, Device, Event, Gate, Item, ItemVariation, Order, OrderPosition, QuestionOption, ) -from pretix.base.signals import checkin_created, order_placed, periodic_task +from pretix.base.signals import checkin_created, periodic_task from pretix.helpers import OF_SELF from pretix.helpers.jsonlogic import Logic from pretix.helpers.jsonlogic_boolalg import convert_to_dnf @@ -1154,23 +1154,6 @@ def perform_checkin(op: OrderPosition, clist: CheckinList, given_answers: dict, ) -@receiver(order_placed, dispatch_uid="legacy_autocheckin_order_placed") -def order_placed(sender, **kwargs): - order = kwargs['order'] - event = sender - - cls = list(event.checkin_lists.filter(auto_checkin_sales_channels=order.sales_channel).prefetch_related( - 'limit_products')) - if not cls: - return - for op in order.positions.all(): - for cl in cls: - if cl.all_products or op.item_id in {i.pk for i in cl.limit_products.all()}: - if not cl.subevent_id or cl.subevent_id == op.subevent_id: - ci = Checkin.objects.create(position=op, list=cl, auto_checked_in=True, type=Checkin.TYPE_ENTRY) - checkin_created.send(event, checkin=ci) - - @receiver(periodic_task, dispatch_uid="autocheckout_exit_all") @scopes_disabled() def process_exit_all(sender, **kwargs): diff --git a/src/pretix/control/forms/checkin.py b/src/pretix/control/forms/checkin.py index 52a52217fd..207a3d78c5 100644 --- a/src/pretix/control/forms/checkin.py +++ b/src/pretix/control/forms/checkin.py @@ -33,9 +33,7 @@ from django_scopes.forms import ( from pretix.base.forms.widgets import SplitDateTimePickerWidget from pretix.base.models import Gate from pretix.base.models.checkin import Checkin, CheckinList -from pretix.control.forms import ( - ItemMultipleChoiceField, SalesChannelCheckboxSelectMultiple, -) +from pretix.control.forms import ItemMultipleChoiceField from pretix.control.forms.widgets import Select2 @@ -67,10 +65,6 @@ class CheckinListForm(forms.ModelForm): kwargs.pop('locales', None) super().__init__(**kwargs) self.fields['limit_products'].queryset = self.event.items.all() - self.fields['auto_checkin_sales_channels'].queryset = self.event.organizer.sales_channels.all() - self.fields['auto_checkin_sales_channels'].widget = SalesChannelCheckboxSelectMultiple( - self.event, choices=self.fields['auto_checkin_sales_channels'].widget.choices - ) if not self.event.organizer.gates.exists(): del self.fields['gates'] @@ -102,7 +96,6 @@ class CheckinListForm(forms.ModelForm): 'limit_products', 'subevent', 'include_pending', - 'auto_checkin_sales_channels', 'allow_multiple_entries', 'allow_entry_after_exit', 'rules', @@ -125,7 +118,6 @@ class CheckinListForm(forms.ModelForm): 'limit_products': ItemMultipleChoiceField, 'gates': SafeModelMultipleChoiceField, 'subevent': SafeModelChoiceField, - 'auto_checkin_sales_channels': SafeModelMultipleChoiceField, 'exit_all_at': NextTimeField, } diff --git a/src/pretix/control/templates/pretixcontrol/checkin/list_edit.html b/src/pretix/control/templates/pretixcontrol/checkin/list_edit.html index 44e1386e33..a56b90b83f 100644 --- a/src/pretix/control/templates/pretixcontrol/checkin/list_edit.html +++ b/src/pretix/control/templates/pretixcontrol/checkin/list_edit.html @@ -67,7 +67,6 @@ {% bootstrap_field form.allow_entry_after_exit layout="control" %} {% bootstrap_field form.addon_match layout="control" %} {% bootstrap_field form.exit_all_at layout="control" %} - {% bootstrap_field form.auto_checkin_sales_channels layout="control" %} {% if form.gates %} {% bootstrap_field form.gates layout="control" %} {% endif %} diff --git a/src/pretix/control/templates/pretixcontrol/checkin/lists.html b/src/pretix/control/templates/pretixcontrol/checkin/lists.html index 00d3de598a..e131f7fdb0 100644 --- a/src/pretix/control/templates/pretixcontrol/checkin/lists.html +++ b/src/pretix/control/templates/pretixcontrol/checkin/lists.html @@ -101,7 +101,6 @@ {% endif %} -