Commit d8509d2e authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg
Browse files

Merge branch 'feature/event-docs' into 'master'

Added document support to events

Closes #257

See merge request !1080
parents db1b6095 1499a72e
......@@ -48,6 +48,14 @@ documents.models module
:undoc-members:
:show-inheritance:
documents.services module
-------------------------
.. automodule:: documents.services
:members:
:undoc-members:
:show-inheritance:
documents.sitemaps module
-------------------------
......
......@@ -4,8 +4,9 @@ from django.utils.translation import ugettext_lazy as _
from documents import forms
from documents.models import (AnnualDocument, AssociationDocument,
GeneralMeeting, Minutes,
EventDocument, GeneralMeeting, Minutes,
MiscellaneousDocument)
from documents.services import is_owner
from utils.translation import TranslatedModelAdmin
......@@ -62,6 +63,27 @@ class AssociationDocumentAdmin(TranslatedModelAdmin):
list_filter = ('created', 'last_updated',)
@admin.register(EventDocument)
class EventDocumentAdmin(TranslatedModelAdmin):
"""Manage the event documents"""
form = forms.EventDocumentForm
list_filter = ('created', 'last_updated',)
def has_change_permission(self, request, document=None):
"""Only allow access to the change form if the user is an owner"""
if (document is not None and
not is_owner(request.member, document)):
return False
return super().has_change_permission(request, document)
def has_delete_permission(self, request, document=None):
"""Only allow delete access if the user is an owner"""
if (document is not None and
not is_owner(request.member, document)):
return False
return super().has_delete_permission(request, document)
@admin.register(MiscellaneousDocument)
class MiscellaneousDocumentAdmin(TranslatedModelAdmin):
"""Manage the miscellaneous documents"""
......
......@@ -79,6 +79,18 @@ class AssociationDocumentForm(forms.ModelForm):
}
class EventDocumentForm(forms.ModelForm):
"""Form that overrides the widgets for the files"""
class Meta:
model = models.EventDocument
fields = ('name_en', 'name_nl', 'file_en', 'file_nl', 'members_only',
'owner',)
widgets = {
'file_nl': DocumentFileInput,
'file_en': DocumentFileInput,
}
class MiscellaneousDocumentForm(forms.ModelForm):
"""Form that overrides the widgets for the files"""
class Meta:
......
......@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-10-05 15:12+0200\n"
"PO-Revision-Date: 2018-06-13 21:48+0200\n"
"POT-Creation-Date: 2018-12-12 20:01+0100\n"
"PO-Revision-Date: 2018-12-12 20:02+0100\n"
"Last-Translator: Joost Rijneveld <joost@joostrijneveld.nl>\n"
"Language-Team: \n"
"Language: nl\n"
......@@ -38,7 +38,11 @@ msgstr "Jaarlijks document"
msgid "Association document"
msgstr "Verenigingsdocument"
#: models.py templates/documents/meetingyear.html
#: models.py
msgid "Event document"
msgstr "Evenementdocument"
#: models.py templates/documents/index.html
msgid "Minutes"
msgstr "Notulen"
......@@ -70,11 +74,11 @@ msgstr "bestand"
msgid "members only"
msgstr "alleen voor leden"
#: models.py
#: models.py templates/documents/index.html
msgid "Annual documents"
msgstr "Jaarlijkse documenten"
#: models.py templates/documents/index.html
#: models.py
msgid "Annual report"
msgstr "Jaarverslag"
......@@ -98,6 +102,18 @@ msgstr "Overig verenigingsdocument"
msgid "Miscellaneous association documents"
msgstr "Overige verenigingsdocumenten"
#: models.py
msgid "event document"
msgstr "evenementdocument"
#: models.py
msgid "event documents"
msgstr "evenementdocumenten"
#: models.py
msgid "owner"
msgstr "eigenaar"
#: models.py
msgid "Miscellaneous documents"
msgstr "Overig documenten"
......@@ -110,7 +126,7 @@ msgstr "Algemene ledenvergadering"
msgid "General meetings"
msgstr "Algemene ledenvergaderingen"
#: models.py
#: models.py templates/documents/index.html
msgid "documents"
msgstr "documenten"
......@@ -144,10 +160,6 @@ msgstr ""
"\"https://olympus.science.ru.nl\">de website van koepelvereniging Olympus</"
"a>."
#: templates/documents/index.html
msgid "Policy Documents &amp; Annual Reports"
msgstr "Beleidsdocumenten &amp; Jaarverslagen"
#: templates/documents/index.html
msgid ""
"Every candidate board of Thalia drafts a policy document before being "
......@@ -169,14 +181,6 @@ msgstr ""
"er zijn georganiseerd. In het onderstaande overzicht zijn de afgelopen "
"beleidsplannen en jaarverslagen terug te vinden."
#: templates/documents/index.html
msgid "Policy"
msgstr "Beleidsdocument"
#: templates/documents/index.html
msgid "General Meetings"
msgstr "Algemene Ledenvergaderingen"
#: templates/documents/index.html
msgid ""
"The General Meetings (ALVs) can be attended by all members, honorary members "
......@@ -193,27 +197,13 @@ msgstr ""
"is."
#: templates/documents/index.html
msgid "Earlier.."
msgstr "Eerder.."
#: templates/documents/meetingyear.html
#, python-format
msgid "General Meetings of %(year)s-%(nextyear)s:"
msgstr "ALV's van %(year)s-%(nextyear)s:"
msgid "Older"
msgstr "Ouder"
#: templates/documents/meetingyear.html
msgid "Meeting"
#: templates/documents/index.html
msgid "GM"
msgstr "ALV"
#: templates/documents/meetingyear.html
msgid "No minutes<br>available"
msgstr "Geen notulen<br>beschikbaar"
#: templates/documents/meetingyear.html
msgid "Only signed-in users can view<br>General Meeting documents."
msgstr "ALV-stukken zijn alleen in te zien<br>door ingelogde gebruikers."
#: templates/documents/meetingyear.html
#, python-format
msgid "There are no General Meetings available for %(year)s-%(nextyear)s"
msgstr "Er zijn geen ALV's beschikbaar van %(year)s-%(nextyear)s"
#: templates/documents/index.html
msgid "There have not been any general meetings yet."
msgstr "Er zijn nog geen algemene ledenvergadering geweest."
# Generated by Django 2.0.8 on 2018-11-28 19:07
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('activemembers', '0036_auto_20181024_1939'),
('documents', '0008_2_refactor_documents'),
]
operations = [
migrations.CreateModel(
name='EventDocument',
fields=[
('document_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='documents.Document')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='activemembers.MemberGroup', verbose_name='owner')),
],
options={
'verbose_name': 'event document',
'verbose_name_plural': 'event documents',
},
bases=('documents.document',),
),
migrations.AlterField(
model_name='document',
name='category',
field=models.CharField(choices=[('annual', 'Annual document'), ('association', 'Association document'), ('event', 'Event document'), ('minutes', 'Minutes'), ('misc', 'Miscellaneous document')], default='misc', max_length=40, verbose_name='category'),
),
]
# Generated by Django 2.1.4 on 2018-12-19 20:46
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('documents', '0009_event_documents'),
]
operations = [
migrations.AlterModelOptions(
name='eventdocument',
options={'permissions': (('override_owner', 'Can access event document as if owner'),), 'verbose_name': 'event document', 'verbose_name_plural': 'event documents'},
),
]
......@@ -17,6 +17,7 @@ class Document(models.Model, metaclass=ModelTranslateMeta):
DOCUMENT_CATEGORIES = (
('annual', _('Annual document')),
('association', _('Association document')),
('event', _('Event document')),
('minutes', _('Minutes')),
('misc', _('Miscellaneous document')),
)
......@@ -122,6 +123,26 @@ class AssociationDocument(Document):
super().save(*args, **kwargs)
class EventDocument(Document):
"""Describes a document for events"""
class Meta:
verbose_name = _('event document')
verbose_name_plural = _('event documents')
permissions = (
("override_owner", "Can access event document as if owner"),
)
owner = models.ForeignKey(
'activemembers.MemberGroup',
verbose_name=_('owner'),
on_delete=models.CASCADE,
)
def save(self, *args, **kwargs):
self.category = 'event'
super().save(*args, **kwargs)
class MiscellaneousDocumentManager(models.Manager):
"""Custom manager to filter for misc documents"""
def get_queryset(self):
......
def is_owner(member, event_doc):
if member and member.is_authenticated:
if member.is_superuser or member.has_perm('documents.override_owner'):
return True
if event_doc and member.has_perm('documents.change_document'):
return member.get_member_groups().filter(
pk=event_doc.owner.pk).exists()
return False
.association-document-card, .annual-document-card {
.association-document-card, .annual-document-card, .event-document-card {
.name {
-webkit-hyphens: auto;
-moz-hyphens: auto;
......
......@@ -18,6 +18,17 @@ def association_document_card(document):
)
@register.inclusion_tag('includes/grid_item.html')
def event_document_card(document):
return grid_item(
title=document.name,
meta_text='',
url=document.get_absolute_url(),
image_url=static("documents/images/thumb.png"),
class_name='event-document-card',
)
@register.inclusion_tag('includes/grid_item.html')
def annual_document_card(type, document):
name = ''
......
......@@ -111,7 +111,8 @@ class EventAdmin(DoNextModelAdmin):
fields = ('title', 'description', 'start', 'end', 'organiser', 'category',
'registration_start', 'registration_end', 'cancel_deadline',
'send_cancel_email', 'location', 'map_location', 'price', 'fine',
'max_participants', 'no_registration_message', 'published')
'max_participants', 'no_registration_message', 'published',
'documents',)
list_display = ('overview_link', 'event_date', 'registration_date',
'num_participants', 'organiser', 'category', 'published',
'edit_link')
......@@ -121,6 +122,7 @@ class EventAdmin(DoNextModelAdmin):
date_hierarchy = 'start'
search_fields = ('title', 'description')
prepopulated_fields = {'map_location': ('location',)}
filter_horizontal = ('documents',)
def overview_link(self, obj):
return format_html('<a href="{link}">{title}</a>',
......
......@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-11-28 19:43+0100\n"
"PO-Revision-Date: 2018-11-28 19:45+0100\n"
"POT-Creation-Date: 2018-12-12 19:42+0100\n"
"PO-Revision-Date: 2018-12-12 19:42+0100\n"
"Last-Translator: Thom Wiggers <thom@thomwiggers.nl>\n"
"Language-Team: \n"
"Language: nl\n"
......@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.2\n"
"X-Generator: Poedit 2.0.6\n"
#: admin.py
msgid "lecture year"
......@@ -274,6 +274,10 @@ msgstr "Standaard:"
msgid "published"
msgstr "gepubliceerd"
#: models.py
msgid "documents"
msgstr "documenten"
#: models.py
msgid "Start cannot have an empty date or time field"
msgstr "Starttijd kan niet een lege datum of tijd hebben"
......@@ -727,6 +731,10 @@ msgctxt "pizzas"
msgid "Order"
msgstr "Bestellen"
#: templates/events/event.html
msgid "Documents"
msgstr "Documenten"
#: templates/events/event.html
msgid "Registrations"
msgstr "Aanmeldingen"
......
# Generated by Django 2.0.8 on 2018-11-14 18:40
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('documents', '0008_2_refactor_documents'),
('events', '0031_auto_20181128_1950'),
]
operations = [
migrations.AddField(
model_name='event',
name='documents',
field=models.ManyToManyField(to='documents.Document', verbose_name='documents', blank=True),
),
]
......@@ -161,6 +161,12 @@ class Event(models.Model, metaclass=ModelTranslateMeta):
ScheduledMessage, on_delete=models.deletion.SET_NULL,
related_name='start_event', blank=True, null=True)
documents = models.ManyToManyField(
'documents.Document',
verbose_name=_("documents"),
blank=True,
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._price = self.price
......
{% extends "base.html" %}
{% load i18n static bleach_tags thumbnail member_card google_map_url grid_item alert %}
{% load i18n static bleach_tags thumbnail member_card google_map_url grid_item alert document_cards %}
{% block title %}{{ event.title }} — {% trans "Calendar"|capfirst %} — {{ block.super }}{% endblock %}
{% block opengraph_title %}{{ event.title }} — {% trans "Calendar"|capfirst %} — {{ block.super }}{% endblock %}
......@@ -223,6 +223,22 @@
</div>
</section>
{% if event.documents.exists %}
<section class="page-section" id="events-documents">
<div class="container">
<h1 class="text-center section-title">{% trans "Documents" %}</h1>
<div class="row mt-4">
{% for doc in event.documents.all %}
<div class="col-6 col-md-2 my-3">
{% event_document_card doc %}
</div>
{% endfor %}
</div>
</div>
</section>
{% endif %}
{% if user.is_authenticated and event.participants|length > 0 %}
<section class="page-section" id="events-registrations">
<div class="container">
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment