models.py 4.85 KB
Newer Older
1
2
3
4
5
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
6
7
from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse
8
9
10
11

from core.models import User

def validate_type(value):
Skia's avatar
Skia committed
12
    if value not in settings.SITH_SUBSCRIPTIONS.keys():
13
14
15
        raise ValidationError(_('Bad subscription type'))

def validate_payment(value):
16
    if value not in settings.SITH_SUBSCRIPTION_PAYMENT_METHOD:
17
18
        raise ValidationError(_('Bad payment method'))

19
20
21
class Subscriber(User):
    class Meta:
        proxy = True
22
23

    def is_subscribed(self):
Skia's avatar
Skia committed
24
25
        s = self.subscriptions.last()
        return s.is_valid_now() if s is not None else False
26
27

class Subscription(models.Model):
28
    member = models.ForeignKey(Subscriber, related_name='subscriptions')
29
30
    subscription_type = models.CharField(_('subscription type'),
                                         max_length=255,
Skia's avatar
Skia committed
31
                                         choices=((k, v['name']) for k,v in sorted(settings.SITH_SUBSCRIPTIONS.items())))
32
33
    subscription_start = models.DateField(_('subscription start'))
    subscription_end = models.DateField(_('subscription end'))
34
    payment_method = models.CharField(_('payment method'), max_length=255, choices=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD)
Skia's avatar
Skia committed
35
    # TODO add location!
36

37
38
39
40
41
42
43
44
45
46
47
    class Meta:
        permissions = (
                ('change_subscription', 'Can make someone become a subscriber'),
                ('view_subscription', 'Can view who is a subscriber'),
                )

    def clean(self):
        for s in Subscription.objects.filter(member=self.member).exclude(pk=self.pk).all():
            if s.is_valid_now():
                raise ValidationError(_('You can not subscribe many time for the same period'))

48
49
50
    class Meta:
        ordering = ['subscription_start',]

51
52
53
    def get_absolute_url(self):
        return reverse('core:user_profile', kwargs={'user_id': self.member.pk})

54
    def __str__(self):
55
        return self.member.username+' - '+str(self.pk)
56

57
58
59
60
    @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),
Skia's avatar
Skia committed
61
        and the start date given in settings.SITH_START_DATE.
62
        It takes the nearest past start date.
Skia's avatar
Skia committed
63
        Exemples: with SITH_START_DATE = (8, 15)
64
65
66
67
68
69
            Today      -> Start date
            2015-03-17 -> 2015-02-15
            2015-01-11 -> 2014-08-15
        """
        today = d
        year = today.year
Skia's avatar
Skia committed
70
        start = date(year, settings.SITH_START_DATE[0], settings.SITH_START_DATE[1])
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
        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))

Skia's avatar
Skia committed
98
    def can_be_edited_by(self, user):
Skia's avatar
Skia committed
99
        return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) or user.is_in_group(settings.SITH_GROUPS['root']['name'])
Skia's avatar
Skia committed
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    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()