Files
qlockify-backend-deployment/apps/projects/services/projects.py

83 lines
2.6 KiB
Python

from django.db import transaction
from django.shortcuts import get_object_or_404
from rest_framework.exceptions import ValidationError, PermissionDenied
from apps.clients.models import Client
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,
created_by=user,
updated_by=user,
)
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."})
client_id = kwargs.pop("client")
client = get_object_or_404(Client, id=client_id, is_deleted=False) if client_id else None
kwargs["client"] = client
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