models.py 5.72 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

Skia's avatar
Skia committed
23
24
25
    def __init__(self, *args, **kwargs):
        super(Subscriber, self).__init__(*args, **kwargs)

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

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

40
41
42
43
44
45
46
47
48
49
50
    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'))

51
52
53
54
55
56
57
58
59
60
61
    def save(self, *args, **kwargs):
        """
        This makes the Subscription to be updated with right dates with respect to date.today() each time you save the
        Subscription object.
        It means that you must be careful when modifying old Subscription, because you could make
        someone that had no more valid subscription to get one again!

        TODO: FIXME by putting it in the right function that would be triggered only when using the right Form!!!!
        """
        self.subscription_start = self.compute_start()
        self.subscription_end = self.compute_end(
Skia's avatar
Skia committed
62
                duration=settings.SITH_SUBSCRIPTIONS[self.subscription_type]['duration'],
63
64
65
                start=self.subscription_start)
        super(Subscription, self).save(*args, **kwargs)

66
67
68
    class Meta:
        ordering = ['subscription_start',]

69
70
71
    def get_absolute_url(self):
        return reverse('core:user_profile', kwargs={'user_id': self.member.pk})

72
    def __str__(self):
73
        return self.member.username+' - '+str(self.pk)
74

75
76
77
78
    @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
79
        and the start date given in settings.SITH_START_DATE.
80
        It takes the nearest past start date.
Skia's avatar
Skia committed
81
        Exemples: with SITH_START_DATE = (8, 15)
82
83
84
85
86
87
            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
88
        start = date(year, settings.SITH_START_DATE[0], settings.SITH_START_DATE[1])
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
        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
116
    def can_be_edited_by(self, user):
Skia's avatar
Skia committed
117
        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
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
    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()