import uuid from datetime import timedelta from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver from django.utils import timezone class UserManager(BaseUserManager): def create_user(self, email): user = self.model(email=email) user.set_unusable_password() user.save(using=self._db) return user def create_superuser(self, email, password): user = self.model(email=email, is_staff=True, is_superuser=True) user.set_password(password) user.save(using=self._db) return user class LoginToken(models.Model): email = models.EmailField() uid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) class User(AbstractBaseUser): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) email = models.EmailField(unique=True) username = models.CharField(max_length=35, unique=True, null=True, blank=True) searchable = models.BooleanField(default=False) palette = models.CharField(max_length=32, default="palette-default") stripe_customer_id = models.CharField(max_length=255, null=True, blank=True) is_staff = models.BooleanField(default=False) is_superuser = models.BooleanField(default=False) objects = UserManager() REQUIRED_FIELDS = [] USERNAME_FIELD = "email" def has_perm(self, perm, obj=None): return self.is_superuser def has_module_perms(self, app_label): return self.is_superuser class Wallet(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="wallet") writs = models.IntegerField(default=0) esteem = models.IntegerField(default=0) class Token(models.Model): COIN = "coin" FREE = "Free" TITHE = "tithe" TOKEN_TYPE_CHOICES = [ (COIN, "Coin-on-a-String"), (FREE, "Free Token"), (TITHE, "Tithe Token"), ] user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="tokens") token_type = models.CharField(max_length=8, choices=TOKEN_TYPE_CHOICES) expires_at = models.DateTimeField(null=True, blank=True) def tooltip_text(self): if self.token_type == self.COIN: return ( "Coin-on-a-String: Admit 1 Entry" " (and another after that, and another after that\u2026)" " \u2014 no expiry" ) if self.token_type == self.FREE: return ( f"Free Token: Admit 1 Entry" f" \u2014 Expires {self.expires_at.strftime('%Y-%m-%d')}" ) return self.get_token_type_display() class PaymentMethod(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="payment_methods") stripe_pm_id = models.CharField(max_length=255) last4 = models.CharField(max_length=4) brand = models.CharField(max_length=32) def __str__(self): return f"{self.brand} ....{self.last4}" @receiver(post_save, sender=User) def create_wallet_and_tokens(sender, instance, created, **kwargs): if not created: return Wallet.objects.create(user=instance, writs=144) Token.objects.create(user=instance, token_type=Token.COIN) Token.objects.create( user=instance, token_type=Token.FREE, expires_at=timezone.now() + timedelta(days=7), )