Skip to content

Commit

Permalink
Merge pull request #751 from dotKom/guest-attendance
Browse files Browse the repository at this point in the history
Reservations (WIP)
  • Loading branch information
hernil committed Aug 17, 2014
2 parents b45f1c9 + 6f29bdd commit cde6328
Show file tree
Hide file tree
Showing 8 changed files with 441 additions and 55 deletions.
58 changes: 50 additions & 8 deletions apps/events/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-

from django import forms
from django.contrib import admin
from django.contrib import admin, messages
from django.core import validators
from django.utils.translation import ugettext as _

Expand All @@ -13,6 +13,8 @@
from apps.events.models import FieldOfStudyRule
from apps.events.models import GradeRule
from apps.events.models import UserGroupRule
from apps.events.models import Reservation
from apps.events.models import Reservee
from apps.feedback.admin import FeedbackRelationInline


Expand Down Expand Up @@ -116,13 +118,15 @@ def save_model(self, request, obj, form, change):
else:
# If attendance max capacity changed we will notify users that they are now on the attend list
old_event = Event.objects.get(id=obj.id)
if old_event.is_attendance_event() and old_event.wait_list:
diff_capacity = obj.attendance_event.max_capacity - old_event.attendance_event.max_capacity
if diff_capacity > 0:
if diff_capacity > len(old_event.wait_list):
diff_capacity = len(old_event.wait_list)
# Using old_event because max_capacity has already been changed in obj
old_event.notify_waiting_list(host=request.META['HTTP_HOST'], extra_capacity=diff_capacity)
if old_event.is_attendance_event():
old_waitlist_size = old_event.attendance_event.waitlist_qs.count()
if old_waitlist_size > 0:
diff_capacity = obj.attendance_event.max_capacity - old_event.attendance_event.max_capacity
if diff_capacity > 0:
if diff_capacity > old_waitlist_size:
diff_capacity = old_waitlist_size
# Using old_event because max_capacity has already been changed in obj
old_event.notify_waiting_list(host=request.META['HTTP_HOST'], extra_capacity=diff_capacity)
obj.save()

def save_formset(self, request, form, formset, change):
Expand All @@ -139,9 +143,47 @@ def get_form(self, request, obj=None, **kwargs):
return form


class ReserveeInline(admin.TabularInline):
model = Reservee
extra = 1
classes = ('grp-collapse grp-open',) # style
inline_classes = ('grp-collapse grp-open',) # style


class ReservationAdmin(admin.ModelAdmin):
model = Reservation
inlines = (ReserveeInline,)
max_num = 1
extra = 0
list_display = ('attendance_event', '_number_of_seats_taken', 'seats', '_attendees', '_max_capacity')
classes = ('grp-collapse grp-open',) # style
inline_classes = ('grp-collapse grp-open',) # style

def _number_of_seats_taken(self, obj):
return obj.number_of_seats_taken
_number_of_seats_taken.short_description = _("Fylte reservasjoner")

def _attendees(self, obj):
return obj.attendance_event.number_of_attendees
_attendees.short_description = _("Antall deltakere")

def _max_capacity(self, obj):
return obj.attendance_event.max_capacity
_max_capacity.short_description = _("Arrangementets maks-kapasitet")

def save_model(self, request, obj, form, change):
if change:
number_of_free_seats = obj.attendance_event.max_capacity - obj.attendance_event.number_of_attendees
if number_of_free_seats < obj.seats:
obj.seats = number_of_free_seats
self.message_user(request, _("Du har valgt et antall reserverte plasser som overskrider antallet ledige plasser for dette arrangementet. Antallet ble automatisk justert til %d (alle ledige plasser).") % number_of_free_seats, messages.WARNING)
obj.save()


admin.site.register(Event, EventAdmin)
admin.site.register(Attendee, AttendeeAdmin)
admin.site.register(RuleBundle, RuleBundleAdmin)
admin.site.register(GradeRule, GradeRuleAdmin)
admin.site.register(UserGroupRule, UserGroupRuleAdmin)
admin.site.register(FieldOfStudyRule, FieldOfStudyRuleAdmin)
admin.site.register(Reservation, ReservationAdmin)
185 changes: 185 additions & 0 deletions apps/events/migrations/0007_auto__add_reservation__add_reservee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding model 'Reservation'
db.create_table(u'events_reservation', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('attendance_event', self.gf('django.db.models.fields.related.OneToOneField')(related_name='reserved_seats', unique=True, to=orm['events.AttendanceEvent'])),
('seats', self.gf('django.db.models.fields.PositiveIntegerField')()),
))
db.send_create_signal(u'events', ['Reservation'])

# Adding model 'Reservee'
db.create_table(u'events_reservee', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('reservation', self.gf('django.db.models.fields.related.ForeignKey')(related_name='reservees', to=orm['events.Reservation'])),
('name', self.gf('django.db.models.fields.CharField')(max_length=69)),
('note', self.gf('django.db.models.fields.CharField')(max_length=100)),
('allergies', self.gf('django.db.models.fields.CharField')(max_length=200)),
))
db.send_create_signal(u'events', ['Reservee'])


