from django.contrib.auth import get_user_model from django.db import models from core.models.base import BaseModel from apps.workspaces.models import Workspace User = get_user_model() class Project(BaseModel): workspace = models.ForeignKey( Workspace, on_delete=models.CASCADE, related_name="projects", ) name = models.CharField(max_length=255) client = models.ForeignKey( "clients.Client", on_delete=models.SET_NULL, null=True, blank=True, related_name="projects", ) description = models.TextField(blank=True) is_archived = models.BooleanField(default=False) color = models.CharField(max_length=7, blank=True) class Meta: db_table = "project" ordering = ("-updated_at", "-created_at") indexes = [ models.Index(fields=["workspace"], name="project_workspace_idx"), ] constraints = [ models.UniqueConstraint( fields=["workspace", "name"], name="unique_project_name_per_workspace", condition=models.Q(is_deleted=False), ) ] def __str__(self): return self.name class ProjectMembership(BaseModel): class Role(models.TextChoices): MANAGER = "manager", "Manager" MEMBER = "member", "Member" project = models.ForeignKey( Project, on_delete=models.CASCADE, related_name="memberships", ) user = models.ForeignKey( User, on_delete=models.CASCADE, related_name="project_memberships", ) role = models.CharField( max_length=20, choices=Role.choices, default=Role.MEMBER, ) is_active = models.BooleanField(default=True) class Meta: db_table = "project_membership" ordering = ("-created_at",) indexes = [ models.Index(fields=["project"], name="project_membership_project_idx"), models.Index(fields=["user"], name="project_membership_user_idx"), ] constraints = [ models.UniqueConstraint( fields=["project", "user"], name="unique_project_membership", condition=models.Q(is_deleted=False), ) ] def __str__(self): return f"{self.user} @ {self.project}" class ProjectRate(BaseModel): project = models.ForeignKey( Project, on_delete=models.CASCADE, related_name="rates", ) hourly_rate = models.DecimalField( max_digits=10, decimal_places=2, ) currency = models.CharField( max_length=3, default="USD", ) effective_from = models.DateTimeField() is_active = models.BooleanField(default=True) class Meta: db_table = "project_rate" ordering = ("-effective_from",) indexes = [ models.Index(fields=["project"], name="project_rate_project_idx"), ] class ProjectUserRate(BaseModel): project = models.ForeignKey( Project, on_delete=models.CASCADE, related_name="user_rates", ) user = models.ForeignKey( User, on_delete=models.CASCADE, related_name="project_rates", ) hourly_rate = models.DecimalField( max_digits=10, decimal_places=2, ) currency = models.CharField( max_length=3, default="USD", ) effective_from = models.DateTimeField() is_active = models.BooleanField(default=True) class Meta: db_table = "project_user_rate" ordering = ("-effective_from",) constraints = [ models.UniqueConstraint( fields=["project", "user", "effective_from"], name="unique_project_user_rate_time", condition=models.Q(is_deleted=False), ) ] indexes = [ models.Index(fields=["project"], name="pur_project_idx"), models.Index(fields=["user"], name="pur_user_idx"), ]