Merge branch 'feature-payment' into develop
This commit is contained in:
@@ -13,3 +13,5 @@ logs/
|
||||
/media/
|
||||
node_modules/
|
||||
/.coverage
|
||||
db.sqlite3
|
||||
requirements_henu.txt
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
@@ -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'),
|
||||
),
|
||||
]
|
||||
+32
-93
@@ -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))
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
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,
|
||||
'date': date2str(self.date),
|
||||
'source': self.source,
|
||||
'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 MemberRequest(models.Model):
|
||||
member = models.ForeignKey(Member)
|
||||
|
||||
def get_dict(self):
|
||||
return {
|
||||
'id': self.id,
|
||||
'member': self.member.get_dict(),
|
||||
'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
|
||||
|
||||
+28
-6
@@ -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
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
{% extends "members_base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div id="sidebar-wrapper">
|
||||
<ul class="sidebar-nav">
|
||||
<li><a href="#/list">Listaa jäsenet</a></li>
|
||||
<li><a href="#/add">Lisää jäsen</a></li>
|
||||
<li><a href="#/addmany">Lisää jäseniä</a></li>
|
||||
<li><a href="#/applications">Jäsenhakemukset</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- /#sidebar-wrapper -->
|
||||
|
||||
<!-- Page Content -->
|
||||
<div class="col-xs-12 col-sm-12 col-lg-12">
|
||||
<div id="header" class="row">
|
||||
<div class="col-xs-11 col-sm-11 col-lg-11">
|
||||
<h1 style="text-align:center; margin-top:10px; margin-bottom: 10px;">Aalto-yliopiston Sähköinsinöörikilta RY:n jäsenrekisteri</h1>
|
||||
</div>
|
||||
<div class="col-xs-1 col-sm-1 col-lg-1">
|
||||
<form action="/logout" method="post"> {% csrf_token %}
|
||||
<input type="Submit" value="Logout" name="Logout" class="btn btn-danger" style="margin-top:12px;"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-view></div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
+3
-4
@@ -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, )
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user