from rest_framework import status, viewsets from rest_framework.decorators import action from rest_framework.response import Response from apps.accounts.permissions import CanRegisterCitySite, IsExecutive, can_sync from apps.accounts.scoping import filter_city_sites_queryset from apps.farms.services.city_registry import ensure_hq_site_for_city from apps.sync.models import CitySite from apps.sync.serializers import CitySiteSerializer, CitySiteWriteSerializer class CitySiteViewSet(viewsets.ModelViewSet): """ List/read: scoped (director all; BUH managed GMs; GM own). Create/update/delete: GM and GM Admin. Sync: GM and GM Admin only (stubs until mirror pull is implemented). Creating a city site also attaches (or creates) an HQ Site so farm data appears in the executive view list. """ executive_sync_action = True def get_queryset(self): qs = CitySite.objects.select_related("registered_by").all() return filter_city_sites_queryset(qs, self.request.user) def get_permissions(self): if self.action in {"create", "update", "partial_update", "destroy"}: return [CanRegisterCitySite()] return [IsExecutive()] def get_serializer_class(self): if self.action in {"create", "update", "partial_update"}: return CitySiteWriteSerializer return CitySiteSerializer def perform_create(self, serializer): city = serializer.save(registered_by=self.request.user) ensure_hq_site_for_city(city) def perform_update(self, serializer): city = serializer.save() if city.is_active: ensure_hq_site_for_city(city) @action(detail=True, methods=["post"], url_path="sync") def sync(self, request, pk=None): if not can_sync(request.user): return Response({"detail": "Sync not allowed."}, status=status.HTTP_403_FORBIDDEN) city = self.get_object() if not city.is_active: return Response( {"detail": "City site is inactive."}, status=status.HTTP_400_BAD_REQUEST, ) return Response( { "detail": "City sync not implemented yet.", "city_site": CitySiteSerializer(city).data, }, status=status.HTTP_501_NOT_IMPLEMENTED, ) @action(detail=False, methods=["post"], url_path="sync-all") def sync_all(self, request): if not can_sync(request.user): return Response({"detail": "Sync not allowed."}, status=status.HTTP_403_FORBIDDEN) cities = list(self.get_queryset().filter(is_active=True)) return Response( { "detail": "City sync-all not implemented yet.", "city_count": len(cities), "cities": CitySiteSerializer(cities, many=True).data, }, status=status.HTTP_501_NOT_IMPLEMENTED, )