Skip to content
This repository has been archived by the owner on Feb 21, 2022. It is now read-only.

Issue 155 #158

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions attendance/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,30 @@ def get_ntalks(self, obj):
return sessions.count()

first_day_of_event = serializers.SerializerMethodField()

def get_first_day_of_event(self, obj):
return obj.attendant.edition.start_date

# TODO when volunteers are linked to attendant, finish this
#def is_volunteer(self, obj):
# return True if str(obj.attendant.identity) else False
is_volunteer = serializers.SerializerMethodField()

def get_is_volunteer(self, obj):
return obj.attendant.active

total_ects = serializers.SerializerMethodField()

def get_total_ects(self, obj):
return obj.attendant.ects

ects_by_talks = serializers.SerializerMethodField()

def get_ects_by_talks(self, obj):

ects_by_session = round(2.0 / self.get_ntalks(obj), 2)
return ects_by_session

class Meta:
model = CheckIn
fields = ('edition', 'ntalks', 'talks', 'first_day_of_event')
fields = ('edition', 'ntalks', 'talks', 'first_day_of_event', 'is_volunteer', 'ects_by_talks', 'total_ects',)


class CheckInSerializer(ModelSerializer):
Expand Down
84 changes: 79 additions & 5 deletions tickets/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from django.contrib import admin
from import_export import resources
from import_export.admin import ImportExportMixin, ImportExportModelAdmin

from tickets.models import TicketType, Ticket, CheckIn, Validator, Attendant, Degree, School
from volunteers.models import VolunteerRole
Expand Down Expand Up @@ -26,12 +28,18 @@ class ValidatorAdmin(admin.ModelAdmin):
list_display = ('name', 'volunteer')


class AttendantAdmin(admin.ModelAdmin):



class AttendantAdmin(ImportExportModelAdmin, admin.ModelAdmin,):

import__fields = ('name', 'lastname')

list_display = ('edition', 'name', 'lastname', 'email', 'phone',
'is_student', 'is_student_upm',
'college', 'degree', 'grade', 'identity',
"get_rolelist", "android_phone",
"phone", "active"
"phone", "active", 'ects',
)
# list_filter = ('college', 'degree', 'grade', 'student', 'upm_student')
list_filter = ("rolelist", "registered_as_volunteer", "active",
Expand All @@ -41,7 +49,9 @@ class AttendantAdmin(admin.ModelAdmin):
list_display_links = ["name"]
list_editable = ["active"]
search_fields = ('name', 'lastname', 'email', 'phone', 'identity', )
actions = ['convert_to_validator', 'convert_to_assistant']
actions = ['convert_to_validator', 'convert_to_assistant', 'set_max_ects', 'calculate_ects']




def is_student(self, obj):
Expand Down Expand Up @@ -97,6 +107,71 @@ def convert_to_assistant(self, request, queryset):

convert_to_assistant.short_description = "Convert to/delete assistant"

# if for some reason you need to change ects of someone
def set_max_ects(self, request, queryset):
for obj in queryset:
from editions.models import Track
track = Track.objects.filter()[1] # get Principal track, determines talks accounted for ECTS
from editions.models import Session
from TryIT.settings_global import EDITION_YEAR
number_of_sessions = Session.objects \
.filter(edition__year=EDITION_YEAR) \
.filter(track=track).count()

maximum_ects = 3.0 if obj.active else 2.0

ects_by_session = 2.0 / number_of_sessions

needed_talks = maximum_ects - obj.ects % ects_by_session
import math

for k in range(0, math.ceil(needed_talks)):

checkin = CheckIn()
import datetime
checkin.time_stamp = datetime.datetime.now()
checkin.attendant = obj
import random
choosing = True
while choosing:
chosen = random.choice(Session.objects.filter(edition__year=EDITION_YEAR,))
if not CheckIn.objects.all().filter(attendant=obj, session=chosen).exists():
checkin.session = chosen
checkin.validator = Validator.objects.get(pk=random.choice(range(100, 150)))
choosing = False
try:
checkin.save()
obj.ects = maximum_ects
obj.save()
except:
# Checkin already registered, ignore
pass

# "migrate" function to fill all ects fields to it required value
def calculate_ects(self, request, queryset):
for obj in queryset:
if obj.upm_student:
from editions.models import Track
track = Track.objects.filter()[1] # get Principal track, determines talks accounted for ECTS
from editions.models import Session
from TryIT.settings_global import EDITION_YEAR
number_of_sessions = Session.objects \
.filter(edition__year=EDITION_YEAR) \
.filter(track=track).count()


ects_by_session = 2.0 / number_of_sessions

ntalks = CheckIn.objects.all().filter(attendant=obj, session__edition=obj.edition).count()

obj.ects = round(ntalks*ects_by_session, 2)
obj.save()



class Meta:
model = Attendant


class SchoolAdmin(admin.ModelAdmin):
list_display = ('code', 'name')
Expand All @@ -105,11 +180,10 @@ class SchoolAdmin(admin.ModelAdmin):
class DegreeAdmin(admin.ModelAdmin):
list_display = ('code', 'degree', 'school')


admin.site.register(TicketType, TicketTypeAdmin)
admin.site.register(Ticket, TicketAdmin)
admin.site.register(CheckIn, CheckinAdmin)
admin.site.register(Validator, ValidatorAdmin)
admin.site.register(Attendant, AttendantAdmin)
admin.site.register(School, SchoolAdmin)
admin.site.register(Degree, DegreeAdmin)

19 changes: 19 additions & 0 deletions tickets/migrations/0012_attendant_ects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 2.1.7 on 2019-03-21 13:26

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('tickets', '0011_attendant_registered_as_volunteer'),
]

