feat(projects): support members and align rate payloads
This commit is contained in:
@@ -95,9 +95,13 @@ class ProjectViewSet(ModelViewSet):
|
||||
"""
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
|
||||
members_data = serializer.validated_data.pop("members", [])
|
||||
|
||||
workspace = get_object_or_404(Workspace, id=serializer.validated_data["workspace"], is_deleted=False)
|
||||
client = get_object_or_404(Client, id=serializer.validated_data.get("client"), is_deleted=False)
|
||||
client_id = serializer.validated_data.get("client")
|
||||
client = get_object_or_404(Client, id=client_id, is_deleted=False) if client_id else None
|
||||
|
||||
project = create_project(
|
||||
user=request.user,
|
||||
workspace=workspace,
|
||||
@@ -106,6 +110,13 @@ class ProjectViewSet(ModelViewSet):
|
||||
description=serializer.validated_data.get("description", ""),
|
||||
color=serializer.validated_data.get("color", "")
|
||||
)
|
||||
|
||||
for member in members_data:
|
||||
add_project_member(
|
||||
project=project,
|
||||
user_id=member["user_id"],
|
||||
role=member["role"]
|
||||
)
|
||||
|
||||
output_serializer = ProjectSerializer(project)
|
||||
return Response(output_serializer.data, status=status.HTTP_201_CREATED)
|
||||
@@ -119,11 +130,41 @@ class ProjectViewSet(ModelViewSet):
|
||||
|
||||
serializer = self.get_serializer(data=request.data, partial=partial)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
|
||||
members_data = serializer.validated_data.pop("members", None)
|
||||
|
||||
updated_project = update_project(
|
||||
project=project,
|
||||
**serializer.validated_data
|
||||
)
|
||||
|
||||
# Full sync of project members if array is provided
|
||||
if members_data is not None:
|
||||
current_memberships = {str(m.user_id): m for m in updated_project.memberships.filter(is_deleted=False)}
|
||||
incoming_users = {str(m['user_id']) for m in members_data}
|
||||
|
||||
# Add or Update roles
|
||||
for member in members_data:
|
||||
user_id_str = str(member['user_id'])
|
||||
if user_id_str in current_memberships:
|
||||
# Reactivate or update role
|
||||
update_project_member(
|
||||
current_memberships[user_id_str],
|
||||
role=member['role'],
|
||||
is_active=True
|
||||
)
|
||||
else:
|
||||
# Add new member
|
||||
add_project_member(
|
||||
project=updated_project,
|
||||
user_id=member['user_id'],
|
||||
role=member['role']
|
||||
)
|
||||
|
||||
# Deactivate omitted members
|
||||
for user_id_str, membership in current_memberships.items():
|
||||
if user_id_str not in incoming_users:
|
||||
update_project_member(membership, is_active=False)
|
||||
|
||||
output_serializer = ProjectSerializer(updated_project)
|
||||
return Response(output_serializer.data, status=status.HTTP_200_OK)
|
||||
@@ -247,12 +288,12 @@ class ProjectRateViewSet(BaseProjectNestedViewSet):
|
||||
project_id = serializer.validated_data["project_id"]
|
||||
self.verify_manager_access(project_id)
|
||||
|
||||
project = get_object_or_404(Project, id=project_id, is_deleted=False)
|
||||
rate = create_project_rate(
|
||||
project=project,
|
||||
amount=serializer.validated_data["amount"],
|
||||
currency=serializer.validated_data.get("currency", "USD")
|
||||
)
|
||||
project = get_object_or_404(Project, id=project_id, is_deleted=False)
|
||||
rate = create_project_rate(
|
||||
project=project,
|
||||
hourly_rate=serializer.validated_data["hourly_rate"],
|
||||
currency=serializer.validated_data.get("currency", "USD")
|
||||
)
|
||||
return Response(ProjectRateSerializer(rate).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
@@ -293,13 +334,13 @@ class ProjectUserRateViewSet(BaseProjectNestedViewSet):
|
||||
project_id = serializer.validated_data["project_id"]
|
||||
self.verify_manager_access(project_id)
|
||||
|
||||
project = get_object_or_404(Project, id=project_id, is_deleted=False)
|
||||
user_rate = create_project_user_rate(
|
||||
project=project,
|
||||
user_id=serializer.validated_data["user_id"],
|
||||
amount=serializer.validated_data["amount"],
|
||||
currency=serializer.validated_data.get("currency", "USD")
|
||||
)
|
||||
project = get_object_or_404(Project, id=project_id, is_deleted=False)
|
||||
user_rate = create_project_user_rate(
|
||||
project=project,
|
||||
user_id=serializer.validated_data["user_id"],
|
||||
hourly_rate=serializer.validated_data["hourly_rate"],
|
||||
currency=serializer.validated_data.get("currency", "USD")
|
||||
)
|
||||
return Response(ProjectUserRateSerializer(user_rate).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
|
||||
Reference in New Issue
Block a user