Allow to subscribe before subscription end

This commit is contained in:
Pierre Brunet 2017-09-04 11:25:28 +02:00
parent 53696b7750
commit 2f912a197c
5 changed files with 36 additions and 7 deletions

View File

@ -230,7 +230,7 @@ class User(AbstractBaseUser):
@cached_property @cached_property
def is_subscribed(self): def is_subscribed(self):
s = self.subscriptions.last() s = self.subscriptions.filter(subscription_start__lte=timezone.now()).last()
return s.is_valid_now() if s is not None else False return s.is_valid_now() if s is not None else False
_club_memberships = {} _club_memberships = {}

View File

@ -421,6 +421,9 @@ SITH_CAN_CREATE_SUBSCRIPTIONS = [
1, 1,
] ]
# Number of weeks before the end of a subscription when the subscriber can resubscribe
SITH_SUBSCRIPTION_END = 10
# Subscription durations are in semestres # Subscription durations are in semestres
# Be careful, modifying this parameter will need a migration to be applied # Be careful, modifying this parameter will need a migration to be applied
SITH_SUBSCRIPTIONS = { SITH_SUBSCRIPTIONS = {

View File

@ -64,7 +64,7 @@ class Subscription(models.Model):
def clean(self): def clean(self):
try: try:
for s in Subscription.objects.filter(member=self.member).exclude(pk=self.pk).all(): for s in Subscription.objects.filter(member=self.member).exclude(pk=self.pk).all():
if s.is_valid_now(): if s.is_valid_now() and s.subscription_end - timedelta(weeks=settings.SITH_SUBSCRIPTION_END) > date.today():
raise ValidationError(_("You can not subscribe many time for the same period")) raise ValidationError(_("You can not subscribe many time for the same period"))
except: # This should not happen, because the form should have handled the data before, but sadly, it still except: # This should not happen, because the form should have handled the data before, but sadly, it still
# calls the model validation :'( # calls the model validation :'(
@ -138,7 +138,7 @@ class Subscription(models.Model):
return 'No user - ' + str(self.pk) return 'No user - ' + str(self.pk)
@staticmethod @staticmethod
def compute_start(d=None, duration=1): def compute_start(d=None, duration=1, user=None):
""" """
This function computes the start date of the subscription with respect to the given date (default is 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.SITH_START_DATE. and the start date given in settings.SITH_START_DATE.
@ -150,12 +150,14 @@ class Subscription(models.Model):
""" """
if not d: if not d:
d = date.today() d = date.today()
if user is not None and user.subscriptions.exists():
d = user.subscriptions.last().subscription_end
if duration <= 2: # Sliding subscriptions for 1 or 2 semesters if duration <= 2: # Sliding subscriptions for 1 or 2 semesters
return d return d
return get_start_of_semester(d) return get_start_of_semester(d)
@staticmethod @staticmethod
def compute_end(duration, start=None): def compute_end(duration, start=None, user=None):
""" """
This function compute the end date of the subscription given a start date and a duration in number of semestre This function compute the end date of the subscription given a start date and a duration in number of semestre
Exemple: Exemple:
@ -166,7 +168,8 @@ class Subscription(models.Model):
2015-09-18 - 4 -> 2017-09-18 2015-09-18 - 4 -> 2017-09-18
""" """
if start is None: if start is None:
start = Subscription.compute_start(duration=duration) start = Subscription.compute_start(duration=duration, user=user)
# This can certainly be simplified, but it works like this # This can certainly be simplified, but it works like this
try: try:
return start.replace(month=int(round((start.month - 1 + 6 * duration) % 12 + 1, 0)), return start.replace(month=int(round((start.month - 1 + 6 * duration) % 12 + 1, 0)),

View File

@ -137,3 +137,24 @@ class DecimalDurationTest(TestCase):
start=s.subscription_start) start=s.subscription_start)
s.save() s.save()
self.assertTrue(s.subscription_end == date(2017, 12, 29)) self.assertTrue(s.subscription_end == date(2017, 12, 29))
class SpecialCasesOfSubscription(TestCase):
def setUp(self):
call_command("populate")
self.user = User.objects.filter(username="public").first()
@mock.patch('subscription.models.date', FakeDate)
def test_subscription_before_end_of_actual_one(self):
user = User.objects.filter(pk=self.user.pk).first()
s = Subscription(member=user, subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[3],
payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0])
s.subscription_start = date(2015, 8, 29)
s.subscription_end = s.compute_end(duration=2,
start=s.subscription_start)
s.save()
self.assertTrue(s.subscription_end == date(2016, 8, 29))
date_mock_today(2016, 8, 25)
d = Subscription.compute_end(duration=2,
user=user)
self.assertTrue(d == date(2017, 8, 29))

View File

@ -117,10 +117,12 @@ class NewSubscription(CreateView):
def form_valid(self, form): def form_valid(self, form):
form.instance.subscription_start = Subscription.compute_start( form.instance.subscription_start = Subscription.compute_start(
duration=settings.SITH_SUBSCRIPTIONS[form.instance.subscription_type]['duration']) duration=settings.SITH_SUBSCRIPTIONS[form.instance.subscription_type]['duration'],
user=form.instance.member)
form.instance.subscription_end = Subscription.compute_end( form.instance.subscription_end = Subscription.compute_end(
duration=settings.SITH_SUBSCRIPTIONS[form.instance.subscription_type]['duration'], duration=settings.SITH_SUBSCRIPTIONS[form.instance.subscription_type]['duration'],
start=form.instance.subscription_start start=form.instance.subscription_start,
user=form.instance.member
) )
return super(NewSubscription, self).form_valid(form) return super(NewSubscription, self).form_valid(form)