import datetime import math import random from django.db import models class FundraisingGoal(models.Model): """Conservancy fundraiser Goal""" fundraiser_code_name = models.CharField(max_length=200, blank=False, unique=True) 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) def __str__(self): return self.fundraiser_code_name def percentage_there(self): return self.fundraiser_so_far_amount / self.fundraiser_goal_amount * 100 class Meta: ordering = ('fundraiser_code_name',) def providers(self): return GoalProvider.objects.filter(fundraising_goal=self) def random_providers(self, k=None): providers = self.providers() if not providers.exists(): return None elif k is None: return random.choice(providers) 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( 'FundraisingGoal', on_delete=models.CASCADE, ) provider_name = models.CharField(max_length=512) def __str__(self): return self.provider_name