Merge pull request #584 from emanuelschuetze/participants-1

Participants fields: add 'title', remove 'type', use 'groups'
This commit is contained in:
Oskar Hahn 2013-04-09 13:25:18 -07:00
commit 632c9476ed
10 changed files with 162 additions and 105 deletions

View File

@ -1,12 +1,15 @@
"Vorname";"Nachname";"Geschlecht";"Gliederungsebene";"Typ";"Amt";"Kommentar"
"Angramain";"Aranea";"female";;"delegate";;
"Bastian";"Bux";"male";;"observer";"2. Vorsitzender";
"Emma";"Dampf";"female";"Ortsverband Berlin-Mitte";"delegate";"AG Frauen";
"David";"Delegierter";"male";"Ortsverband Berlin-Mitte";"delegate";"Haushaltsausschuss";"Demo-Account"
"Marta";"Grankvist";"female";"Ortsverband Köln";"delegate";"1. Vorsitzende";
"Atréju";"Grün";"male";"Ortsverband Freiburg";"staff";"Versammlungsleitung";
"Li Si";"Mandala";"female";;"staff";;
"Malin";"Melchersson";"male";"Gastredner e.V.";"guest";;
"Molly";"Tender";"female";"Ortsverband Berlin-Mitte";"delegate";;
"Dr. Karl";"Tur Tur";"male";;"observer";;
"Volker";"Versammlungsleitung";"male";"Ortsverband Hamburg";"delegate";"Versammlungsleitung";"Demo-Account"
"Titel";"Vorname";"Nachname";"Geschlecht";"E-Mail";"Gruppen-ID";"Gliederungsebene";"Amt";"Über mich";"Kommentar";"Aktiviert"
;"Angramain";"Aranea";"female";;;;;;;1
;"Bastian";"Bux";"male";;;;"2. Vorsitzender";;;1
;"Emma";"Dampf";"female";;3;"Ortsverband Berlin-Mitte";"AG Frauen";;;0
"Dr.";"David";"Delegierter";"male";"david@example.com";3;"Ortsverband Berlin-Mitte";"Haushaltsausschuss";"Zu meiner Person:
A
B
C";"Demo-Account";1
;"Marta";"Grankvist";"female";;3,4;"Ortsverband Köln";"1. Vorsitzende";;;0
"Prof. Dr.";"Atréju";"Grün";"male";;4;"Ortsverband Freiburg";"Versammlungsleitung";;;1
;"Li Si";"Mandala";"female";;4;;;;;1
;"Malin";"Melchersson";"male";;;"Gastredner e.V.";;;;1
;"Molly";"Tender";"female";;3;"Ortsverband Berlin-Mitte";;;;1
"Dr. med.";"Karl";"Tur Tur";"male";;;;;;;1
"Dipl.-Ing.";"Volker";"Versammlungsleitung";"male";"volker@example.com";3,4;"Ortsverband Hamburg";"Versammlungsleitung";;"Demo-Account";1

1 Titel Vorname Nachname Geschlecht Typ E-Mail Gruppen-ID Gliederungsebene Amt Über mich Kommentar Aktiviert
2 Angramain Aranea female delegate 1
3 Bastian Bux male observer 2. Vorsitzender 1
4 Emma Dampf female delegate 3 Ortsverband Berlin-Mitte AG Frauen 0
5 Dr. David Delegierter male delegate david@example.com 3 Ortsverband Berlin-Mitte Haushaltsausschuss Zu meiner Person: A B C Demo-Account 1
6 Marta Grankvist female delegate 3,4 Ortsverband Köln 1. Vorsitzende 0
7 Prof. Dr. Atréju Grün male staff 4 Ortsverband Freiburg Versammlungsleitung 1
8 Li Si Mandala female staff 4 1
9 Malin Melchersson male guest Gastredner e.V. 1
10 Molly Tender female delegate 3 Ortsverband Berlin-Mitte 1
11 Dr. med. Dr. Karl Karl Tur Tur male observer 1
12 Dipl.-Ing. Volker Versammlungsleitung male delegate volker@example.com 3,4 Ortsverband Hamburg Versammlungsleitung Demo-Account 1
13
14
15

