Move signup models back to webapp
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
# Ilmotunkki
|
||||
|
||||
## Terms
|
||||
- Signup, Form with collection of questions
|
||||
- Response, One answer to some signup
|
||||
- Quota, Amount of people allowed to respond with some option selected.
|
||||
- In generic case there is no option and quota is just max number of people.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Officials may generate signups forms
|
||||
- Officials may see results from signups
|
||||
- Officials may see some stats from their signups
|
||||
- for example distributions of multiple choice answers
|
||||
- Officials should be able to edit signups wherever possible
|
||||
- Propably not possible to edit after first response
|
||||
- Officials should be able to delete responses
|
||||
- Officials should be able to embed payment information to the signup?
|
||||
- TODO: is there need for unique reference numbers for every response?
|
||||
- Officials should be able to save a signup to a reusable template.
|
||||
- Possibility to save templates?
|
||||
|
||||
- Signup may be attached to an event
|
||||
- Multiple signups to a single event should be possible (FTMK uses for museum visits? Erna asked if it was possible in old web)
|
||||
- Possibility for external service (Google Form, URL will suffice)
|
||||
|
||||
- Signup should support custom quotas
|
||||
- Atleast quotas from multiple choices and checkboxes
|
||||
- Text quotas are risky (typos everywhere!!)
|
||||
- Signup should have start and end times
|
||||
- Signup should support atleast following questiontypes
|
||||
- Text
|
||||
- multiple choice (select one)
|
||||
- checkbox (boolean yes/no)
|
||||
|
||||
- Signup should support reserve slots.
|
||||
- TODO: quota based reserves or generic? or both?
|
||||
|
||||
- Responding should send confirm email
|
||||
- Response should be editable by responder and only by the responder until the closing of the signup
|
||||
- TODO: is there need to custom edit period or disable?
|
||||
|
||||
- Responders should see amount of quotas left.
|
||||
- Responders should see some information about other responses
|
||||
- TODO: names? should this be editable by officials?
|
||||
- Or superadmin can edit and the one signing up within edit period
|
||||
- NOTE: Quota related info is exposed if any info is printed
|
||||
- When quotas need to be hidden? PoTa?
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
from django.contrib import admin
|
||||
from signup.models import Event, Signup, SignupForm, TemplateQuestion
|
||||
from modeltranslation.admin import TranslationAdmin
|
||||
from django.contrib.auth.models import Permission
|
||||
# this is needed so that the models get registered for translation
|
||||
import webapp.translation
|
||||
|
||||
admin.site.register(Event, TranslationAdmin)
|
||||
admin.site.register(SignupForm, TranslationAdmin)
|
||||
admin.site.register(Signup, TranslationAdmin)
|
||||
admin.site.register(TemplateQuestion, TranslationAdmin)
|
||||
@@ -1,5 +0,0 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class SignupConfig(AppConfig):
|
||||
name = 'Sign-up'
|
||||
@@ -1,62 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11 on 2018-06-19 17:20
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('signup', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='answer',
|
||||
options={'verbose_name': 'Sign-up answer', 'verbose_name_plural': 'Sign-up answers'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='signup',
|
||||
options={'verbose_name': 'Sign-up', 'verbose_name_plural': 'Sign-ups'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='templatequestion',
|
||||
options={'verbose_name': 'Template question', 'verbose_name_plural': 'Template questions'},
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='templatequestion',
|
||||
old_name='questions',
|
||||
new_name='question',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='signupform',
|
||||
name='questions',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='signupform',
|
||||
name='question',
|
||||
field=models.CharField(default='', max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='templatequestion',
|
||||
name='name',
|
||||
field=models.CharField(default='', max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='signupform',
|
||||
name='end',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='signupform',
|
||||
name='start',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now),
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Question',
|
||||
),
|
||||
]
|
||||
@@ -1,28 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11 on 2018-06-19 17:23
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('signup', '0002_auto_20180619_2020'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='answer',
|
||||
name='signup',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='signup',
|
||||
name='answer',
|
||||
field=models.CharField(default='', max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Answer',
|
||||
),
|
||||
]
|
||||
@@ -1,74 +0,0 @@
|
||||
"""Signup and Event models."""
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from webapp.models import Tag, BaseFeed
|
||||
from webapp.utils import month_from_now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from auditlog.registry import auditlog
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
|
||||
import logging
|
||||
|
||||
|
||||
VERBOSE_NAME = _('Webapp')
|
||||
|
||||
|
||||
class Event(BaseFeed):
|
||||
"""Model for event."""
|
||||
|
||||
start = models.DateTimeField(default=timezone.now)
|
||||
end = models.DateTimeField(default=timezone.now)
|
||||
signupForm = models.ManyToManyField(
|
||||
'SignupForm', blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return _('Event: {}').format(self.title)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Event')
|
||||
verbose_name_plural = _('Events')
|
||||
|
||||
|
||||
class TemplateQuestion(models.Model):
|
||||
"""Stores template questions for signup forms as JSONB"""
|
||||
# question = JSONField()
|
||||
name = models.CharField(max_length=255)
|
||||
question = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return _('Template questions: {}').format(self.name)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Template question')
|
||||
verbose_name_plural = _('Template questions')
|
||||
|
||||
|
||||
class SignupForm(models.Model):
|
||||
"""Model for event signup form. Stores questions in JSONB."""
|
||||
|
||||
start = models.DateTimeField(default=timezone.now)
|
||||
end = models.DateTimeField(default=timezone.now)
|
||||
# question = JSONField()
|
||||
question = models.CharField(max_length=255)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Signup form')
|
||||
verbose_name_plural = _('Signup forms')
|
||||
|
||||
|
||||
class Signup(models.Model):
|
||||
signupForm = models.ForeignKey('SignupForm', on_delete=models.CASCADE)
|
||||
time = models.DateTimeField(default=timezone.now)
|
||||
answer = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return _('Sign-ups: {}').format(self.signupForm)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Sign-up')
|
||||
verbose_name_plural = _('Sign-ups')
|
||||
|
||||
|
||||
auditlog.register(Event)
|
||||
auditlog.register(Signup)
|
||||
@@ -1,3 +0,0 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@@ -1,32 +0,0 @@
|
||||
"""Translation classes."""
|
||||
|
||||
from modeltranslation.translator import register, TranslationOptions
|
||||
from signup.models import Event, Signup, SignupForm, TemplateQuestion
|
||||
|
||||
|
||||
@register(Event)
|
||||
class EventTranslationOptions(TranslationOptions):
|
||||
"""Class for event translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(Signup)
|
||||
class SignupTranslationOptions(TranslationOptions):
|
||||
"""Class for registration translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(SignupForm)
|
||||
class SignupFormTranslationOptions(TranslationOptions):
|
||||
"""Class for registration translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(TemplateQuestion)
|
||||
class TemplateQuestionTranslationOptions(TranslationOptions):
|
||||
"""Class for registration translation options."""
|
||||
|
||||
fields = ()
|
||||
@@ -1,27 +0,0 @@
|
||||
"""Signup urls."""
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from signup.views import new_signup # , open_signups
|
||||
# from kaehmy.views import list_view
|
||||
# from kaehmy.views import submit
|
||||
# from kaehmy.views import comment
|
||||
# from kaehmy.views import statistics_view
|
||||
# from kaehmy.views import export_view
|
||||
|
||||
urlpatterns = [
|
||||
# signup
|
||||
# url(r'^$', open_signups),
|
||||
# url(r'^list$', open_signups),
|
||||
url(r'^(?P<idx>\d+)$', new_signup),
|
||||
# url(r'^$', list_view),
|
||||
# url(r'^submit', submit),
|
||||
# url(r'^statistics', statistics_view),
|
||||
# url(r'^export', export_view),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
urlpatterns += staticfiles_urlpatterns()
|
||||
@@ -1,9 +0,0 @@
|
||||
from django.shortcuts import render
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||
from members.views.utils import *
|
||||
from signup.models import SignupForm
|
||||
|
||||
|
||||
def new_signup(request, *args, **kwargs):
|
||||
pass
|
||||
@@ -92,7 +92,6 @@ INSTALLED_APPS = [
|
||||
'webapp',
|
||||
'members',
|
||||
'infoscreen',
|
||||
'signup',
|
||||
'coffee_scale',
|
||||
'kaehmy',
|
||||
'ohlhafv',
|
||||
|
||||
@@ -27,7 +27,6 @@ import infoscreen.urls
|
||||
import members.urls
|
||||
import coffee_scale.urls
|
||||
import password_reset.urls
|
||||
import signup.urls
|
||||
|
||||
urlpatterns = [
|
||||
url(r'', include('webapp.urls')),
|
||||
@@ -36,7 +35,6 @@ urlpatterns = [
|
||||
url(r'^coffee/', include('coffee_scale.urls')),
|
||||
url(r'^kaehmy/', include('kaehmy.urls')),
|
||||
url(r'^ohlhafv/', include('ohlhafv.urls')),
|
||||
url(r'^signup/', include('signup.urls')),
|
||||
|
||||
# admin
|
||||
url(r'^admin/', admin.site.urls),
|
||||
|
||||
+5
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
from django.contrib import admin
|
||||
from webapp.models import Official, Role, Committee
|
||||
from webapp.models import Feed, Tag, BaseFeed
|
||||
from webapp.models import Feed, Tag, BaseFeed, Event, Signup, SignupForm, TemplateQuestion
|
||||
from modeltranslation.admin import TranslationAdmin
|
||||
from django.contrib.auth.models import Permission
|
||||
# this is needed so that the models get registered for translation
|
||||
@@ -12,6 +12,10 @@ admin.site.register(Permission)
|
||||
|
||||
admin.site.register(Feed, TranslationAdmin)
|
||||
admin.site.register(Tag, TranslationAdmin)
|
||||
admin.site.register(Event, TranslationAdmin)
|
||||
admin.site.register(SignupForm, TranslationAdmin)
|
||||
admin.site.register(Signup, TranslationAdmin)
|
||||
admin.site.register(TemplateQuestion, TranslationAdmin)
|
||||
admin.site.register(Official)
|
||||
admin.site.register(Role)
|
||||
admin.site.register(Committee)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11 on 2018-06-19 17:09
|
||||
# Generated by Django 1.11 on 2018-07-05 15:51
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
@@ -9,26 +9,17 @@ import django.utils.timezone
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('webapp', '0043_auto_20180605_1953'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Answer',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('answer', models.CharField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Event',
|
||||
fields=[
|
||||
('basefeed_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='webapp.BaseFeed')),
|
||||
('start', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('end', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('start_time', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('end_time', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Event',
|
||||
@@ -36,53 +27,51 @@ class Migration(migrations.Migration):
|
||||
},
|
||||
bases=('webapp.basefeed',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Question',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('questions', models.CharField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Signup',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('time', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('answer', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Sign-up',
|
||||
'verbose_name_plural': 'Sign-ups',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SignupForm',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('start', models.DateTimeField()),
|
||||
('end', models.DateTimeField()),
|
||||
('questions', models.ManyToManyField(to='signup.Question')),
|
||||
('start', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('end', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('question', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'SignupForm',
|
||||
'verbose_name_plural': 'SignupForm',
|
||||
'verbose_name': 'Signup form',
|
||||
'verbose_name_plural': 'Signup forms',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TemplateQuestion',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('questions', models.CharField(max_length=255)),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('question', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Template question',
|
||||
'verbose_name_plural': 'Template questions',
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='signup',
|
||||
name='signupForm',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='signup.SignupForm'),
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='webapp.SignupForm'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='signupForm',
|
||||
field=models.ManyToManyField(blank=True, to='signup.SignupForm'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='answer',
|
||||
name='signup',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='signup.Signup'),
|
||||
field=models.ManyToManyField(blank=True, to='webapp.SignupForm'),
|
||||
),
|
||||
]
|
||||
@@ -9,6 +9,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth.models import User
|
||||
from auditlog.registry import auditlog
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
|
||||
import logging
|
||||
|
||||
@@ -55,11 +56,86 @@ class Feed(BaseFeed):
|
||||
verbose_name_plural = _('Feeds')
|
||||
|
||||
|
||||
class Event(BaseFeed):
|
||||
"""Model for event."""
|
||||
|
||||
start_time = models.DateTimeField(default=timezone.now)
|
||||
end_time = models.DateTimeField(default=timezone.now)
|
||||
signupForm = models.ManyToManyField(
|
||||
'SignupForm', blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return _('Event: {}').format(self.title)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Event')
|
||||
verbose_name_plural = _('Events')
|
||||
|
||||
|
||||
class TemplateQuestion(models.Model):
|
||||
"""Stores template questions for signup forms as JSONB"""
|
||||
# question = JSONField()
|
||||
name = models.CharField(max_length=255)
|
||||
question = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return _('Template questions: {}').format(self.name)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Template question')
|
||||
verbose_name_plural = _('Template questions')
|
||||
|
||||
|
||||
class SignupForm(models.Model):
|
||||
"""Model for event signup form. Stores questions in JSONB."""
|
||||
|
||||
start = models.DateTimeField(default=timezone.now)
|
||||
end = models.DateTimeField(default=timezone.now)
|
||||
# question = JSONField()
|
||||
question = models.CharField(max_length=255)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Signup form')
|
||||
verbose_name_plural = _('Signup forms')
|
||||
|
||||
|
||||
class Signup(models.Model):
|
||||
signupForm = models.ForeignKey('SignupForm', on_delete=models.CASCADE)
|
||||
time = models.DateTimeField(default=timezone.now)
|
||||
answer = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return _('Sign-ups: {}').format(self.signupForm)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Sign-up')
|
||||
verbose_name_plural = _('Sign-ups')
|
||||
|
||||
|
||||
|
||||
class BaseRole(models.Model):
|
||||
"""Base model for occupations/roles."""
|
||||
|
||||
# CATEGORIES = (
|
||||
# ('corporate', _('Corporate affairs')),
|
||||
# ('freshman', _('Freshmen')),
|
||||
# ('international', _('International')),
|
||||
# ('external', _('External affairs')),
|
||||
# ('media', _('Media')),
|
||||
# ('tech', _('Technology')),
|
||||
# ('wellbeing', _('Wellbeing')),
|
||||
# ('elepaja', _('Elepaja')),
|
||||
# ('ceremonies', _('Ceremonies')),
|
||||
# ('culture', _('Culture')),
|
||||
# ('studies', _('Studies')),
|
||||
# ('sosso', _('Sössö magazine')),
|
||||
# ('alumni', _('Alumni relations')),
|
||||
# ('others', _('Others')),
|
||||
# )
|
||||
|
||||
name = models.CharField(_('Name'), max_length=255)
|
||||
is_board = models.BooleanField(_('Board member'))
|
||||
# category = models.CharField(_('Category'), choices=CATEGORIES, default='others', max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
n = self.name.capitalize()
|
||||
@@ -131,6 +207,8 @@ class Official(User):
|
||||
|
||||
auditlog.register(Tag)
|
||||
auditlog.register(Feed)
|
||||
auditlog.register(Event)
|
||||
auditlog.register(Signup)
|
||||
auditlog.register(PresetRole)
|
||||
auditlog.register(Role)
|
||||
auditlog.register(Official)
|
||||
|
||||
+30
-1
@@ -1,7 +1,7 @@
|
||||
"""Translation classes."""
|
||||
|
||||
from modeltranslation.translator import register, TranslationOptions
|
||||
from webapp.models import BaseFeed, Feed, Tag
|
||||
from webapp.models import BaseFeed, Feed, Tag, Event, Signup, SignupForm, TemplateQuestion
|
||||
from webapp.models import PresetRole, BaseRole
|
||||
|
||||
|
||||
@@ -26,6 +26,35 @@ class TagTranslationOptions(TranslationOptions):
|
||||
fields = ('name',)
|
||||
|
||||
|
||||
@register(Event)
|
||||
class EventTranslationOptions(TranslationOptions):
|
||||
"""Class for event translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(Signup)
|
||||
class SignupTranslationOptions(TranslationOptions):
|
||||
"""Class for registration translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(SignupForm)
|
||||
class SignupFormTranslationOptions(TranslationOptions):
|
||||
"""Class for registration translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(TemplateQuestion)
|
||||
class TemplateQuestionTranslationOptions(TranslationOptions):
|
||||
"""Class for registration translation options."""
|
||||
|
||||
fields = ()
|
||||
|
||||
|
||||
|
||||
@register(BaseRole)
|
||||
class BaseRoleTranslationOptions(TranslationOptions):
|
||||
"""Class for base role translation options"""
|
||||
|
||||
Reference in New Issue
Block a user