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
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
_club_memberships = {}

View File

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

View File

@ -64,7 +64,7 @@ class Subscription(models.Model):
def clean(self):
try:
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"))
except: # This should not happen, because the form should have handled the data before, but sadly, it still
# calls the model validation :'(
@ -138,7 +138,7 @@ class Subscription(models.Model):
return 'No user - ' + str(self.pk)
@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),
and the start date given in settings.SITH_START_DATE.
@ -150,12 +150,14 @@ class Subscription(models.Model):
"""
if not d:
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
return d
return get_start_of_semester(d)
@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
Exemple:
@ -166,7 +168,8 @@ class Subscription(models.Model):
2015-09-18 - 4 -> 2017-09-18
"""
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
try:
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)
s.save()
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):
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(
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)