View File

@ -1,12 +1,15 @@
"First Name";"Last Name";"Gender";"Structure Level";"Type";"Committee";"Comment"
"Angramain";"Aranea";"female";;"delegate";;
"Bastian";"Bux";"male";;"observer";"2. Vorsitzender";
"Emma";"Dampf";"female";"Ortsverband Berlin-Mitte";"delegate";"AG Frauen";
"David";"Delegierter";"male";"Ortsverband Berlin-Mitte";"delegate";"Haushaltsausschuss";"Demo-Account"
"Marta";"Grankvist";"female";"Ortsverband Köln";"delegate";"1. Vorsitzende";
"Atréju";"Grün";"male";"Ortsverband Freiburg";"staff";"Versammlungsleitung";
"Li Si";"Mandala";"female";;"staff";;
"Malin";"Melchersson";"male";"Gastredner e.V.";"guest";;
"Molly";"Tender";"female";"Ortsverband Berlin-Mitte";"delegate";;
"Dr. Karl";"Tur Tur";"male";;"observer";;
"Volker";"Versammlungsleitung";"male";"Ortsverband Hamburg";"delegate";"Versammlungsleitung";"Demo-Account"
"First Name";"Last Name";"Gender";"Email";"Group id";"Structure Level";"Committee";"About me";"Comment";"Is active"
"Angramain";"Aranea";"female";;;;;;;1
"Bastian";"Bux";"male";;;;"2. Vorsitzender";;;1
"Emma";"Dampf";"female";;3;"Ortsverband Berlin-Mitte";"AG Frauen";;;0
"David";"Delegierter";"male";"david@example.com";3;"Ortsverband Berlin-Mitte";"Haushaltsausschuss";"Zu meiner Person:
A
B
C";"Demo-Account";1
"Marta";"Grankvist";"female";;3,4;"Ortsverband Köln";"1. Vorsitzende";;;0
"Atréju";"Grün";"male";;4;"Ortsverband Freiburg";"Versammlungsleitung";;;1
"Li Si";"Mandala";"female";;4;;;;;1
"Malin";"Melchersson";"male";;;"Gastredner e.V.";;;;1
"Molly";"Tender";"female";;3;"Ortsverband Berlin-Mitte";;;;1
"Karl";"Tur Tur";"male";;;;;;;1
"Volker";"Versammlungsleitung";"male";"volker@example.com";3,4;"Ortsverband Hamburg";"Versammlungsleitung";;"Demo-Account";1

1 First Name Last Name Gender Email Type Group id Structure Level Committee About me Comment Is active
2 Angramain Aranea female delegate 1
3 Bastian Bux male observer 2. Vorsitzender 1
4 Emma Dampf female delegate 3 Ortsverband Berlin-Mitte AG Frauen 0
5 David Delegierter male david@example.com delegate 3 Ortsverband Berlin-Mitte Haushaltsausschuss Zu meiner Person: A B C Demo-Account 1
6 Marta Grankvist female delegate 3,4 Ortsverband Köln 1. Vorsitzende 0
7 Atréju Grün male staff 4 Ortsverband Freiburg Versammlungsleitung 1
8 Li Si Mandala female staff 4 1
9 Malin Melchersson male guest Gastredner e.V. 1
10 Molly Tender female delegate 3 Ortsverband Berlin-Mitte 1
11 Dr. Karl Karl Tur Tur male observer 1
12 Volker Versammlungsleitung male volker@example.com delegate 3,4 Ortsverband Hamburg Versammlungsleitung Demo-Account 1
13
14
15

View File

@ -67,21 +67,38 @@ def import_users(csv_file):
dialect=dialect)):
if line_no:
try:
(first_name, last_name, gender, structure_level, type, committee, comment) = line[:7]
(title, first_name, last_name, gender, email, groups,
structure_level, committee, about_me, comment, is_active) = line[:11]
except ValueError:
error_messages.append(_('Ignoring malformed line %d in import file.') % (line_no + 1))
continue
user = User()
user.title = title
user.last_name = last_name
user.first_name = first_name
user.username = gen_username(first_name, last_name)
user.gender = gender
user.email = email
user.structure_level = structure_level
user.type = type
user.committee = committee
user.about_me = about_me
user.comment = comment
if is_active == '1':
user.is_active = True
else:
user.is_active = False
user.default_password = gen_password()
user.save()
for groupid in groups:
try:
if groupid != ",":
Group.objects.get(pk=groupid).user_set.add(user)
except ValueError:
error_messages.append(_('Ignoring malformed group id in line %d.') % (line_no + 1))
continue
except Group.DoesNotExist:
error_messages.append(_('Group id %s does not exists (line %d).') % (groupid, line_no + 1))
continue
user.reset_password()
count_success += 1
except csv.Error:

