Commit b35483d2 authored by Skia's avatar Skia

WIP: Begin ae app with subscription handling

parent a6aac76d
from django.contrib import admin
# Register your models here.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('core', '0002_auto_20151215_0827'),
]
operations = [
migrations.CreateModel(
name='Member',
fields=[
('user', models.OneToOneField(primary_key=True, to=settings.AUTH_USER_MODEL, serialize=False)),
],
),
migrations.CreateModel(
name='Subscription',
fields=[
('id', models.AutoField(auto_created=True, serialize=False, primary_key=True, verbose_name='ID')),
('subscription_type', models.CharField(choices=[('cursus branche', 'Cursus Branche'), ('cursus tronc commun', 'Cursus Tronc Commun'), ('deux semestres', 'Deux semestres'), ('un semestre', 'Un semestre')], verbose_name='subscription type', max_length=255)),
('subscription_start', models.DateField(verbose_name='subscription start')),
('subscription_end', models.DateField(verbose_name='subscription end')),
('payment_method', models.CharField(choices=[('cheque', 'Chèque'), ('cash', 'Espèce'), ('other', 'Autre')], verbose_name='payment method', max_length=255)),
('member', models.ForeignKey(related_name='subscriptions', to='ae.Member')),
],
options={
'ordering': ['subscription_start'],
},
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ae', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='subscription',
name='subscription_type',
field=models.CharField(verbose_name='subscription type', max_length=255, choices=[('cursus-branche', 'Cursus Branche'), ('cursus-tronc-commun', 'Cursus Tronc Commun'), ('deux-semestres', 'Deux semestres'), ('un-semestre', 'Un semestre')]),
),
]
from datetime import date, timedelta
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from core.models import User
def validate_type(value):
if value not in settings.AE_SUBSCRIPTIONS.keys():
raise ValidationError(_('Bad subscription type'))
def validate_payment(value):
if value not in settings.AE_PAYMENT_METHOD:
raise ValidationError(_('Bad payment method'))
class Member(models.Model):
user = models.OneToOneField(User, primary_key=True)
def is_subscribed(self):
return self.subscriptions.last().is_valid_now()
class Subscription(models.Model):
member = models.ForeignKey(Member, related_name='subscriptions')
subscription_type = models.CharField(_('subscription type'),
max_length=255,
choices=((k.lower().replace(' ', '-'), k) for k in sorted(settings.AE_SUBSCRIPTIONS.keys())))
subscription_start = models.DateField(_('subscription start'))
subscription_end = models.DateField(_('subscription end'))
payment_method = models.CharField(_('payment method'), max_length=255, choices=settings.AE_PAYMENT_METHOD)
class Meta:
ordering = ['subscription_start',]
@staticmethod
def compute_start(d=date.today()):
"""
This function computes the start date of the subscription with respect to the given date (default is today),
and the start date given in settings.AE_START_DATE.
It takes the nearest past start date.
Exemples: with AE_START_DATE = (8, 15)
Today -> Start date
2015-03-17 -> 2015-02-15
2015-01-11 -> 2014-08-15
"""
today = d
year = today.year
start = date(year, settings.AE_START_DATE[0], settings.AE_START_DATE[1])
start2 = start.replace(month=(start.month+6)%12)
if start > start2:
start, start2 = start2, start
if today < start:
return start2.replace(year=year-1)
elif today < start2:
return start
else:
return start2
@staticmethod
def compute_end(duration, start=None):
"""
This function compute the end date of the subscription given a start date and a duration in number of semestre
Exemple:
Start - Duration -> End date
2015-09-18 - 1 -> 2016-03-18
2015-09-18 - 2 -> 2016-09-18
2015-09-18 - 3 -> 2017-03-18
2015-09-18 - 4 -> 2017-09-18
"""
if start is None:
start = Subscription.compute_start()
# This can certainly be simplified, but it works like this
return start.replace(month=(start.month+6*duration)%12,
year=start.year+int(duration/2)+(1 if start.month > 6 and duration%2 == 1 else 0))
def is_valid_now(self):
return self.subscription_start <= date.today() and date.today() <= self.subscription_end
def guy_test(date):
print(str(date)+" -> "+str(Subscription.compute_start(date)))
def bibou_test(duration, date=None):
print(str(date)+" - "+str(duration)+" -> "+str(Subscription.compute_end(duration, date)))
def guy():
guy_test(date(2015, 7, 11))
guy_test(date(2015, 8, 11))
guy_test(date(2015, 2, 17))
guy_test(date(2015, 3, 17))
guy_test(date(2015, 1, 11))
guy_test(date(2015, 2, 11))
guy_test(date(2015, 8, 17))
guy_test(date(2015, 9, 17))
print('='*80)
bibou_test(1, date(2015, 2, 18))
bibou_test(2, date(2015, 2, 18))
bibou_test(3, date(2015, 2, 18))
bibou_test(4, date(2015, 2, 18))
bibou_test(1, date(2015, 9, 18))
bibou_test(2, date(2015, 9, 18))
bibou_test(3, date(2015, 9, 18))
bibou_test(4, date(2015, 9, 18))
bibou_test(1)
bibou_test(2)
bibou_test(3)
bibou_test(4)
if __name__ == "__main__":
guy()
{% extends "core/base.html" %}
{% block title %}
{% if profile %}
Edit {{ member.user.get_display_name }}'s subscription
{% endif %}
{% endblock %}
{% block content %}
<h3>Edit subscription</h3>
{# <p><a href="{% url 'core:user_profile' object.member.user.id %}">Go to profile</a></p> #}
{# <p>You're editing the subscription of <strong>{{ member.user.get_display_name }}</strong></p>#}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="Save!" /></p>
</form>
{% endblock %}
from django.test import TestCase
# Create your tests here.
from django.conf.urls import url, include
from ae.views import *
urlpatterns = [
# Subscription views
url(r'^subscription/(?P<user_id>[0-9]+)/$', NewSubscription.as_view(), name='subscription'),
]
from django.shortcuts import render
from django.views.generic.edit import UpdateView, CreateView
from django import forms
from django.forms import Select
from django.conf import settings
from ae.models import Member, Subscription
from core.views import CanEditMixin, CanEditPropMixin, CanViewMixin
class SubscriptionForm(forms.ModelForm):
class Meta:
model = Subscription
fields = ['subscription_type', 'payment_method']
#widgets = {
# 'subscription_type': Select(choices={(k.lower(), k+" - "+str(v['price'])+"€"+str(Subscription.compute_end(2))) for k,v in settings.AE_SUBSCRIPTIONS.items()}),
#}
class NewSubscription(CanEditMixin, CreateView):
template_name = 'ae/subscription.html'
form_class = SubscriptionForm
......@@ -38,6 +38,7 @@ INSTALLED_APPS = (
'django.contrib.messages',
'django.contrib.staticfiles',
'core',
'ae',
)
MIDDLEWARE_CLASSES = (
......@@ -117,6 +118,9 @@ EMAIL_HOST="localhost"
EMAIL_PORT=25
# AE configuration
# Define the date in the year serving as reference for the subscriptions calendar
# (month, day)
AE_START_DATE = (8, 15) # 15th August
AE_GROUPS = {
'root': {
'id': 1,
......@@ -136,3 +140,28 @@ AE_GROUPS = {
},
}
AE_PAYMENT_METHOD = [('cheque', 'Chèque'),
('cash', 'Espèce'),
('other', 'Autre'),
]
# Subscription durations are in semestres (should be settingized)
AE_SUBSCRIPTIONS = {
'Un semestre': {
'price': 15,
'duration': 1,
},
'Deux semestres': {
'price': 28,
'duration': 2,
},
'Cursus Tronc Commun': {
'price': 45,
'duration': 4,
},
'Cursus Branche': {
'price': 45,
'duration': 6,
},
# To be completed....
}
......@@ -21,5 +21,6 @@ handler404 = "core.views.not_found"
urlpatterns = [
url(r'^', include('core.urls', namespace="core", app_name="core")),
url(r'^ae/', include('ae.urls', namespace="ae", app_name="ae")),
url(r'^admin/', include(admin.site.urls)),
]
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment