106 lines
3.9 KiB
Python
106 lines
3.9 KiB
Python
import secrets
|
|
import string
|
|
from typing import Optional
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth import get_user_model
|
|
from django.db import models
|
|
from django.utils.translation import gettext_lazy as _
|
|
from phonenumber_field.modelfields import PhoneNumberField
|
|
from rules import is_superuser
|
|
from rules.contrib.models import RulesModel
|
|
|
|
from members.rules import is_member_manager
|
|
|
|
|
|
class MemberManager(models.Manager):
|
|
def get_queryset(self) -> models.QuerySet:
|
|
return super().get_queryset().select_related("user")
|
|
|
|
|
|
class Member(RulesModel):
|
|
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="member", verbose_name=_("user"))
|
|
family_members = models.ManyToManyField("self", symmetrical=True, blank=True, verbose_name=_("family members"))
|
|
|
|
birthday = models.DateField(_("birthday"), blank=True, null=True)
|
|
license = models.CharField(_("license"), max_length=20, blank=True, null=True)
|
|
|
|
phone_number = PhoneNumberField(_("phone number"), blank=True, null=True)
|
|
emergency_phone_number = PhoneNumberField(_("emergency phone number"), blank=True, null=True)
|
|
notes = models.TextField(_("notes"), blank=True, null=True)
|
|
|
|
access_token = models.CharField(_("access token"), max_length=255, blank=True, null=True)
|
|
|
|
created = models.DateTimeField(auto_now_add=True, verbose_name=_("created"))
|
|
updated = models.DateTimeField(auto_now=True, verbose_name=_("updated"))
|
|
|
|
objects = MemberManager()
|
|
|
|
class Meta:
|
|
verbose_name = _("member")
|
|
verbose_name_plural = _("members")
|
|
ordering = ["user__last_name", "user__first_name"]
|
|
permissions = [("member_manager", _("Can manage members"))]
|
|
rules_permissions = {
|
|
"add": is_superuser | is_member_manager,
|
|
"change": is_superuser | is_member_manager,
|
|
"delete": is_superuser | is_member_manager,
|
|
"view": is_superuser | is_member_manager,
|
|
}
|
|
|
|
def __str__(self):
|
|
return self.user.get_full_name()
|
|
|
|
@classmethod
|
|
def create(cls, first_name: str, last_name: str, email: str, password: Optional[str] = None, member: Optional["Member"] = None) -> "Member":
|
|
"""Creates a new member based on the provided details"""
|
|
|
|
if member is not None and member.pk is not None:
|
|
member.user.first_name = first_name
|
|
member.user.last_name = last_name
|
|
member.user.email = email
|
|
member.user.username = email
|
|
|
|
if password is not None and password != "":
|
|
member.user.set_password(password)
|
|
|
|
else:
|
|
# First check to see if a user already exists in the system
|
|
user, created = get_user_model().objects.get_or_create(
|
|
username=email,
|
|
defaults={
|
|
"first_name": first_name,
|
|
"last_name": last_name,
|
|
"email": email
|
|
}
|
|
)
|
|
|
|
if not created:
|
|
user.first_name = first_name
|
|
user.last_name = last_name
|
|
user.email = email
|
|
user.username = email
|
|
|
|
if hasattr(user, "member"):
|
|
member = user.member
|
|
if password is not None and password != "":
|
|
user.set_password(password)
|
|
else:
|
|
member = cls()
|
|
|
|
initial_password = "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(20))
|
|
|
|
if password is None or password == "":
|
|
password = initial_password
|
|
member.notes = f"Initial password: {initial_password}"
|
|
|
|
user.set_password(password)
|
|
member.user = user
|
|
|
|
if not member.user.is_active:
|
|
member.user.is_active = True
|
|
|
|
member.user.save()
|
|
member.save()
|
|
|
|
return member |