View File

@ -36,16 +36,17 @@ class UserCreateForm(forms.ModelForm, CssClassMixin):
class Meta:
model = User
fields = ('first_name', 'last_name', 'is_active', 'groups', 'structure_level',
'gender', 'type', 'committee', 'about_me', 'comment', 'default_password')
fields = ('title', 'first_name', 'last_name', 'gender', 'email',
'groups', 'structure_level', 'committee', 'about_me', 'comment',
'is_active', 'default_password')
class UserUpdateForm(UserCreateForm):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'is_active', 'groups',
'structure_level', 'gender', 'type', 'committee', 'about_me', 'comment',
'default_password')
fields = ('username', 'title', 'first_name', 'last_name', 'gender', 'email',
'groups', 'structure_level', 'committee', 'about_me', 'comment',
'is_active', 'default_password')
class GroupForm(forms.ModelForm, CssClassMixin):
@ -106,7 +107,8 @@ class UsersettingsForm(forms.ModelForm, CssClassMixin):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'gender', 'email', 'committee', 'about_me')
fields = ('username', 'title', 'first_name', 'last_name', 'gender', 'email',
'committee', 'about_me')
class UserImportForm(forms.Form, CssClassMixin):

View File

@ -30,25 +30,19 @@ class User(PersonMixin, Person, SlideMixin, DjangoUser):
('male', _('Male')),
('female', _('Female')),
)
TYPE_CHOICES = (
('delegate', _('Delegate')),
('observer', _('Observer')),
('staff', _('Staff')),
('guest', _('Guest')),
)
django_user = models.OneToOneField(DjangoUser, editable=False, parent_link=True)
structure_level = models.CharField(
max_length=100, blank=True, default='', verbose_name=_("Structure level"),
max_length=255, blank=True, default='', verbose_name=_("Structure level"),
help_text=_('Will be shown after the name.'))
title = models.CharField(
max_length=50, blank=True, default='', verbose_name=_("Titel"),
help_text=_('Will be shown before the name.'))
gender = models.CharField(
max_length=50, choices=GENDER_CHOICES, blank=True,
verbose_name=_("Gender"), help_text=_('Only for filtering the participant list.'))
type = models.CharField(
max_length=100, choices=TYPE_CHOICES, blank=True,
verbose_name=_("Typ"), help_text=_('Only for filtering the participant list.'))
committee = models.CharField(
max_length=100, blank=True, default='', verbose_name=_("Committee"),
max_length=255, blank=True, default='', verbose_name=_("Committee"),
help_text=_('Only for filtering the participant list.'))
about_me = models.TextField(
blank=True, default='', verbose_name=_('About me'),
@ -62,7 +56,11 @@ class User(PersonMixin, Person, SlideMixin, DjangoUser):
@property
def clean_name(self):
return self.get_full_name() or self.username
if self.title:
name = "%s %s" % (self.title, self.get_full_name())
else:
name = self.get_full_name()
return name or self.username
def get_name_suffix(self):
return self.structure_level

View File

@ -13,15 +13,21 @@
</h1>
<p>{% trans 'Select a CSV file to import participants!' %}</p>
<p>{% trans 'Required comma separated values' %}:
<code>({% trans 'first_name, last_name, gender, structure level, type, committee, comment' %})</code>
<br>
{% trans 'Required CSV file encoding: UTF-8 (Unicode).' %}
</p>
<p><a href="https://github.com/OpenSlides/OpenSlides/wiki/CSV-Import" target="_blank">{% trans 'A CSV example file is available in OpenSlides Wiki.' %}</a>
</p>
<p>{% trans 'Please note' %}:</p>
<ul>
<li>
{% trans 'Required comma separated values' %}:<br>
<code>({% trans 'title, first name, last name, gender, email, group id, structure level, committee, about me, comment, is active' %})</code>
</li>
<li>
{% trans 'Default groups' %}:
{% trans 'Anonymous' %} (<code>1</code>), {% trans 'Registered' %} (<code>2</code>),
{% trans 'Delegate' %} (<code>3</code>), {% trans 'Staff' %} (<code>4</code>)
</li>
<li>{% trans 'Required CSV file encoding: UTF-8 (Unicode).' %}</li>
<li><a href="https://github.com/OpenSlides/OpenSlides/wiki/CSV-Import" target="_blank">{% trans 'Use the CSV example file from OpenSlides Wiki.' %}</a></li>
</ul>
<form enctype="multipart/form-data" action="" method="post">{% csrf_token %}
{% include "form.html" %}

View File

@ -59,10 +59,11 @@
<thead>
<tr>
<th>{% trans "Present" %}</th>
<th class="optional">{% trans "Title" %}</th>
<th>{% trans "First Name" %}</th>
<th>{% trans "Last Name" %}</th>
<th class="optional">{% trans "Structure level" %}</th>
<th class="optional">{% trans "Type" %}</th>
<th class="optional">{% trans "Group" %}</th>
<th class="optional">{% trans "Committee" %}</th>
{% if perms.participant.can_manage_participant %}
<th class="optional">{% trans "Comment" %}</th>
@ -88,10 +89,18 @@
title="{% if user.is_active %}{% trans 'present' %}{% else %}{% trans 'absent' %}{% endif %}"></i>
{% endif %}
</td>
<td class="optional">{{ user.title }}</td>
<td><a href="{% url 'user_view' user.id %}">{{ user.first_name }}</a></td>
<td><a href="{% url 'user_view' user.id %}">{{ user.last_name }}</a></td>
<td class="optional">{{ user.structure_level }}</td>
<td class="optional">{{ user.get_type_display }}</td>
<td class="optional">
{% for group in user.groups.all %}
{% if group.name != 'Registered' %}
{{ group}}
{% if not forloop.last %}<br>{% endif %}
{% endif %}
{% endfor %}
</td>
<td class="optional">{{ user.committee }}</td>
{% if perms.participant.can_manage_participant %}
<td class="optional">{{ user.comment|first_line }}</td>

View File

@ -7,55 +7,50 @@
{% block content %}
<h1>{{ shown_user }}
<h1>{{ shown_user.clean_name }}
<small class="pull-right">
<a href="{% url 'user_overview' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to overview" %}</a>
</small>
</h1>
<p>{{ shown_user.email }}</p>
<h4>{% trans "Groups" %}</h4>
<p>
<fieldset>
<legend>{% trans "Personal data" %}</legend>
<label>{% trans "Gender" %}</label>
{{ shown_user.get_gender_display }}
<label>{% trans "Email" %}</label>
{{ shown_user.email }}
<label>{% trans "About me" %}</label>
{{ shown_user.about_me|linebreaks }}
</fieldset>
<fieldset>
<legend>{% trans "Event data" %}</legend>
<label>{% trans "Structure level" %}</label>
{{ shown_user.structure_level }}
<label>{% trans "Committee" %}</label>
{{ shown_user.committee }}
<label>{% trans "Groups" %}</label>
{% if shown_user.groups.all %}
{{ shown_user.groups.all|join:", " }}
{% else %}
{% trans "The participant is not member of any group." %}
{% endif %}
</p>
{% if shown_user.get_gender_display %}
<h4>{% trans "Gender" %}</h4>
<p>{{ shown_user.get_gender_display }}</p>
{% endif %}
{% if shown_user.get_type_display %}
<h4>{% trans "Type" %}</h4>
<p>{{ shown_user.get_type_display }}</p>
{% endif %}
{% if shown_user.committee %}
<h4>{% trans "Committee" %}</h4>
<p>{{ shown_user.committee }}</p>
{% endif %}
{% if shown_user.about_me %}
<h4>{% trans "About me" %}</h4>
<p>{{ shown_user.about_me }}</p>
{% endif %}
</fieldset>
{% if perms.participant.can_manage_participant %}
{% if shown_user.comment %}
<h4>{% trans "Comment" %}</h4>
<p>{{ shown_user.comment }}</p>
{% endif %}
<h4>{% trans "Last Login" %}</h4>
<fieldset>
<legend>{% trans "Administrative data" %}</legend>
<label>{% trans "User name" %}</label>
{{ shown_user.username }}
<label>{% trans "Comment" %}</label>
{{ shown_user.comment|linebreaks }}
<label>{% trans "Last Login" %}</label>
{% if shown_user.last_login > shown_user.date_joined %}
<p>{{ shown_user.last_login }}</p>
{{ shown_user.last_login }}
{% else %}
<p>{% trans "The participant has not logged in yet." %}</p>
{% trans "The participant has not logged in yet." %}
{% endif %}
{% endif %}
{% endblock %}