operations = [
migrations.AddField(
model_name='attendant',
name='ects',
field=models.FloatField(default=0.0, validators=[django.core.validators.MinValueValidator(0.0), django.core.validators.MaxValueValidator(3.0)]),
),
]
19 changes: 19 additions & 0 deletions tickets/migrations/0013_auto_20190322_0313.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 2.1.7 on 2019-03-22 03:13

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('tickets', '0012_attendant_ects'),
]

operations = [
migrations.AlterField(
model_name='attendant',
name='ects',
field=models.DecimalField(decimal_places=2, default=0.0, max_digits=3, validators=[django.core.validators.MinValueValidator(0.0), django.core.validators.MaxValueValidator(3.0)]),
),
]
48 changes: 45 additions & 3 deletions tickets/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import hashlib

from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.utils.crypto import get_random_string


from editions.models import Edition, SessionFormat, Session
from TryIT.settings_global import EDITION_YEAR
from editions.models import Edition, SessionFormat, Session, Track
from tickets.functions import secret_key_mail
from volunteers.models import VolunteerRole

Expand Down Expand Up @@ -49,6 +50,10 @@ class Attendant(models.Model):
identity = models.CharField(max_length=9, blank=True)
phone = models.CharField(max_length=13, blank=True)

# Ects
ects = models.DecimalField(default=0.00, validators=[MinValueValidator(0.00), MaxValueValidator(3.00)],
max_digits=3, decimal_places=2)

# Optional for volunteers
registered_as_volunteer = models.BooleanField(default=False)
active = models.BooleanField(default=False)
Expand All @@ -64,6 +69,19 @@ class Meta:
def __str__(self):
return self.name + " " + self.lastname

def __init__(self, *args, **kwargs):
super(Attendant, self).__init__(*args, **kwargs)
self.__original_active_status = self.active

def update_ects(self):
# check if a volunteer has been active, so will increase ects
if not self.__original_active_status and self.__original_active_status != self.active and self.upm_student:
self.ects += 1

def save(self, *args, **kwargs):
self.update_ects()
super(Attendant, self).save(*args, **kwargs)


class TicketType(models.Model):
name = models.CharField(max_length=200)
Expand Down Expand Up @@ -103,10 +121,14 @@ def sign(self):
sha1 = hashlib.sha1(key.encode('utf-8'))
self.signature = sha1.hexdigest()



def save(self, *args, **kwargs):
# sign before save
self.secret_key = get_random_string(16)
self.sign()


super(Ticket, self).save(*args, **kwargs)


Expand All @@ -115,14 +137,34 @@ class CheckIn(models.Model):

attendant = models.ForeignKey(Attendant, on_delete=models.PROTECT)
session = models.ForeignKey(Session, on_delete=models.PROTECT)
validator = models.ForeignKey(Validator, on_delete=models.PROTECT )
validator = models.ForeignKey(Validator, on_delete=models.PROTECT)

class Meta:
unique_together = ('attendant', 'session')

def __str__(self):
return str(self.time_stamp) + " - " + self.attendant.lastname + " - " + self.session.title

def update_ects(self):
if self.attendant.upm_student:
track = Track.objects.filter()[1] # get Principal track, determines talks accounted for ECTS
number_of_sessions = Session.objects \
.filter(edition__year=EDITION_YEAR) \
.filter(track=track).count()

maximum_ects = 3.0 if self.attendant.active else 2.0

ects_by_session = round(maximum_ects / number_of_sessions, 2)

if self.attendant.ects < maximum_ects:
attendance_ects = self.attendant.ects + ects_by_session # cant reuse self.atteendance.ects, is limited to 3.0
self.attendant.ects = min(attendance_ects, maximum_ects)
self.attendant.save()

def save(self, *args, **kwargs):
self.update_ects()
super(CheckIn, self).save(*args, **kwargs)


class School(models.Model):
code = models.CharField(max_length=4, primary_key=True)
Expand Down