diff --git a/.gitignore b/.gitignore index ffd9a26..b606e14 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ logs/ /media/ node_modules/ /.coverage +db.sqlite3 +requirements_henu.txt diff --git a/members/admin.py b/members/admin.py index bacee5d..7550b85 100644 --- a/members/admin.py +++ b/members/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from members.models import Member, MemberRequest +from members.models import Member, Request # Register your models here. admin.site.register(Member) -admin.site.register(MemberRequest) +admin.site.register(Request) diff --git a/members/migrations/0003_auto_20170329_1928.py b/members/migrations/0003_auto_20170329_1928.py new file mode 100644 index 0000000..ddffdda --- /dev/null +++ b/members/migrations/0003_auto_20170329_1928.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-03-29 16:28 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('members', '0002_auto_20170329_1857'), + ] + + operations = [ + migrations.CreateModel( + name='Payment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateTimeField(default=datetime.datetime(1970, 1, 1, 2, 0))), + ('source', models.CharField(max_length=255)), + ('first_name', models.CharField(max_length=255)), + ('last_name', models.CharField(max_length=255)), + ('email', models.EmailField(max_length=255)), + ], + ), + migrations.CreateModel( + name='Request', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=127)), + ('last_name', models.CharField(max_length=127)), + ('email', models.EmailField(max_length=254)), + ('POR', models.CharField(default='ei_tiedossa', max_length=255)), + ('AYY', models.BooleanField(default=False)), + ('jas', models.BooleanField(default=False)), + ('submitted', models.DateTimeField(default=django.utils.timezone.now)), + ], + options={ + 'abstract': False, + }, + ), + migrations.RemoveField( + model_name='memberrequest', + name='member', + ), + migrations.AlterField( + model_name='member', + name='POR', + field=models.CharField(default='ei_tiedossa', max_length=255), + ), + migrations.AlterField( + model_name='member', + name='paid', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.DeleteModel( + name='MemberRequest', + ), + migrations.AddField( + model_name='payment', + name='member', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='members.Member'), + ), + ] diff --git a/members/models.py b/members/models.py index d0b47da..744bf94 100644 --- a/members/models.py +++ b/members/models.py @@ -4,115 +4,54 @@ from datetime import datetime from io import StringIO import csv - -class Member(models.Model): +class BaseMember(models.Model): ''' - Member model represets one member on the registry + Base model for member. ''' - first_name = models.CharField(max_length=127) last_name = models.CharField(max_length=127) email = models.EmailField() - POR = models.CharField(max_length=255) # place of residence + POR = models.CharField(default="ei_tiedossa", max_length=255) # place of residence AYY = models.BooleanField(default=False) jas = models.BooleanField(default=False) - created = models.DateTimeField(default=timezone.now) - paid = models.DateTimeField(default=datetime.fromtimestamp(0)) - - def get_dict(self): - return { - 'id': self.id, - 'first_name': self.first_name, - 'last_name': self.last_name, - 'email': self.email, - 'POR': self.POR, - 'AYY': self.AYY, - 'jas': self.jas, - 'created': date2str(self.created), - 'paid': date2str(self.paid), - } - @classmethod - def create_from_dict(cls, d): - mbr = cls() - mbr.update_from_dict(d) - return mbr - - def update_from_dict(self, d): - dmap = { - 'first_name': reverse_map('first_name'), - 'last_name': reverse_map('last_name'), - 'email': reverse_map('email'), - 'POR': reverse_map('POR'), - 'AYY': reverse_map('AYY'), - 'jas': reverse_map('jas'), - 'paid': reverse_map('paid', str2date), - } - for k, v in d.items(): - try: - self.__setattr__(dmap[k].key, dmap[k].parser(v)) - except KeyError: - pass - self.save() - - @classmethod - def import_csv(cls, csv_string): - reader = csv.reader(StringIO(csv_string.strip())) - response = {"status": "success", "errors": []} - try: - data = list(reader) - except ValueError: - return {"status": "failure", "errors": ["could not parse csv file"]} - - affirmative_answers = ['yes', 'y', '1', 'true', "kyllä", "khyl"] - for row in data: - - try: - obj = cls.objects.create( - first_name=row[0].strip(), - last_name=row[1].strip(), - email=row[2].strip(), - POR=row[3].strip(), - AYY=row[4].lower().strip() in affirmative_answers, - jas=row[5].lower().strip() in affirmative_answers, - paid=timezone.now() - ) - print("added obj {}".format(obj)) - - except: - response["status"] = "failure" - response["errors"].append("failure adding item {}".format(", ".join(row))) - - return response - - def __str__(self): - return "{} {}".format(self.first_name, self.last_name) + class Meta: + abstract = True -class MemberRequest(models.Model): - member = models.ForeignKey(Member) +class Request(BaseMember): + ''' + Member request model represents one member request. + ''' + submitted = models.DateTimeField(default=timezone.now) + + +class Payment(models.Model): + ''' + Payment model representing one payment event + ''' + date = models.DateTimeField(default=datetime.fromtimestamp(0)) + source = models.CharField(max_length=255) + first_name = models.CharField(max_length=255) + last_name = models.CharField(max_length=255) + email = models.EmailField(max_length=255) + member = models.ForeignKey('Member', on_delete=models.SET_NULL, blank=True, null=True) def get_dict(self): return { 'id': self.id, - 'member': self.member.get_dict(), + 'date': date2str(self.date), + 'source': self.source, + 'first_name': self.first_name, + 'last_name': self.last_name, + 'email': self.email, + 'member': self.member.get_dict() if self.member else {} } -def date2str(date): +class Member(BaseMember): ''' - Convert date to a standard date string + Member model represets one member on the registry. ''' - if date is None: - return None - return date.strftime("%Y-%m-%d %H:%M:%S") - - -def str2date(s): - return datetime.strptime(s,"%Y-%m-%d %H:%M:%S") - - -class reverse_map: - def __init__(self, key, parser=lambda x: x): - self.key = key - self.parser = parser + created = models.DateTimeField(default=timezone.now) + paid = models.DateTimeField(default=timezone.now) #this needs to be assigned as Payment.date diff --git a/members/serializers.py b/members/serializers.py index bcf8793..c473ff5 100644 --- a/members/serializers.py +++ b/members/serializers.py @@ -1,7 +1,7 @@ from rest_framework import serializers from django.utils import timezone from datetime import datetime -from members.models import Member, MemberRequest +from members.models import Member, Request from django.conf import settings @@ -37,10 +37,32 @@ class MemberSerializer(serializers.Serializer): instance.save() return instance -class MemberRequestSerializer(serializers.ModelSerializer): +class MemberRequestSerializer(serializers.Serializer): id = serializers.IntegerField(read_only=True) - member = MemberSerializer() + submitted = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") + first_name = serializers.CharField(required=True, max_length=127) + last_name = serializers.CharField(required=True, max_length=127) + email = serializers.EmailField(min_length=None, max_length=None, required=True) + POR = serializers.CharField(max_length=255) + AYY = serializers.BooleanField(default=False) + jas = serializers.BooleanField(default=False) - class Meta: - model = MemberRequest - fields = ('id', 'member') + def created(self, validated_data): + ''' + Create and return a new MemberRequest instance, given the validated data. + ''' + return MemberRequest.objects.create(**validated_data) + + def update(self, instance, validated_data): + ''' + Update and return an existing Member request instance given the validated data. + ''' + instance.submitted = validated_data.get('submitted', instance.submitted) + instance.first_name = validated_data.get('first_name', instance.first_name) + instance.last_name = validated_data.get('last_name', instance.last_name) + instance.email = validated_data.get('email', instance.email) + instance.POR = validated_data.get('POR', instance.POR) + instance.AYY = validated_data.get('AYY', instance.AYY) + instance.jas = validated_data.get('jas', instance.jas) + instance.save() + return instance diff --git a/members/templates/members_index.html b/members/templates/members_index.html deleted file mode 100644 index 6cac673..0000000 --- a/members/templates/members_index.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "members_base.html" %} - -{% block content %} -
- - - - - - -
- -
-
-{% endblock content %} diff --git a/members/views.py b/members/views.py index bdfdaff..851dc2e 100644 --- a/members/views.py +++ b/members/views.py @@ -4,7 +4,7 @@ from django.views.decorators.http import require_http_methods from django.views.decorators.csrf import ensure_csrf_cookie from django.http import HttpResponse, HttpResponseBadRequest from django.core.exceptions import ValidationError -from members.models import Member, MemberRequest +from members.models import Member, Request import json from django.core.mail import send_mail import requests @@ -32,7 +32,6 @@ class MembersList(generics.ListCreateAPIView): permission_classes = (HasRights, permissions.IsAuthenticated, ) throttle_classes = (BurstRateThrottle, SustainedRateThrottle, ) - class MemberDetails(generics.RetrieveUpdateDestroyAPIView): queryset = Member.objects.all() serializer_class = MemberSerializer @@ -40,13 +39,13 @@ class MemberDetails(generics.RetrieveUpdateDestroyAPIView): throttle_classes = (BurstRateThrottle, SustainedRateThrottle, ) class MemberRequestList(generics.ListCreateAPIView): - queryset = MemberRequest.objects.all() + queryset = Request.objects.all() serializer_class = MemberRequestSerializer permission_classes = (HasRights, permissions.IsAuthenticated, ) throttle_classes = (BurstRateThrottle, SustainedRateThrottle, ) class MemberRequestDetail(generics.RetrieveUpdateDestroyAPIView): - queryset = MemberRequest.objects.all() + queryset = Request.objects.all() serializer_class = MemberRequestSerializer permission_classes = (HasRights, permissions.IsAuthenticated, ) throttle_classes = (BurstRateThrottle, SustainedRateThrottle, ) diff --git a/misc/create_dummydata.py b/misc/create_dummydata.py index f1c16df..d694dd2 100644 --- a/misc/create_dummydata.py +++ b/misc/create_dummydata.py @@ -9,8 +9,7 @@ from django.conf import settings django.setup() #django related stuff should be imported below this -from members.models import Member, MemberRequest -from infoscreen.models import Rotation, ExternalImageInfoItem, InfoInstance +from members.models import Member, Request from misc.namegenerator import generate_names MEMBERAMOUNT = 30 MEMBERREQUESTAMOUNT = 3 @@ -47,3 +46,21 @@ inst = InfoInstance.objects.create( item=i_item, duration=20.0 ) + +# for m in list(Member.objects.all())[:5]: +# MemberRequest.objects.create(member=m) +names = generate_names(MEMBERREQUESTAMOUNT) +maildomains = ["example.coms",'ggmail.om',"notmail.dom"] #intentionally wrong +places = ["Helsinki", "Espoo", "Korso","Kerava", "Kouvostoliitto"] +for i in range(MEMBERREQUESTAMOUNT): + f,l = names[i] + mail = "{}.{}@{}".format(f.lower(),l.lower(),random.choice(maildomains)) + por = random.choice(places) + ayy = random.randint(0,1) + jas = random.randint(0,1) + Request.objects.create(first_name=f, + last_name=l, + email=mail, + POR=por, + AYY=ayy, + jas=jas)