UPD: more registration staff on dav_events.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import EventStatus, EventFlag, Event, OneClickAction
|
||||
from .models import EventStatus, EventFlag, Event, OneClickAction, Participant
|
||||
|
||||
|
||||
@admin.register(EventStatus)
|
||||
@@ -13,11 +13,20 @@ class EventFlagInline(admin.TabularInline):
|
||||
extra = 1
|
||||
|
||||
|
||||
class EventParticipantInline(admin.TabularInline):
|
||||
model = Participant
|
||||
extra = 1
|
||||
|
||||
@admin.register(Event)
|
||||
class EventAdmin(admin.ModelAdmin):
|
||||
inlines = [EventFlagInline]
|
||||
inlines = [EventFlagInline, EventParticipantInline]
|
||||
|
||||
|
||||
@admin.register(OneClickAction)
|
||||
class OneClickActionAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
@admin.register(Participant)
|
||||
class ParticipantAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
from . import generic
|
||||
from . import events
|
||||
from . import participant
|
||||
|
||||
15
dav_events/forms/participant.py
Normal file
15
dav_events/forms/participant.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django import forms
|
||||
|
||||
from ..models import Participant
|
||||
|
||||
|
||||
class ParticipantForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Participant
|
||||
exclude = ['event', 'created_at', 'position', 'purge_at']
|
||||
widgets = {
|
||||
'emergency_contact': forms.Textarea(attrs={'rows': 4}),
|
||||
'experience': forms.Textarea(attrs={'rows': 5}),
|
||||
'note': forms.Textarea(attrs={'rows': 5}),
|
||||
}
|
||||
47
dav_events/migrations/0030_auto_20190603_1014.py
Normal file
47
dav_events/migrations/0030_auto_20190603_1014.py
Normal file
@@ -0,0 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.20 on 2019-06-03 10:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dav_events', '0029_event_registration_closed'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Participant',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('position', models.IntegerField(verbose_name='Listennummer')),
|
||||
('personal_names', models.CharField(max_length=1024, verbose_name='Vorname(n)')),
|
||||
('family_names', models.CharField(max_length=1024, verbose_name='Familienname')),
|
||||
('address', models.CharField(help_text='Straße, Hausnummer', max_length=1024, verbose_name='Anschrift')),
|
||||
('postal_code', models.CharField(max_length=254, verbose_name='Postleitzahl')),
|
||||
('city', models.CharField(max_length=1024, verbose_name='Ort')),
|
||||
('email_address', models.EmailField(max_length=254, verbose_name='E-Mail-Adresse')),
|
||||
('phone_number', models.CharField(max_length=254, verbose_name='Telefonnummer')),
|
||||
('dav_number', models.CharField(max_length=62, verbose_name='DAV Mitgliednummer')),
|
||||
('emergency_contact', models.TextField(blank=True, verbose_name='Notfall-Kontakt')),
|
||||
('experience', models.TextField(blank=True, verbose_name='Erfahrung')),
|
||||
('note', models.TextField(blank=True, verbose_name='Anmerkung')),
|
||||
('paid', models.BooleanField(default=False, verbose_name='Teilnehmerbeitrag bezahlt')),
|
||||
('purge_at', models.DateTimeField()),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='participants', to='dav_events.Event')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Teilnehmer',
|
||||
'verbose_name_plural': 'Teilnehmer',
|
||||
'ordering': ['event', 'position'],
|
||||
},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='participant',
|
||||
unique_together=set([('event', 'position')]),
|
||||
),
|
||||
]
|
||||
@@ -2,3 +2,4 @@ from .event import Event
|
||||
from .eventflag import EventFlag
|
||||
from .eventstatus import EventStatus
|
||||
from .oneclickaction import OneClickAction
|
||||
from .participant import Participant
|
||||
|
||||
79
dav_events/models/participant.py
Normal file
79
dav_events/models/participant.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
import datetime
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
midnight = datetime.time(00, 00, 00)
|
||||
one_day = datetime.timedelta(1)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Participant(models.Model):
|
||||
event = models.ForeignKey('Event', related_name='participants')
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
position = models.IntegerField(verbose_name='Listennummer')
|
||||
|
||||
personal_names = models.CharField(max_length=1024,
|
||||
verbose_name=_('Vorname(n)'))
|
||||
family_names = models.CharField(max_length=1024,
|
||||
verbose_name=_('Familienname'))
|
||||
address = models.CharField(max_length=1024,
|
||||
verbose_name=_('Anschrift'),
|
||||
help_text=_('Straße, Hausnummer'))
|
||||
postal_code = models.CharField(max_length=254,
|
||||
verbose_name=_('Postleitzahl'))
|
||||
city = models.CharField(max_length=1024,
|
||||
verbose_name=_('Ort'))
|
||||
email_address = models.EmailField(verbose_name=_('E-Mail-Adresse'))
|
||||
phone_number = models.CharField(max_length=254,
|
||||
verbose_name=_('Telefonnummer'))
|
||||
dav_number = models.CharField(max_length=62,
|
||||
#validators=[DAVNumberValidator],
|
||||
verbose_name=_('DAV Mitgliednummer'))
|
||||
emergency_contact = models.TextField(blank=True,
|
||||
verbose_name=_('Notfall-Kontakt'))
|
||||
experience = models.TextField(blank=True,
|
||||
verbose_name=_('Erfahrung'))
|
||||
note = models.TextField(blank=True,
|
||||
verbose_name=_('Anmerkung'))
|
||||
|
||||
paid = models.BooleanField('Teilnehmerbeitrag bezahlt', default=False)
|
||||
|
||||
purge_at = models.DateTimeField()
|
||||
|
||||
class Meta:
|
||||
unique_together = (('event', 'position'), )
|
||||
verbose_name = _('Teilnehmer')
|
||||
verbose_name_plural = _('Teilnehmer')
|
||||
ordering = ['event', 'position']
|
||||
|
||||
def __str__(self):
|
||||
return '{position}. {name}'.format(
|
||||
position=self.position,
|
||||
name=self.get_full_name(),
|
||||
)
|
||||
|
||||
def get_full_name(self):
|
||||
return '{} {}'.format(self.personal_names, self.family_names)
|
||||
|
||||
def save(self, **kwargs):
|
||||
if not self.purge_at and self.event:
|
||||
self.purge_at = self.__class__.calc_purge_at(self.event)
|
||||
|
||||
super(Participant, self).save(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def calc_purge_at(event):
|
||||
if event.alt_last_day:
|
||||
last_day = event.alt_last_day
|
||||
elif event.last_day:
|
||||
last_day = event.last_day
|
||||
elif event.alt_first_day:
|
||||
last_day = event.alt_first_day
|
||||
else:
|
||||
last_day = event.first_day
|
||||
return timezone.make_aware(datetime.datetime.combine(last_day + one_day * 7, midnight))
|
||||
@@ -220,22 +220,117 @@
|
||||
</div>
|
||||
<hr />
|
||||
<h4>Teilnehmer (Designstudie - Das funktioniert alles noch nicht!)</h4>
|
||||
<div class="panel panel-default">
|
||||
<div id="headingRegistrations" class="panel-heading" role="tab">
|
||||
<h5 class="panel-title">
|
||||
<a role="button" href="#collapseRegistrations" data-toggle="collapse" data-parent="#accordion"
|
||||
aria-expanded="true" aria-controls="collapseRegistrations">
|
||||
<span class="caret"></span> Anmeldungen
|
||||
</a>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="collapseRegistrations" class="panel-collapse collapse"
|
||||
role="tabpanel" aria-labelledby="headingRegistrations">
|
||||
<div class="panel-body">
|
||||
{% for registration in registrations %}
|
||||
<form action="" method="post" class="form-inline">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="registration" value="{{ registration.id }}">
|
||||
{% if registration.answered %}
|
||||
<span class="text-muted disabled">
|
||||
{% endif %}
|
||||
<button type="submit" name="action" value="accept_registration"
|
||||
class="btn btn-link" title="Teilnehmer hinzufügen">
|
||||
<span class="text-success">{% bootstrap_icon 'plus-sign' %}</span>
|
||||
</button>
|
||||
<button type="submit" name="action" value="reject_registration"
|
||||
class="btn btn-link" title="Anmeldung löschen">
|
||||
<span class="text-danger">{% bootstrap_icon 'minus-sign' %}</span>
|
||||
</button>
|
||||
{{ registration.get_full_name }}
|
||||
(<a href="mailto:{{ registration.email_address }}">{{ registration.email_address }}</a>,
|
||||
{{ registration.phone_number }})
|
||||
|
||||
<span title="Anmeldezeitpunkt">
|
||||
{% bootstrap_icon 'time' %}
|
||||
{{ registration.created_at|date:'d. F Y, G:i' }}
|
||||
</span>
|
||||
|
||||
<span title="{{ registration.get_info }}">
|
||||
{% bootstrap_icon 'info-sign' %}
|
||||
</span>
|
||||
{% if registration.answered %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% empty %}
|
||||
Keine unbestätigten Anmeldungen vorhanden
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div id="headingAddParticipant" class="panel-heading" role="tab">
|
||||
<h5 class="panel-title">
|
||||
<a role="button" href="#collapseAddParticipant" data-toggle="collapse" data-parent="#accordion"
|
||||
aria-expanded="true" aria-controls="collapseAddParticipant">
|
||||
Teilnehmer hinzufügen
|
||||
<span class="caret"></span> weiteren Teilnehmer eintragen
|
||||
</a>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="collapseAddParticipant" class="panel-collapse collapse in"
|
||||
<div id="collapseAddParticipant" class="panel-collapse collapse {% if create_participant_form.errors %}in{% endif %}"
|
||||
role="tabpanel" aria-labelledby="headingAddParticipant">
|
||||
<div class="panel-body">
|
||||
Formular
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<button class="btn btn-success">Speichern</button>
|
||||
{% bootstrap_form_errors create_participant_form %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
{% bootstrap_field create_participant_form.personal_names %}
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
{% bootstrap_field create_participant_form.family_names %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
{% bootstrap_field create_participant_form.address %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
{% bootstrap_field create_participant_form.postal_code %}
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
{% bootstrap_field create_participant_form.city %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
{% bootstrap_field create_participant_form.email_address %}
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
{% bootstrap_field create_participant_form.phone_number %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
{% bootstrap_field create_participant_form.dav_number %}
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
{% bootstrap_field create_participant_form.emergency_contact %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
{% bootstrap_field create_participant_form.experience %}
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
{% bootstrap_field create_participant_form.note %}
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-success">{% bootstrap_icon 'plus-sign' %} {% trans 'Teilnehmer hinzufügen' %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -245,7 +340,7 @@
|
||||
<h5 class="panel-title">
|
||||
<a role="button" href="#collapseParticipant_{{ participant.id }}" data-toggle="collapse" data-parent="#accordion"
|
||||
aria-expanded="true" aria-controls="collapseParticipant_{{ participant.id }}">
|
||||
{{ participant.position }}. {{ participant.get_full_name }}
|
||||
<span class="caret"></span> {{ participant.position }}. {{ participant.get_full_name }}
|
||||
</a>
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@ import os
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import login
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import PermissionDenied, SuspiciousOperation
|
||||
from django.core.exceptions import PermissionDenied, SuspiciousOperation, FieldDoesNotExist
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
@@ -169,58 +169,130 @@ class EventRegistrationsView(EventPermissionMixin, generic.DetailView):
|
||||
self.enforce_permission(obj)
|
||||
return obj
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = {}
|
||||
if self.request.method in ('POST', 'PUT'):
|
||||
kwargs.update({
|
||||
'data': self.request.POST,
|
||||
'files': self.request.FILES,
|
||||
})
|
||||
return kwargs
|
||||
|
||||
def get_create_participant_form(self):
|
||||
event = self.get_object()
|
||||
form = forms.participant.ParticipantForm(**self.get_form_kwargs())
|
||||
form.instance.event = event
|
||||
form.instance.position = event.participants.count() + 1
|
||||
return form
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(EventRegistrationsView, self).get_context_data(**kwargs)
|
||||
obj = context.get('event')
|
||||
context['has_permission_update'] = self.has_permission('update', obj)
|
||||
context['is_published_any'] = obj.workflow.has_reached_status('published*')
|
||||
context['is_done'] = obj.workflow.has_reached_status('expired')
|
||||
event = context.get('event')
|
||||
context['has_permission_update'] = self.has_permission('update', event)
|
||||
context['is_published_any'] = event.workflow.has_reached_status('published*')
|
||||
context['is_done'] = event.workflow.has_reached_status('expired')
|
||||
|
||||
class MockParticipant(object):
|
||||
def __init__(self, id, name):
|
||||
self.id = id
|
||||
self.name = name
|
||||
|
||||
@property
|
||||
def position(self):
|
||||
return self.id
|
||||
|
||||
def get_full_name(self):
|
||||
return self.name
|
||||
|
||||
participants = [MockParticipant(1, 'Erika Musterfrau'), MockParticipant(2, 'Max Mustermann')]
|
||||
participants = event.participants.all()
|
||||
context['participants'] = participants
|
||||
|
||||
if hasattr(event, 'registrations'):
|
||||
# registrations = event.registrations.filter(answered=False)
|
||||
registrations = event.registrations.all()
|
||||
context['registrations'] = registrations
|
||||
if 'create_participant_form' not in context:
|
||||
context['create_participant_form'] = self.get_create_participant_form()
|
||||
return context
|
||||
|
||||
def _send_mails(self, event, request):
|
||||
editor = request.user
|
||||
def _notify_publisher(self, event, editor):
|
||||
recipients = get_users_by_role('publisher')
|
||||
for recipient in recipients:
|
||||
if recipient.email:
|
||||
email = emails.EventRegistrationClosedMail(recipient=recipient, event=event, editor=editor)
|
||||
email.send()
|
||||
|
||||
def _close_registration(self, request, event):
|
||||
logger.info('Close registration: %s', event)
|
||||
event.registration_closed = True
|
||||
event.save(implicit_update=True)
|
||||
self._notify_publisher(event, request.user)
|
||||
messages.success(request, _(u'Die Anmeldung wurde geschlossen'))
|
||||
|
||||
def _reopen_registration(self, request, event):
|
||||
logger.info('Reopen registration: %s', event)
|
||||
event.registration_closed = False
|
||||
event.save(implicit_update=True)
|
||||
messages.success(request, _(u'Die Anmeldung wurde geöffnet'))
|
||||
|
||||
def _kill_deadline(self, request, event):
|
||||
logger.info('Delete deadline: %s', event)
|
||||
event.deadline = None
|
||||
event.registration_closed = False
|
||||
event.save(implicit_update=True)
|
||||
messages.success(request, _(u'Der Anmeldeschluss wurde gelöscht'))
|
||||
|
||||
def _accept_registration(self, request, registration):
|
||||
event = registration.event
|
||||
|
||||
position = event.participants.count() + 1
|
||||
|
||||
data = {
|
||||
'event': event,
|
||||
'position': position,
|
||||
'personal_names': registration.personal_names,
|
||||
'family_names': registration.family_names,
|
||||
'address': registration.address,
|
||||
'postal_code': registration.postal_code,
|
||||
'city': registration.city,
|
||||
'email_address': registration.email_address,
|
||||
'phone_number': registration.phone_number,
|
||||
'dav_number': registration.dav_number,
|
||||
'emergency_contact': registration.emergency_contact,
|
||||
'experience': registration.experience,
|
||||
'note': registration.note,
|
||||
'purge_at': registration.purge_at,
|
||||
}
|
||||
participant = models.Participant.objects.create(**data)
|
||||
registration.answered = True
|
||||
registration.save()
|
||||
messages.success(request, _(u'Teilnehmer hinzugefügt: {}'.format(participant.get_full_name())))
|
||||
|
||||
def _reject_registration(self, registration):
|
||||
registration.answered = True
|
||||
registration.save()
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
event = self.get_object()
|
||||
self.object = event
|
||||
|
||||
action = request.POST.get('action')
|
||||
if action == 'close-registration':
|
||||
logger.info('Close registration: %s', event)
|
||||
event.registration_closed = True
|
||||
event.save(implicit_update=True)
|
||||
self._send_mails(event, request)
|
||||
messages.success(request, _(u'Die Anmeldung wurde geschlossen'))
|
||||
self._close_registration(request, event)
|
||||
elif action == 'open-registration':
|
||||
logger.info('Reopen registration: %s', event)
|
||||
event.registration_closed = False
|
||||
event.save(implicit_update=True)
|
||||
messages.success(request, _(u'Die Anmeldung wurde geöffnet'))
|
||||
self._reopen_registration(request, event)
|
||||
elif action == 'kill-deadline':
|
||||
logger.info('Delete deadline: %s', event)
|
||||
event.deadline = None
|
||||
event.registration_closed = False
|
||||
event.save(implicit_update=True)
|
||||
messages.success(request, _(u'Der Anmeldeschluss wurde gelöscht'))
|
||||
self._kill_deadline(request, event)
|
||||
elif action == 'accept_registration':
|
||||
if hasattr(event, 'registrations'):
|
||||
registration_id = request.POST.get('registration')
|
||||
registration = event.registrations.get(id=registration_id)
|
||||
self._accept_registration(request, registration)
|
||||
else:
|
||||
raise FieldDoesNotExist('Event has no registrations')
|
||||
elif action == 'reject_registration':
|
||||
if hasattr(event, 'registrations'):
|
||||
registration_id = request.POST.get('registration')
|
||||
registration = event.registrations.get(id=registration_id)
|
||||
self._reject_registration(registration)
|
||||
else:
|
||||
raise FieldDoesNotExist('Event has no registrations')
|
||||
else:
|
||||
form = self.get_create_participant_form()
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
participant = form.instance
|
||||
messages.success(request, _(u'Teilnehmer hinzugefügt: {}'.format(participant.get_full_name())))
|
||||
else:
|
||||
messages.error(request, _(u'irgendwas ging schief.'))
|
||||
return self.render_to_response(self.get_context_data(create_participant_form=form))
|
||||
return HttpResponseRedirect(reverse('dav_events:registrations', kwargs={'pk': event.pk}))
|
||||
|
||||
@method_decorator(login_required)
|
||||
|
||||
@@ -11,7 +11,7 @@ logger = logging.getLogger(__name__)
|
||||
class RegistrationForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Registration
|
||||
exclude = ['event', 'created_at', 'privacy_policy', 'purge_at']
|
||||
exclude = ['event', 'created_at', 'privacy_policy', 'purge_at', 'answered']
|
||||
widgets = {
|
||||
'emergency_contact': forms.Textarea(attrs={'rows': 4}),
|
||||
'experience': forms.Textarea(attrs={'rows': 5}),
|
||||
|
||||
25
dav_registration/migrations/0003_auto_20190603_1425.py
Normal file
25
dav_registration/migrations/0003_auto_20190603_1425.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.20 on 2019-06-03 14:25
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dav_registration', '0002_auto_20190401_1310'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='registration',
|
||||
name='answered',
|
||||
field=models.BooleanField(default=False, verbose_name='Durch Tourleitung beantwortet'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='registration',
|
||||
name='purge_at',
|
||||
field=models.DateTimeField(verbose_name='Zeitpunkt der Datenlöschung'),
|
||||
),
|
||||
]
|
||||
@@ -69,7 +69,9 @@ class Registration(models.Model):
|
||||
verbose_name=_('Erklärung zur Datenspeicherung'))
|
||||
privacy_policy_accepted = models.BooleanField(default=False,
|
||||
verbose_name=_('Einwilligung zur Datenspeicherung'))
|
||||
purge_at = models.DateTimeField()
|
||||
purge_at = models.DateTimeField(_('Zeitpunkt der Datenlöschung'))
|
||||
|
||||
answered = models.BooleanField(_('Durch Tourleitung beantwortet'), default=False)
|
||||
|
||||
@staticmethod
|
||||
def pk2hexstr(pk):
|
||||
@@ -105,6 +107,25 @@ class Registration(models.Model):
|
||||
def get_full_name(self):
|
||||
return '{} {}'.format(self.personal_names, self.family_names)
|
||||
|
||||
def get_info(self):
|
||||
text = """{fullname}
|
||||
{address}, {postal_code} {city}
|
||||
|
||||
Erfahrung:
|
||||
{experience}
|
||||
|
||||
Anmerkung:
|
||||
{note}
|
||||
"""
|
||||
return text.format(
|
||||
fullname=self.get_full_name(),
|
||||
address=self.address,
|
||||
postal_code=self.postal_code,
|
||||
city=self.city,
|
||||
experience=self.experience,
|
||||
note=self.note,
|
||||
)
|
||||
|
||||
def save(self, **kwargs):
|
||||
creating = False
|
||||
if not self.id:
|
||||
|
||||
Reference in New Issue
Block a user