from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required from django.http import QueryDict from django.shortcuts import redirect, render from django.utils.decorators import method_decorator from django.utils.translation import gettext_lazy as _ from geopy.distance import geodesic from rest_framework import status from rest_framework.pagination import PageNumberPagination from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView from base.models import Company from geofencing.forms import GeoFencingSetupForm from .models import GeoFencing from .serializers import * class GeoFencingSetupGetPostAPIView(APIView): permission_classes = [IsAuthenticated] @method_decorator( permission_required("geofencing.view_geofencing", raise_exception=True), name="dispatch", ) def get(self, request): if request.user.is_superuser: location = GeoFencing.objects.all() else: company = request.user.employee_get.get_company() location = company.geo_fencing.all() paginator = PageNumberPagination() page = paginator.paginate_queryset(location, request) serializer = GeoFencingSetupSerializer(page, many=True) return Response(serializer.data, status=status.HTTP_200_OK) @method_decorator( permission_required("geofencing.add_geofencing", raise_exception=True), name="dispatch", ) def post(self, request): data = request.data if not request.user.is_superuser: if isinstance(data, QueryDict): data = data.dict() company = request.user.employee_get.get_company() if company: data["company_id"] = company.id serializer = GeoFencingSetupSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class GeoFencingSetupPutDeleteAPIView(APIView): permission_classes = [IsAuthenticated] def get_location(self, pk): try: return GeoFencing.objects.get(pk=pk) except Exception as e: raise serializers.ValidationError(e) @method_decorator( permission_required("geofencing.change_geofencing", raise_exception=True), name="dispatch", ) def put(self, request, pk): location = self.get_location(pk) company = request.user.employee_get.get_company() if request.user.is_superuser or company == location.company_id: serializer = GeoFencingSetupSerializer( location, data=request.data, partial=True ) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) raise serializers.ValidationError("Access Denied..") @method_decorator( permission_required("geofencing.delete_geofencing", raise_exception=True), name="dispatch", ) def delete(self, request, pk): location = self.get_location(pk) company = request.user.employee_get.get_company() if request.user.is_superuser or company == location.company_id: location.delete() return Response( {"message": "GeoFencing location deleted successfully"}, status=status.HTTP_200_OK, ) raise serializers.ValidationError("Access Denied..") class GeoFencingEmployeeLocationCheckAPIView(APIView): permission_classes = [IsAuthenticated] def get_company(self, request): try: company = request.user.employee_get.get_company() return company except Exception as e: raise serializers.ValidationError(e) def get_company_location(self, request): company = self.get_company(request) try: location = GeoFencing.objects.get(company_id=company) return location except Exception as e: raise serializers.ValidationError(e) def post(self, request): serializer = EmployeeLocationSerializer(data=request.data) company_location = self.get_company_location(request) if company_location.start: if serializer.is_valid(): geofence_center = ( company_location.latitude, company_location.longitude, ) employee_location = ( request.data.get("latitude"), request.data.get("longitude"), ) distance = geodesic(geofence_center, employee_location).meters if distance <= company_location.radius_in_meters: return Response( {"message": "Inside the geofence"}, status=status.HTTP_200_OK ) return Response( {"message": "Outside the geofence"}, status=status.HTTP_400_BAD_REQUEST, ) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) raise serializers.ValidationError("Geofencing is not yet started..") class GeoFencingSetUpPermissionCheck(APIView): permission_classes = [IsAuthenticated] def get(self, request): geo_fencing = GeoFencingSetupGetPostAPIView() if geo_fencing.get(request).status_code == 200: return Response(status=200) return Response(status=400) def get_company(request): try: selected_company = request.session.get("selected_company") if selected_company == "all": return None company = Company.objects.get(id=selected_company) return company except Exception as e: raise serializers.ValidationError(e) def get_company_location(request): company = get_company(request) try: location = GeoFencing.objects.get(company_id=company) return location except Exception as e: raise serializers.ValidationError(e) @login_required @permission_required("geofencing.add_localbackup") def geo_location_config(request): try: form = GeoFencingSetupForm(instance=get_company_location(request)) except: form = GeoFencingSetupForm() if request.method == "POST": try: form = GeoFencingSetupForm( request.POST, instance=get_company_location(request) ) except: form = GeoFencingSetupForm(request.POST) if form.is_valid(): geofencing = form.save(commit=False) geofencing.company_id = get_company(request) geofencing.save() messages.success(request, _("Geofencing config created successfully.")) else: messages.info(request, "Not valid") return render(request, "geo_config.html", {"form": form})