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

88 lines
3.0 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
from apps.workspaces.models import WorkspaceMembership
@transaction.atomic
def create_project(user, workspace, name, client=None, description="", color="", thumbnail=None):
"""
Creates a new workspace-shared 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,
thumbnail=thumbnail,
color=color,
created_by=user,
updated_by=user,
)
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."})
if "client" in kwargs:
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
clear_thumbnail = kwargs.pop("clear_thumbnail", False)
old_thumbnail_name = project.thumbnail.name if project.thumbnail else None
if clear_thumbnail and project.thumbnail:
project.thumbnail.delete(save=False)
project.thumbnail = None
update_fields.append("thumbnail")
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)
if old_thumbnail_name and project.thumbnail and project.thumbnail.name != old_thumbnail_name:
storage = project.thumbnail.storage
if storage.exists(old_thumbnail_name):
storage.delete(old_thumbnail_name)
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