175 lines
5.9 KiB
Python
175 lines
5.9 KiB
Python
import uuid
|
|
from datetime import datetime, timedelta
|
|
|
|
from django.contrib.auth.models import (
|
|
AbstractBaseUser,
|
|
BaseUserManager,
|
|
PermissionsMixin,
|
|
)
|
|
from django.core.validators import RegexValidator
|
|
from django.db import models
|
|
from django.utils import timezone
|
|
from django.utils.translation import gettext as _
|
|
from foldbank.utils import get_bank_logo_file_path
|
|
|
|
|
|
# object managers
|
|
class CustomAccountManager(BaseUserManager):
|
|
def create_user(self, username, password):
|
|
if not username:
|
|
raise ValueError("Users must have a username.")
|
|
user = self.model(username=username)
|
|
user.set_password(password)
|
|
user.save(using=self._db)
|
|
return user
|
|
|
|
def create_superuser(self, username, password):
|
|
user = self.create_user(username, password)
|
|
user.is_staff = True
|
|
user.is_superuser = True
|
|
user.save(using=self._db)
|
|
return user
|
|
|
|
|
|
|
|
# Create your models here.
|
|
class User(AbstractBaseUser, PermissionsMixin):
|
|
# TODO: make username case insensitive yet retain case sensitivity
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
username = models.CharField(
|
|
max_length=32,
|
|
unique=True,
|
|
null=True,
|
|
blank=True,
|
|
validators=[
|
|
RegexValidator(
|
|
r"^[a-zA-Z0-9_]*$",
|
|
message="only allows letters, numbers and underscores",
|
|
)
|
|
],
|
|
help_text=_("only allows letters, numbers and underscores"),
|
|
)
|
|
name = models.CharField(null=True, blank=True, max_length=128)
|
|
|
|
is_active = models.BooleanField(default=True)
|
|
is_staff = models.BooleanField(default=False)
|
|
is_superuser = models.BooleanField(default=False)
|
|
|
|
date_joined = models.DateTimeField(auto_now_add=True)
|
|
last_login = models.DateTimeField(default=timezone.now)
|
|
last_updated = models.DateTimeField(auto_now=True)
|
|
|
|
objects = CustomAccountManager()
|
|
|
|
USERNAME_FIELD = "username"
|
|
|
|
def __str__(self):
|
|
if not self.username:
|
|
return "USERNAME-NOT-SET"
|
|
return self.username
|
|
|
|
|
|
class Tag(models.Model):
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
title = models.CharField(blank=True, null=True, max_length=64)
|
|
sub_category = models.CharField(blank=True, null=True, max_length=64)
|
|
icon_type = models.CharField(blank=True, null=True, max_length=64)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
|
|
def __str__(self):
|
|
return f"{self.title} - {self.sub_category}"
|
|
|
|
|
|
|
|
class Bank(models.Model):
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
name = models.CharField(blank=True, null=True, max_length=64)
|
|
logo = models.FileField(
|
|
upload_to=get_bank_logo_file_path,
|
|
null=True,
|
|
blank=True,
|
|
default=None,
|
|
)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
|
|
class Account(models.Model):
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
user = models.ForeignKey("User", on_delete=models.PROTECT)
|
|
bank = models.ForeignKey("Bank", on_delete=models.PROTECT)
|
|
account_number = models.CharField(blank=True, null=True, max_length=64)
|
|
SAVINGS_ACCOUNT = "SA"
|
|
CURRENT_ACCOUNT = "CA"
|
|
ACCOUNT_TYPES = [
|
|
(SAVINGS_ACCOUNT, "Savings Account"),
|
|
(CURRENT_ACCOUNT, "Current Account"),
|
|
]
|
|
account_type = models.CharField(
|
|
max_length=2,
|
|
choices=ACCOUNT_TYPES,
|
|
default=SAVINGS_ACCOUNT,
|
|
)
|
|
ifsc_code = models.CharField(blank=True, null=True, max_length=64)
|
|
swift_bic = models.CharField(blank=True, null=True, max_length=64)
|
|
holders_name = models.CharField(blank=True, null=True, max_length=64)
|
|
USER_ACCOUNT = "UA"
|
|
ORG_ACCOUNT = "OA"
|
|
ACCOUNT_OWNER_TYPES = [
|
|
(USER_ACCOUNT, "User Account"),
|
|
(ORG_ACCOUNT, "Organization Account"),
|
|
]
|
|
account_owner_type = models.CharField(
|
|
max_length=2,
|
|
choices=ACCOUNT_OWNER_TYPES,
|
|
default=USER_ACCOUNT,
|
|
)
|
|
balance = models.FloatField(null=True, blank=True)
|
|
|
|
def __str__(self):
|
|
return f"{self.account_owner_type} - {self.bank} - {self.account_number} - {self.holders_name}"
|
|
|
|
|
|
class Transaction(models.Model):
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
amount = models.FloatField(null=True, blank=True)
|
|
tag = models.ForeignKey("Tag", on_delete=models.PROTECT)
|
|
from_account = models.ForeignKey(
|
|
"Account", on_delete=models.PROTECT, related_name="transactions_from"
|
|
)
|
|
to_account = models.ForeignKey(
|
|
"Account", on_delete=models.PROTECT, related_name="transactions_to"
|
|
)
|
|
|
|
def __str__(self):
|
|
return f"{self.from_account.holders_name} - {self.to_account.holders_name}"
|
|
|
|
|
|
|
|
class RecurringPayment(models.Model):
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
from_account = models.ForeignKey(
|
|
"Account", on_delete=models.PROTECT, related_name="recurring_payment_from"
|
|
)
|
|
to_account = models.ForeignKey(
|
|
"Account", on_delete=models.PROTECT, related_name="recurring_payment_to"
|
|
)
|
|
frequency = models.DurationField(default=timedelta(days=30))
|
|
amount = models.FloatField(null=True, blank=True)
|
|
due_on = models.DateTimeField(auto_now_add=True)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
tag = models.ForeignKey("Tag", on_delete=models.PROTECT)
|
|
|
|
def __str__(self):
|
|
return f"{self.from_account.holders_name} - {self.to_account.holders_name}"
|
|
|
|
|
|
|
|
class RecurringPaymentTransactionLink(models.Model):
|
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
recurring_payment = models.ForeignKey("RecurringPayment", on_delete=models.PROTECT)
|
|
transaction = models.ForeignKey("Transaction", on_delete=models.PROTECT)
|