+
+
+class Contact(models.Model):
+ COLD = 10
+ TRIED = 20
+ SINGLE = 30
+ RECURRING = 40
+ OPT_OUT = 50
+
+ email = models.EmailField(unique=True)
+ level = models.PositiveSmallIntegerField(
+ choices=[
+ (TRIED, _('Would-be donor')),
+ (SINGLE, _('One-time donor')),
+ (RECURRING, _('Recurring donor')),
+ (COLD, _('Cold')),
+ (OPT_OUT, _('Opt out')),
+ ])
+ since = models.DateTimeField()
+ expires_at = models.DateTimeField(null=True, blank=True)
+
+ @classmethod
+ def update(cls, email, level, since, expires_at=None):
+ obj, created = cls.objects.get_or_create(email=email, defaults={
+ "level": level,
+ "since": since,
+ "expires_at": expires_at
+ })
+ if not created:
+ obj.ascend(level, since, expires_at)
+
+ def ascend(self, level, since, expires_at=None):
+ if level < self.level:
+ return
+ if level == self.level:
+ self.since = min(since, self.since)
+
+ if expires_at and self.expires_at:
+ self.expires_at = max(expires_at, self.expires_at)
+ else:
+ self.expires_at = expires_at
+ else:
+ self.level = level
+ self.since = since
+ self.expires_at = expires_at
+ self.save()
+