feat(projects): add projects app's basic structure and endpoints
This commit is contained in:
74
apps/projects/services/projects.py
Normal file
74
apps/projects/services/projects.py
Normal file
@@ -0,0 +1,74 @@
|
||||
from django.db import transaction
|
||||
from rest_framework.exceptions import ValidationError, PermissionDenied
|
||||
|
||||
from apps.projects.models import Project, ProjectMembership
|
||||
from apps.workspaces.models import WorkspaceMembership
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def create_project(user, workspace, name, client=None, description="", color=""):
|
||||
"""
|
||||
Creates a new project and automatically assigns the creator
|
||||
as an active MANAGER of that project.
|
||||
"""
|
||||
workspace_member = WorkspaceMembership.objects.filter(
|
||||
workspace=workspace,
|
||||
user=user,
|
||||
is_active=True,
|
||||
is_deleted=False
|
||||
).first()
|
||||
|
||||
if not workspace_member:
|
||||
raise PermissionDenied("You do not have access to this workspace.")
|
||||
|
||||
if Project.objects.filter(workspace=workspace, name=name, is_deleted=False).exists():
|
||||
raise ValidationError({"name": "A project with this name already exists in the workspace."})
|
||||
|
||||
project = Project.objects.create(
|
||||
workspace=workspace,
|
||||
name=name,
|
||||
client=client,
|
||||
description=description,
|
||||
color=color
|
||||
)
|
||||
|
||||
ProjectMembership.objects.create(
|
||||
project=project,
|
||||
user=user,
|
||||
role=ProjectMembership.Role.MANAGER,
|
||||
is_active=True
|
||||
)
|
||||
|
||||
return project
|
||||
|
||||
|
||||
def update_project(project, **kwargs):
|
||||
"""
|
||||
Updates specific fields of an existing project.
|
||||
"""
|
||||
update_fields = []
|
||||
|
||||
# Optional manual uniqueness check if name is being updated
|
||||
if "name" in kwargs and kwargs["name"] != project.name:
|
||||
if Project.objects.filter(workspace=project.workspace, name=kwargs["name"], is_deleted=False).exists():
|
||||
raise ValidationError({"name": "A project with this name already exists in the workspace."})
|
||||
|
||||
for field, value in kwargs.items():
|
||||
if hasattr(project, field) and getattr(project, field) != value:
|
||||
setattr(project, field, value)
|
||||
update_fields.append(field)
|
||||
|
||||
if update_fields:
|
||||
update_fields.append("updated_at")
|
||||
project.save(update_fields=update_fields)
|
||||
|
||||
return project
|
||||
|
||||
|
||||
def toggle_project_archive(project) -> Project:
|
||||
"""
|
||||
Archives or unarchives a project.
|
||||
"""
|
||||
project.is_archived = not project.is_archived
|
||||
project.save(update_fields=["is_archived", "updated_at"])
|
||||
return project
|
||||
Reference in New Issue
Block a user