View File

@ -86,16 +86,6 @@ class UserDetailView(DetailView, PermissionMixin):
context_object_name = 'shown_user'
class GroupDetailView(DetailView, PermissionMixin):
"""
Classed based view to show a specific group in the interface.
"""
permission_required = 'participant.can_manage_participant'
model = Group
template_name = 'participant/group_detail.html'
context_object_name = 'group'
class UserCreateView(CreateView):
"""
Create a new participant.
@ -184,8 +174,8 @@ class ParticipantsListPDF(PDFView):
document_title = ugettext_lazy('List of Participants')
def append_to_pdf(self, story):
data = [['#', _('Last Name'), _('First Name'), _('Group'), _('Type'),
_('Committee')]]
data = [['#', _('Title'), _('Last Name'), _('First Name'),
_('Structure level'), _('Group'), _('Committee')]]
if config['participant_sort_users_by_first_name']:
sort = 'first_name'
else:
@ -193,12 +183,17 @@ class ParticipantsListPDF(PDFView):
counter = 0
for user in User.objects.all().order_by(sort):
counter += 1
groups = ''
for group in user.groups.all():
if unicode(group) != "Registered":
groups += "%s<br/>" % unicode(group)
data.append([
counter,
Paragraph(user.title, stylesheet['Tablecell']),
Paragraph(user.last_name, stylesheet['Tablecell']),
Paragraph(user.first_name, stylesheet['Tablecell']),
Paragraph(user.structure_level, stylesheet['Tablecell']),
Paragraph(user.get_type_display(), stylesheet['Tablecell']),
Paragraph(groups, stylesheet['Tablecell']),
Paragraph(user.committee, stylesheet['Tablecell'])])
t = LongTable(data, style=[
('VALIGN', (0, 0), (-1, -1), 'TOP'),
@ -292,7 +287,7 @@ class UserImportView(FormView):
permission_required = 'participant.can_manage_participant'
template_name = 'participant/import.html'
form_class = UserImportForm
success_url_name = 'user_import'
success_url_name = 'user_overview'
def form_valid(self, form):
# check for valid encoding (will raise UnicodeDecodeError if not)
@ -339,6 +334,16 @@ class GroupOverview(ListView):
model = Group
class GroupDetailView(DetailView, PermissionMixin):
"""
Classed based view to show a specific group in the interface.
"""
permission_required = 'participant.can_manage_participant'
model = Group
template_name = 'participant/group_detail.html'
context_object_name = 'group'
class GroupCreateView(CreateView):
"""
Create a new group.

View File

@ -117,7 +117,19 @@ tr.total td {
.optional {
display: auto;
}
fieldset {
margin-bottom: 10px;
}
fieldset legend {
margin-bottom: 5px;
}
fieldset label {
font-weight: bold;
margin: 10px 0 0 0;
}
fieldset label:after {
content: ":";
}
/** Forms **/
input, textarea {
@ -144,7 +156,14 @@ form .required label:after {
legend + .control-group {
margin-top: 0px !important;
}
#id_permissions {
height: 310px;
width: auto;
}
#id_submitter, #id_supporter, #id_users {
height: 110px;
width: auto;
}
/** Left sitebar navigation **/
.leftmenu ul {