from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin from django.contrib.auth.validators import UnicodeUsernameValidator from django.contrib.contenttypes.models import ContentType from django.core.mail import send_mail from django.db import models from django.utils.translation import gettext_lazy as _ from rules.contrib.models import RulesModelMixin, RulesModelBase from outbo.apps.authentication import rules from outbo.apps.authentication.managers import UserManager from outbo.apps.core.models import TimestampableDeletableMixin class User( RulesModelMixin, TimestampableDeletableMixin, AbstractBaseUser, PermissionsMixin, metaclass=RulesModelBase, ): objects = UserManager() all_objects = UserManager(alive_only=False) class Meta: verbose_name = _("user") verbose_name_plural = _("users") rules_permissions = { "read": rules.can_read_user, "read_current": rules.can_read_current_user, } username_validator = UnicodeUsernameValidator() username = models.CharField( verbose_name=_("username"), max_length=150, unique=True, help_text=_( "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." ), validators=[username_validator], error_messages={"unique": _("A user with that username already exists.")}, ) email = models.EmailField( verbose_name=_("email address"), blank=True, null=True, unique=True ) is_staff = models.BooleanField( verbose_name=_("staff status"), default=False, help_text=_("Designates whether the user can log into this admin site."), ) is_observer = models.BooleanField( verbose_name=_("observer status"), default=False, help_text=_("Designates whether the user is an observer."), ) is_trader = models.BooleanField( verbose_name=_("trader status"), default=False, help_text=_("Designates whether the user is an trader."), ) first_name = models.CharField( verbose_name=_("first name"), max_length=30, blank=True ) last_name = models.CharField( verbose_name=_("last name"), max_length=150, blank=True ) organization = models.ForeignKey( verbose_name=_("organization"), to="organizations.Organization", on_delete=models.CASCADE, null=True, default=None, ) category = models.ForeignKey( verbose_name=_("category for trader"), to="organizations.Category", on_delete=models.CASCADE, blank=True, null=True, ) photo = models.ImageField( verbose_name=_("profile photo"), upload_to="users/", blank=True, null=True ) job_title = models.CharField(verbose_name=_("job title"), max_length=30, blank=True) phone_number = models.CharField( verbose_name=_("phone_number"), max_length=30, blank=True ) USERNAME_FIELD = "username" EMAIL_FIELD = "email" REQUIRED_FIELDS = [] @property def photo_url(self): return None if not self.photo else self.photo.url @property def is_active(self): return self.deleted_at is None @property def full_name(self): return f"{self.first_name} {self.last_name}".strip() @property def is_agency(self): return ( False if not self.organization else self.organization.type == ContentType.objects.get( app_label="organizations", model="agencyorganization" ) ) @property def is_client(self): return ( False if not self.organization else self.organization.type == ContentType.objects.get( app_label="organizations", model="clientorganization" ) ) @property def is_supplier(self): return ( False if not self.organization else self.organization.type == ContentType.objects.get( app_label="organizations", model="supplierorganization" ) ) @property def user_role(self): from outbo.apps.projects.models.member import MembershipType if self.is_client: return MembershipType.CLIENT elif self.is_agency: return MembershipType.AGENCY elif self.is_supplier: return MembershipType.SUPPLIER def email_user(self, subject, message, from_email=None, **kwargs): """Send an email to this user.""" send_mail(subject, message, from_email, [self.email], **kwargs)