mirror of
https://github.com/pretix/pretix.git
synced 2026-05-06 15:24:02 +00:00
156 lines
6.1 KiB
Python
156 lines
6.1 KiB
Python
#
|
|
# This file is part of pretix (Community Edition).
|
|
#
|
|
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
|
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
|
# Public License as published by the Free Software Foundation in version 3 of the License.
|
|
#
|
|
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
|
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
|
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
|
# this file, see <https://pretix.eu/about/en/license>.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
|
# <https://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
from itertools import groupby
|
|
|
|
from django.contrib import messages
|
|
from django.db.models import Q
|
|
from django.dispatch import receiver
|
|
from django.http import HttpResponseNotAllowed
|
|
from django.shortcuts import redirect
|
|
from django.template.loader import get_template
|
|
from django.utils.timezone import now
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.views.generic import ListView
|
|
|
|
from pretix.base.datasync.datasync import datasync_providers
|
|
from pretix.base.models import Event, Order
|
|
from pretix.base.models.datasync import OrderSyncQueue
|
|
from pretix.base.services.datasync import sync_single
|
|
from pretix.control.permissions import (
|
|
AdministratorPermissionRequiredMixin, EventPermissionRequiredMixin,
|
|
OrganizerPermissionRequiredMixin,
|
|
)
|
|
from pretix.control.signals import order_info
|
|
from pretix.control.views.orders import OrderView
|
|
|
|
|
|
@receiver(order_info, dispatch_uid="datasync_control_order_info")
|
|
def on_control_order_info(sender: Event, request, order: Order, **kwargs):
|
|
providers = [provider for provider, meta in datasync_providers.filter(active_in=sender)]
|
|
if not providers:
|
|
return ""
|
|
|
|
queued = {p.sync_provider: p for p in order.queued_sync_jobs.all()}
|
|
objects = {
|
|
provider: list(objects)
|
|
for (provider, objects)
|
|
in groupby(order.sync_results.order_by('sync_provider').all(), key=lambda o: o.sync_provider)
|
|
}
|
|
providers = [(provider.identifier, provider.display_name, queued.get(provider.identifier), objects.get(provider.identifier)) for provider in providers]
|
|
|
|
template = get_template("pretixcontrol/datasync/control_order_info.html")
|
|
ctx = {
|
|
"order": order,
|
|
"request": request,
|
|
"event": sender,
|
|
"providers": providers,
|
|
"now": now(),
|
|
}
|
|
return template.render(ctx, request=request)
|
|
|
|
|
|
class ControlSyncJob(OrderView):
|
|
permission = 'can_change_orders'
|
|
|
|
def post(self, request, provider, *args, **kwargs):
|
|
prov, meta = datasync_providers.get(active_in=self.request.event, identifier=provider)
|
|
|
|
if self.request.POST.get("queue_sync") == "true":
|
|
prov.enqueue_order(self.order, 'user')
|
|
messages.success(self.request, _('The sync job has been enqueued and will run in the next minutes.'))
|
|
elif self.request.POST.get("cancel_job"):
|
|
job = self.order.queued_sync_jobs.get(pk=self.request.POST.get("cancel_job"))
|
|
if job.in_flight:
|
|
messages.warning(self.request, _('The sync job is already in progress.'))
|
|
else:
|
|
job.delete()
|
|
messages.success(self.request, _('The sync job has been canceled.'))
|
|
elif self.request.POST.get("run_job_now"):
|
|
job = self.order.queued_sync_jobs.get(pk=self.request.POST.get("run_job_now"))
|
|
if job.in_flight:
|
|
messages.success(self.request, _('The sync job is already in progress.'))
|
|
else:
|
|
job.not_before = now()
|
|
job.need_manual_retry = None
|
|
job.save()
|
|
sync_single.apply_async(args=(job.pk,))
|
|
messages.success(self.request, _('The sync job has been set to run as soon as possible.'))
|
|
|
|
return redirect(self.get_order_url())
|
|
|
|
def get(self, *args, **kwargs):
|
|
return HttpResponseNotAllowed(['POST'])
|
|
|
|
|
|
class FailedSyncJobsView(ListView):
|
|
template_name = 'pretixcontrol/datasync/failed_jobs.html'
|
|
model = OrderSyncQueue
|
|
context_object_name = 'queue_items'
|
|
paginate_by = 100
|
|
ordering = ('triggered',)
|
|
|
|
def get_queryset(self):
|
|
return super().get_queryset().filter(
|
|
Q(need_manual_retry__isnull=False)
|
|
| Q(failed_attempts__gt=0)
|
|
).select_related(
|
|
'order'
|
|
)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
items = self.get_queryset().filter(pk__in=request.POST.getlist('idlist'))
|
|
|
|
if self.request.POST.get("action") == "retry":
|
|
for item in items:
|
|
item.not_before = now()
|
|
item.need_manual_retry = None
|
|
item.save()
|
|
messages.success(self.request, _('The selected jobs have been set to run as soon as possible.'))
|
|
elif self.request.POST.get("action") == "cancel":
|
|
items.delete()
|
|
messages.success(self.request, _('The selected jobs have been canceled.'))
|
|
|
|
return redirect(request.get_full_path())
|
|
|
|
|
|
class GlobalFailedSyncJobsView(AdministratorPermissionRequiredMixin, FailedSyncJobsView):
|
|
pass
|
|
|
|
|
|
class OrganizerFailedSyncJobsView(OrganizerPermissionRequiredMixin, FailedSyncJobsView):
|
|
permission = "can_change_organizer_settings"
|
|
|
|
def get_queryset(self):
|
|
return super().get_queryset().filter(
|
|
event__organizer=self.request.organizer
|
|
)
|
|
|
|
|
|
class EventFailedSyncJobsView(EventPermissionRequiredMixin, FailedSyncJobsView):
|
|
permission = "can_change_event_settings"
|
|
|
|
def get_queryset(self):
|
|
return super().get_queryset().filter(
|
|
event=self.request.event
|
|
)
|