forked from CGM_Public/pretix_original
Allow to import orders (#1516)
* Allow to import orders * seats, subevents * Plugin support * Add docs * Warn about lack of quota handling * Control interface test * Test skeleton * First tests for the impotr columns * Add tests for all columns * Fix question validation
This commit is contained in:
125
src/pretix/control/views/orderimport.py
Normal file
125
src/pretix/control/views/orderimport.py
Normal file
@@ -0,0 +1,125 @@
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.generic import FormView, TemplateView
|
||||
|
||||
from pretix.base.models import CachedFile
|
||||
from pretix.base.services.orderimport import import_orders, parse_csv
|
||||
from pretix.base.views.tasks import AsyncAction
|
||||
from pretix.control.forms.orderimport import ProcessForm
|
||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ImportView(EventPermissionRequiredMixin, TemplateView):
|
||||
template_name = 'pretixcontrol/orders/import_start.html'
|
||||
permission = 'can_change_orders'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if 'file' not in request.FILES:
|
||||
return redirect(reverse('control:event.orders.import', kwargs={
|
||||
'event': request.event.slug,
|
||||
'organizer': request.organizer.slug,
|
||||
}))
|
||||
if not request.FILES['file'].name.endswith('.csv'):
|
||||
messages.error(request, _('Please only upload CSV files.'))
|
||||
return redirect(reverse('control:event.orders.import', kwargs={
|
||||
'event': request.event.slug,
|
||||
'organizer': request.organizer.slug,
|
||||
}))
|
||||
if request.FILES['file'].size > 1024 * 1024 * 10:
|
||||
messages.error(request, _('Please do not upload files larger than 10 MB.'))
|
||||
return redirect(reverse('control:event.orders.import', kwargs={
|
||||
'event': request.event.slug,
|
||||
'organizer': request.organizer.slug,
|
||||
}))
|
||||
|
||||
cf = CachedFile.objects.create(
|
||||
expires=now() + timedelta(days=1),
|
||||
date=now(),
|
||||
filename='import.csv',
|
||||
type='text/csv',
|
||||
)
|
||||
cf.file.save('import.csv', request.FILES['file'])
|
||||
return redirect(reverse('control:event.orders.import.process', kwargs={
|
||||
'event': request.event.slug,
|
||||
'organizer': request.organizer.slug,
|
||||
'file': cf.id
|
||||
}))
|
||||
|
||||
|
||||
class ProcessView(EventPermissionRequiredMixin, AsyncAction, FormView):
|
||||
permission = 'can_change_orders'
|
||||
template_name = 'pretixcontrol/orders/import_process.html'
|
||||
form_class = ProcessForm
|
||||
task = import_orders
|
||||
known_errortypes = ['DataImportError']
|
||||
|
||||
def get_form_kwargs(self):
|
||||
k = super().get_form_kwargs()
|
||||
k.update({
|
||||
'event': self.request.event,
|
||||
'initial': self.request.event.settings.order_import_settings,
|
||||
'headers': self.parsed.fieldnames
|
||||
})
|
||||
return k
|
||||
|
||||
def form_valid(self, form):
|
||||
self.request.event.settings.order_import_settings = form.cleaned_data
|
||||
return self.do(
|
||||
self.request.event.pk, self.file.id, form.cleaned_data, self.request.LANGUAGE_CODE,
|
||||
self.request.user.pk
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def file(self):
|
||||
return get_object_or_404(CachedFile, pk=self.kwargs.get("file"), filename="import.csv")
|
||||
|
||||
@cached_property
|
||||
def parsed(self):
|
||||
return parse_csv(self.file.file, 1024 * 1024)
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if 'async_id' in request.GET and settings.HAS_CELERY:
|
||||
return self.get_result(request)
|
||||
return FormView.get(self, request, *args, **kwargs)
|
||||
|
||||
def get_success_message(self, value):
|
||||
return _('The import was successful.')
|
||||
|
||||
def get_success_url(self, value):
|
||||
return reverse('control:event.orders', kwargs={
|
||||
'event': self.request.event.slug,
|
||||
'organizer': self.request.organizer.slug,
|
||||
})
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not self.parsed:
|
||||
messages.error(request, _('We\'ve been unable to parse the uploaded file as a CSV file.'))
|
||||
return redirect(reverse('control:event.orders.import', kwargs={
|
||||
'event': request.event.slug,
|
||||
'organizer': request.organizer.slug,
|
||||
}))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_error_url(self):
|
||||
return reverse('control:event.orders.import.process', kwargs={
|
||||
'event': self.request.event.slug,
|
||||
'organizer': self.request.organizer.slug,
|
||||
'file': self.file.id
|
||||
})
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['file'] = self.file
|
||||
ctx['parsed'] = self.parsed
|
||||
ctx['sample_rows'] = list(self.parsed)[:3]
|
||||
return ctx
|
||||
Reference in New Issue
Block a user