diff --git a/conservancy/fundgoal/models.py b/conservancy/fundgoal/models.py index 64729cd581a9af0e1281862e76981ed5cce7b57f..06c3ee93d21687ac1411f700602dab83d3221d2e 100644 --- a/conservancy/fundgoal/models.py +++ b/conservancy/fundgoal/models.py @@ -1,3 +1,5 @@ +import datetime +import math import random from django.db import models @@ -10,6 +12,9 @@ class FundraisingGoal(models.Model): fundraiser_goal_amount = models.DecimalField(max_digits=10, decimal_places=2) fundraiser_so_far_amount = models.DecimalField(max_digits=10, decimal_places=2) fundraiser_donation_count = models.IntegerField() + # The number of new Sustainers that can be double-matched this fundraiser. + # (No, this name makes no sense. We're repurposing an existing model field + # for this new reason.) fundraiser_donation_count_disclose_threshold = models.IntegerField() fundraiser_endtime = models.DateTimeField(null=True) @@ -34,6 +39,20 @@ class FundraisingGoal(models.Model): else: return random.sample(providers, k) + def days_remaining(self): + now = datetime.datetime.now() + return (self.fundraiser_endtime - now).days + + def hours_remaining(self): + now = datetime.datetime.now() + return int(math.ceil((self.fundraiser_endtime - now).seconds / 3600)) + + def match_remaining(self): + return self.fundraiser_goal_amount - self.fundraiser_so_far_amount + + def match_exceeded_by(self): + return self.fundraiser_so_far_amount - self.fundraiser_goal_amount + class GoalProvider(models.Model): fundraising_goal = models.ForeignKey( diff --git a/conservancy/fundgoal/templates/fundgoal/fundraiser_goal_banner_partial.html b/conservancy/fundgoal/templates/fundgoal/fundraiser_goal_banner_partial.html index 4814abf6f9bcce205ca81d7376eac85be8152ea1..97a75adb293bbcaa44489a111e2f126c47a0b570 100644 --- a/conservancy/fundgoal/templates/fundgoal/fundraiser_goal_banner_partial.html +++ b/conservancy/fundgoal/templates/fundgoal/fundraiser_goal_banner_partial.html @@ -1,81 +1,50 @@ {% load humanize %} {% load subtract %} -{% comment %} -# FUNDRAISER VARIABLES AND CONSTANTS GUIDE - -## From Local Context - -* datetime_now: Current DateTime in UTC -* sitefundgoal: The current FundraisingGoal. Attributes: - * fundraiser_goal_amount: The amount being matched - * fundraiser_so_far_amount: The amount contributed so far - * fundraiser_donation_count: The number of people who have contributed so far - * fundraiser_donation_count_disclose_threshold: The number of new Sustainers that can be double-matched this fundraiser. - (No, this name makes no sense. We're repurposing an existing model field for this new reason.) -* sitefundgoal_endtime: DateTime when sitefundgoal ends. - -## Local convenience variables - -* sitefundgoal_timeleft: TimeDelta for how much time remains in the current fundraiser -* this_match_goal: The amount being matched -* this_match_so_far: The amount contributed so far -* this_match_remaining: this_match_goal - this_match_so_far -* this_match_exceeded: this_match_so_far - this_match_goal - -{% endcomment %} -{% with this_match_goal=sitefundgoal.fundraiser_goal_amount this_match_so_far=sitefundgoal.fundraiser_so_far_amount %} -{% with this_match_remaining=this_match_goal|subtract:this_match_so_far sitefundgoal_timeleft=sitefundgoal.fundraiser_endtime|subtract:datetime_now this_match_exceeded=this_match_so_far|subtract:this_match_goal %} - {% if sitefundgoal_timeleft.total_seconds >= -604800 %} -
-
+{% if sitefundgoal.days_remaining >= -7 %}{# i.e. 7 days over completion #} +
+
- {% if datetime_now < sitefundgoal.fundraiser_endtime %} - {% if this_match_remaining <= 0 %} - Thanks to so many donors, we earned our full match! - Help us go further to stand up for software freedom — sign up now! - {% else %} - {% if sitefundgoal_timeleft.days == 0 %} - For the next {% widthratio sitefundgoal_timeleft.total_seconds 3600 1 %} hours only, the - {% elif sitefundgoal_timeleft.days == 1 %} - Through tomorrow only, the - {% elif sitefundgoal_timeleft.days < 14 %} - For only {{ sitefundgoal_timeleft.days }} more days, the + {% if sitefundgoal.days_remaining >= 0 %} + {% if fundgoal.match_remaining <= 0 %} + Thanks to so many donors, we earned our full match! + Help us go further to stand up for software freedom — sign up now! {% else %} - Until January 15, the + {% if sitefundgoal.days_remaining == 0 %} + For the next {{ sitefundgoal.hours_remaining }} hour{{ sitefundgoal.hours_remaining|pluralize }} only, the + {% elif sitefundgoal.days_remaining == 1 %} + Through tomorrow only, the + {% elif sitefundgoal.days_remaining < 14 %} + For only {{ sitefundgoal.days_remaining }} more days, the + {% else %} + Until January 15, the + {% endif %} + next ${{ sitefundgoal.match_remaining|floatformat:0|intcomma }} of support we receive will be matched! {% endif %} - next ${{ this_match_remaining|floatformat:0|intcomma }} of support we receive will be matched! - + {% else %} + Thank you so much to all our donors who participated in our donation match challenge! Here are the results: {% endif %} - {% else %} - Thank you so much to all our donors who participated in our donation match challenge! Here are the results: - {% endif %}
-{% if 1 %} - - - -{% endif %} - -
-
+
{% endif %} -{% endwith %} -{% endwith %} diff --git a/conservancy/local_context_processors.py b/conservancy/local_context_processors.py index 0f14fbe6ccdd87d7fdf617676c953299aa719957..003a1eeb23736a584663acf2c83464925e3764f6 100644 --- a/conservancy/local_context_processors.py +++ b/conservancy/local_context_processors.py @@ -1,5 +1,3 @@ -from datetime import datetime as DateTime - from .fundgoal.models import FundraisingGoal SITE_FUNDGOAL = 'cy2023-end-year-match' @@ -13,7 +11,6 @@ def fundgoal_lookup(fundraiser_sought): def sitefundraiser(request): return { - 'datetime_now': DateTime.now(), 'sitefundgoal': fundgoal_lookup(SITE_FUNDGOAL), }