+ def notify_all(self, subject, template_name, extra_context=None):
+ Funding.notify_funders(
+ subject, template_name, extra_context,
+ query_filter=models.Q(offer=self)
+ )
+
+ def notify_end(self, force=False):
+ if not force and self.notified_end: return
+ assert not self.is_current()
+ self.notify_all(
+ _('The fundraiser has ended!'),
+ 'funding/email/end.txt', {
+ 'offer': self,
+ 'is_win': self.is_win(),
+ 'remaining': self.remaining(),
+ 'current': self.current(),
+ })
+ self.notified_end = datetime.utcnow().replace(tzinfo=utc)
+ self.save()
+
+ def notify_near(self, force=False):
+ if not force and self.notified_near: return
+ assert self.is_current()
+ sum_ = self.sum()
+ need = self.target - sum_
+ self.notify_all(
+ _('The fundraiser will end soon!'),
+ 'funding/email/near.txt', {
+ 'days': (self.end - date.today()).days + 1,
+ 'offer': self,
+ 'is_win': self.is_win(),
+ 'sum': sum_,
+ 'need': need,
+ })
+ self.notified_near = datetime.utcnow().replace(tzinfo=utc)
+ self.save()
+
+ def notify_published(self):
+ assert self.book is not None
+ self.notify_all(
+ _('The book you helped fund has been published.'),
+ 'funding/email/published.txt', {
+ 'offer': self,
+ 'book': self.book,
+ 'author': self.book.pretty_title(),
+ 'current': self.current(),
+ })