def backwards(self, orm):
# Deleting model 'Reservation'
db.delete_table(u'events_reservation')

# Deleting model 'Reservee'
db.delete_table(u'events_reservee')


models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'authentication.onlineuser': {
'Meta': {'ordering': "['first_name', 'last_name']", 'object_name': 'OnlineUser'},
'address': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'allergies': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'compiled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'field_of_study': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gender': ('django.db.models.fields.CharField', [], {'default': "'male'", 'max_length': '10'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'infomail': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'mark_rules': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'nickname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
'ntnu_username': ('django.db.models.fields.CharField', [], {'max_length': '10', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
'rfid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
'started_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2014, 2, 19, 0, 0)'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'})
},
u'companyprofile.company': {
'Meta': {'object_name': 'Company'},
'email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('filebrowser.fields.FileBrowseField', [], {'max_length': '200'}),
'long_description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
'short_description': ('django.db.models.fields.TextField', [], {'max_length': '200'}),
'site': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'events.attendanceevent': {
'Meta': {'object_name': 'AttendanceEvent'},
'event': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'attendance_event'", 'unique': 'True', 'primary_key': 'True', 'to': u"orm['events.Event']"}),
'guest_attendance': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'max_capacity': ('django.db.models.fields.PositiveIntegerField', [], {}),
'registration_end': ('django.db.models.fields.DateTimeField', [], {}),
'registration_start': ('django.db.models.fields.DateTimeField', [], {}),
'rule_bundles': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['events.RuleBundle']", 'null': 'True', 'blank': 'True'}),
'unattend_deadline': ('django.db.models.fields.DateTimeField', [], {}),
'waitlist': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
},
u'events.attendee': {
'Meta': {'ordering': "['timestamp']", 'unique_together': "(('event', 'user'),)", 'object_name': 'Attendee'},
'attended': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'event': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attendees'", 'to': u"orm['events.AttendanceEvent']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'note': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}),
'paid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['authentication.OnlineUser']"})
},
u'events.companyevent': {
'Meta': {'object_name': 'CompanyEvent'},
'company': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['companyprofile.Company']"}),
'event': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'companies'", 'to': u"orm['events.Event']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
u'events.event': {
'Meta': {'object_name': 'Event'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'oppretter'", 'to': u"orm['authentication.OnlineUser']"}),
'description': ('django.db.models.fields.TextField', [], {}),
'event_end': ('django.db.models.fields.DateTimeField', [], {}),
'event_start': ('django.db.models.fields.DateTimeField', [], {}),
'event_type': ('django.db.models.fields.SmallIntegerField', [], {}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('filebrowser.fields.FileBrowseField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'ingress': ('django.db.models.fields.TextField', [], {}),
'ingress_short': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '45'})
},
u'events.fieldofstudyrule': {
'Meta': {'object_name': 'FieldOfStudyRule', '_ormbases': [u'events.Rule']},
'field_of_study': ('django.db.models.fields.SmallIntegerField', [], {}),
u'rule_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['events.Rule']", 'unique': 'True', 'primary_key': 'True'})
},
u'events.graderule': {
'Meta': {'object_name': 'GradeRule', '_ormbases': [u'events.Rule']},
'grade': ('django.db.models.fields.SmallIntegerField', [], {}),
u'rule_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['events.Rule']", 'unique': 'True', 'primary_key': 'True'})
},
u'events.reservation': {
'Meta': {'object_name': 'Reservation'},
'attendance_event': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'reserved_seats'", 'unique': 'True', 'to': u"orm['events.AttendanceEvent']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'seats': ('django.db.models.fields.PositiveIntegerField', [], {})
},
u'events.reservee': {
'Meta': {'ordering': "['id']", 'object_name': 'Reservee'},
'allergies': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '69'}),
'note': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'reservation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reservees'", 'to': u"orm['events.Reservation']"})
},
u'events.rule': {
'Meta': {'object_name': 'Rule'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'offset': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'})
},
u'events.rulebundle': {
'Meta': {'object_name': 'RuleBundle'},
'description': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'field_of_study_rules': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['events.FieldOfStudyRule']", 'null': 'True', 'blank': 'True'}),
'grade_rules': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['events.GradeRule']", 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user_group_rules': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['events.UserGroupRule']", 'null': 'True', 'blank': 'True'})
},
u'events.usergrouprule': {
'Meta': {'object_name': 'UserGroupRule', '_ormbases': [u'events.Rule']},
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.Group']"}),
u'rule_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['events.Rule']", 'unique': 'True', 'primary_key': 'True'})
}
}

complete_apps = ['events']
Loading

0 comments on commit cde6328

Please sign in to comment.