forked from CGM_Public/pretix_original
Creating device objects
This commit is contained in:
@@ -6,7 +6,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
from i18nfield.forms import I18nFormField, I18nTextarea
|
from i18nfield.forms import I18nFormField, I18nTextarea
|
||||||
|
|
||||||
from pretix.base.forms import I18nModelForm, SettingsForm
|
from pretix.base.forms import I18nModelForm, SettingsForm
|
||||||
from pretix.base.models import Organizer, Team
|
from pretix.base.models import Device, Organizer, Team
|
||||||
from pretix.control.forms import ExtFileField, MultipleLanguagesWidget
|
from pretix.control.forms import ExtFileField, MultipleLanguagesWidget
|
||||||
from pretix.multidomain.models import KnownDomain
|
from pretix.multidomain.models import KnownDomain
|
||||||
from pretix.presale.style import get_fonts
|
from pretix.presale.style import get_fonts
|
||||||
@@ -107,7 +107,7 @@ class TeamForm(forms.ModelForm):
|
|||||||
data = super().clean()
|
data = super().clean()
|
||||||
if self.instance.pk and not data['can_change_teams']:
|
if self.instance.pk and not data['can_change_teams']:
|
||||||
if not self.instance.organizer.teams.exclude(pk=self.instance.pk).filter(
|
if not self.instance.organizer.teams.exclude(pk=self.instance.pk).filter(
|
||||||
can_change_teams=True, members__isnull=False
|
can_change_teams=True, members__isnull=False
|
||||||
).exists():
|
).exists():
|
||||||
raise ValidationError(_('The changes could not be saved because there would be no remaining team with '
|
raise ValidationError(_('The changes could not be saved because there would be no remaining team with '
|
||||||
'the permission to change teams and permissions.'))
|
'the permission to change teams and permissions.'))
|
||||||
@@ -115,6 +115,23 @@ class TeamForm(forms.ModelForm):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceForm(forms.ModelForm):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
organizer = kwargs.pop('organizer')
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.fields['limit_events'].queryset = organizer.events.all()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Device
|
||||||
|
fields = ['name', 'all_events', 'limit_events']
|
||||||
|
widgets = {
|
||||||
|
'limit_events': forms.CheckboxSelectMultiple(attrs={
|
||||||
|
'data-inverse-dependency': '#id_all_events'
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class OrganizerSettingsForm(SettingsForm):
|
class OrganizerSettingsForm(SettingsForm):
|
||||||
|
|
||||||
organizer_info_text = I18nFormField(
|
organizer_info_text = I18nFormField(
|
||||||
|
|||||||
@@ -33,6 +33,13 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if 'can_change_organizer_settings' in request.orgapermset %}
|
||||||
|
<li {% if "organizer.device" in url_name %}class="active"{% endif %}>
|
||||||
|
<a href="{% url "control:organizer.devices" organizer=organizer.slug %}">
|
||||||
|
{% trans "Devices" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
{% for nav in nav_organizer %}
|
{% for nav in nav_organizer %}
|
||||||
<li {% if nav.active %}class="active"{% endif %}>
|
<li {% if nav.active %}class="active"{% endif %}>
|
||||||
<a href="{{ nav.url }}">
|
<a href="{{ nav.url }}">
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{% extends "pretixcontrol/organizers/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% block inner %}
|
||||||
|
<legend>{% trans "Connect to device:" %} {{ device.name }}</legend>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{% extends "pretixcontrol/organizers/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% block inner %}
|
||||||
|
{% if device %}
|
||||||
|
<legend>{% trans "Device:" %} {{ device.name }}</legend>
|
||||||
|
{% else %}
|
||||||
|
<legend>{% trans "Connect a new device" %}</legend>
|
||||||
|
{% endif %}
|
||||||
|
<form class="form-horizontal" action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form_errors form %}
|
||||||
|
{% bootstrap_field form.name layout="control" %}
|
||||||
|
{% bootstrap_field form.all_events layout="control" %}
|
||||||
|
{% bootstrap_field form.limit_events layout="control" %}
|
||||||
|
<div class="form-group submit-group">
|
||||||
|
<button type="submit" class="btn btn-primary btn-save">
|
||||||
|
{% trans "Save" %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
{% extends "pretixcontrol/organizers/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% block inner %}
|
||||||
|
<legend>
|
||||||
|
{% trans "Connected devices" %}
|
||||||
|
</legend>
|
||||||
|
{% if devices|length == 0 %}
|
||||||
|
<div class="empty-collection">
|
||||||
|
<p>
|
||||||
|
{% blocktrans trimmed %}
|
||||||
|
You haven't connected any hardware devices yet.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a href="{% url "control:organizer.device.add" organizer=request.organizer.slug %}"
|
||||||
|
class="btn btn-primary btn-lg"><i class="fa fa-plus"></i> {% trans "Connect a device" %}</a>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
<a href="{% url "control:organizer.device.add" organizer=request.organizer.slug %}"
|
||||||
|
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Connect a device" %}</a>
|
||||||
|
</p>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-condensed table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "Device ID" %}</th>
|
||||||
|
<th>{% trans "Name" %}</th>
|
||||||
|
<th>{% trans "Hardware model" %}</th>
|
||||||
|
<th>{% trans "Software" %}</th>
|
||||||
|
<th>{% trans "Setup date" %}</th>
|
||||||
|
<th>{% trans "Events" %}</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for d in devices %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ d.device_id }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ d.name }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ d.hardware_brand|default_if_none:"" }} {{ d.hardware_model|default_if_none:"" }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ d.software_brand|default_if_none:"" }} {{ d.software_version|default_if_none:"" }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if d.initialized %}
|
||||||
|
{{ d.initialized|date:"SHORT_DATETIME_FORMAT" }}
|
||||||
|
{% else %}
|
||||||
|
<em>{% trans "Not yet initialized" %}</em>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if d.all_events %}
|
||||||
|
{% trans "All" %}
|
||||||
|
{% else %}
|
||||||
|
<ul>
|
||||||
|
{% for e in d.limit_events.all %}
|
||||||
|
<li>
|
||||||
|
<a href="{% url "control:event.index" organizer=request.organizer.slug event=e.slug %}">
|
||||||
|
{{ e }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
{% if not d.initialized %}
|
||||||
|
<a href="{% url "control:organizer.device.connect" organizer=request.organizer.slug device=d.id %}"
|
||||||
|
class="btn btn-primary btn-sm"><i class="fa fa-link"></i>
|
||||||
|
{% trans "Connect" %}</a>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{% url "control:organizer.device.edit" organizer=request.organizer.slug device=d.id %}"
|
||||||
|
class="btn btn-default btn-sm"><i class="fa fa-edit"></i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% include "pretixcontrol/pagination.html" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
@@ -68,6 +68,13 @@ urlpatterns = [
|
|||||||
url(r'^organizer/(?P<organizer>[^/]+)/edit$', organizer.OrganizerUpdate.as_view(), name='organizer.edit'),
|
url(r'^organizer/(?P<organizer>[^/]+)/edit$', organizer.OrganizerUpdate.as_view(), name='organizer.edit'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/settings/display$', organizer.OrganizerDisplaySettings.as_view(),
|
url(r'^organizer/(?P<organizer>[^/]+)/settings/display$', organizer.OrganizerDisplaySettings.as_view(),
|
||||||
name='organizer.display'),
|
name='organizer.display'),
|
||||||
|
url(r'^organizer/(?P<organizer>[^/]+)/devices$', organizer.DeviceListView.as_view(), name='organizer.devices'),
|
||||||
|
url(r'^organizer/(?P<organizer>[^/]+)/device/add$', organizer.DeviceCreateView.as_view(),
|
||||||
|
name='organizer.device.add'),
|
||||||
|
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/edit', organizer.DeviceUpdateView.as_view(),
|
||||||
|
name='organizer.device.edit'),
|
||||||
|
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/connect', organizer.DeviceConnectView.as_view(),
|
||||||
|
name='organizer.device.connect'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/teams$', organizer.TeamListView.as_view(), name='organizer.teams'),
|
url(r'^organizer/(?P<organizer>[^/]+)/teams$', organizer.TeamListView.as_view(), name='organizer.teams'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/team/add$', organizer.TeamCreateView.as_view(), name='organizer.team.add'),
|
url(r'^organizer/(?P<organizer>[^/]+)/team/add$', organizer.TeamCreateView.as_view(), name='organizer.team.add'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/$', organizer.TeamMemberView.as_view(),
|
url(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/$', organizer.TeamMemberView.as_view(),
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ from django.views.generic import (
|
|||||||
CreateView, DeleteView, DetailView, FormView, ListView, UpdateView,
|
CreateView, DeleteView, DetailView, FormView, ListView, UpdateView,
|
||||||
)
|
)
|
||||||
|
|
||||||
from pretix.base.models import Organizer, Team, TeamInvite, User
|
from pretix.base.models import Device, Organizer, Team, TeamInvite, User
|
||||||
from pretix.base.models.event import EventMetaProperty
|
from pretix.base.models.event import EventMetaProperty
|
||||||
from pretix.base.models.organizer import TeamAPIToken
|
from pretix.base.models.organizer import TeamAPIToken
|
||||||
from pretix.base.services.mail import SendMailException, mail
|
from pretix.base.services.mail import SendMailException, mail
|
||||||
from pretix.control.forms.filter import OrganizerFilterForm
|
from pretix.control.forms.filter import OrganizerFilterForm
|
||||||
from pretix.control.forms.organizer import (
|
from pretix.control.forms.organizer import (
|
||||||
EventMetaPropertyForm, OrganizerDisplaySettingsForm, OrganizerForm,
|
DeviceForm, EventMetaPropertyForm, OrganizerDisplaySettingsForm,
|
||||||
OrganizerSettingsForm, OrganizerUpdateForm, TeamForm,
|
OrganizerForm, OrganizerSettingsForm, OrganizerUpdateForm, TeamForm,
|
||||||
)
|
)
|
||||||
from pretix.control.permissions import OrganizerPermissionRequiredMixin
|
from pretix.control.permissions import OrganizerPermissionRequiredMixin
|
||||||
from pretix.control.signals import nav_organizer
|
from pretix.control.signals import nav_organizer
|
||||||
@@ -576,3 +576,99 @@ class TeamMemberView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin,
|
|||||||
'organizer': self.request.organizer.slug,
|
'organizer': self.request.organizer.slug,
|
||||||
'team': self.object.pk
|
'team': self.object.pk
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceListView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, ListView):
|
||||||
|
model = Device
|
||||||
|
template_name = 'pretixcontrol/organizers/devices.html'
|
||||||
|
permission = 'can_change_organizer_settings'
|
||||||
|
context_object_name = 'devices'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return self.request.organizer.devices.prefetch_related('limit_events')
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, CreateView):
|
||||||
|
model = Device
|
||||||
|
template_name = 'pretixcontrol/organizers/device_edit.html'
|
||||||
|
permission = 'can_change_organizer_settings'
|
||||||
|
form_class = DeviceForm
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
kwargs['organizer'] = self.request.organizer
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse('control:organizer.device.connect', kwargs={
|
||||||
|
'organizer': self.request.organizer.slug,
|
||||||
|
'device': self.object.pk
|
||||||
|
})
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
form.instance.organizer = self.request.organizer
|
||||||
|
ret = super().form_valid(form)
|
||||||
|
form.instance.members.add(self.request.user)
|
||||||
|
form.instance.log_action('pretix.device.created', user=self.request.user, data={
|
||||||
|
k: getattr(self.object, k) if k != 'limit_events' else [e.id for e in getattr(self.object, k).all()]
|
||||||
|
for k in form.changed_data
|
||||||
|
})
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def form_invalid(self, form):
|
||||||
|
messages.error(self.request, _('Your changes could not be saved.'))
|
||||||
|
return super().form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, UpdateView):
|
||||||
|
model = Device
|
||||||
|
template_name = 'pretixcontrol/organizers/device_edit.html'
|
||||||
|
permission = 'can_change_organizer_settings'
|
||||||
|
context_object_name = 'device'
|
||||||
|
form_class = DeviceForm
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
kwargs['organizer'] = self.request.organizer
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
return get_object_or_404(Device, organizer=self.request.organizer, pk=self.kwargs.get('device'))
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse('control:organizer.devices', kwargs={
|
||||||
|
'organizer': self.request.organizer.slug,
|
||||||
|
})
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
if form.has_changed():
|
||||||
|
self.object.log_action('pretix.device.changed', user=self.request.user, data={
|
||||||
|
k: getattr(self.object, k) if k != 'limit_events' else [e.id for e in getattr(self.object, k).all()]
|
||||||
|
for k in form.changed_data
|
||||||
|
})
|
||||||
|
messages.success(self.request, _('Your changes have been saved.'))
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
def form_invalid(self, form):
|
||||||
|
messages.error(self.request, _('Your changes could not be saved.'))
|
||||||
|
return super().form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceConnectView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, DetailView):
|
||||||
|
model = Device
|
||||||
|
template_name = 'pretixcontrol/organizers/device_connect.html'
|
||||||
|
permission = 'can_change_organizer_settings'
|
||||||
|
context_object_name = 'device'
|
||||||
|
form_class = DeviceForm
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
return get_object_or_404(Device, organizer=self.request.organizer, pk=self.kwargs.get('device'))
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
self.object = self.get_object()
|
||||||
|
if self.object.initialized:
|
||||||
|
messages.error(request, _('This device already has been connected.'))
|
||||||
|
return redirect(reverse('control:organizer.devices', kwargs={
|
||||||
|
'organizer': self.request.organizer.slug,
|
||||||
|
}))
|
||||||
|
return super().get(request, *args, **kwargs)
|
||||||
|
|||||||
Reference in New Issue
Block a user