from django.db import transaction from rest_framework import status, filters from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.response import Response from apps.authentication.api.v1.api import UserViewSet from apps.authentication.models import Organization from apps.core.api import BaseViewSet from apps.core.mixins.search_mixin import DynamicSearchMixin from apps.core.mixins.soft_delete_mixin import SoftDeleteMixin from apps.herd.models import Herd, Rancher, RancherOrganizationLink from apps.herd.services.rancher_dashboard_service import RancherDashboardService from apps.herd.services.rancher_org_link_services import RancherOrganizationService from apps.herd.web.api.v1.serializers import HerdSerializer, RancherSerializer, RancherOrganizationLinkSerializer from apps.livestock.web.api.v1.serializers import LiveStockSerializer from apps.product.models import OrganizationQuotaStats from apps.product.services.quota_dashboard_service import QuotaDashboardService from apps.product.web.api.v1.serializers import product_serializers from common.helpers import get_organization_by_user from common.tools import CustomOperations class HerdViewSet(BaseViewSet, SoftDeleteMixin, viewsets.ModelViewSet): """ Herd ViewSet """ queryset = Herd.objects.all() serializer_class = HerdSerializer filter_backends = [filters.SearchFilter] search_fields = [ "rancher__ranching_farm", "rancher__first_name", "rancher__last_name", "rancher__mobile", "rancher__national_code", "rancher__address", "rancher__province__name", "rancher__city__name", "name", "code", "province__name", "city__name", "postal", "institution", "epidemiologic", "activity", "capacity", ] def list(self, request, *args, **kwargs): """ list of herds """ search = self.filter_queryset(self.get_queryset().order_by('-modify_date')) # search & filter page = self.paginate_queryset(search) if page is not None: # noqa serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) @transaction.atomic def create(self, request, *args, **kwargs): """ create herd with user """ organization = get_organization_by_user(request.user) if 'user' in request.data.keys(): # create user if owner of herd is not exist user = CustomOperations().custom_create( request=request, view=UserViewSet(), data_key='user' ) owner = user['id'] request.data.update({'owner': owner}) # if cooperative do not send in request, set my organization in it if 'cooperative' not in request.data.keys(): request.data.update({'cooperative': organization.id}) serializer = self.serializer_class(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN) @action( methods=['get'], detail=False, url_name='my_herds', url_path='my_herds', name='my_herds' ) @transaction.atomic def my_herds(self, request): """ get current user herds """ serializer = self.serializer_class(self.get_queryset().filter(owner=request.user.id), many=True) if serializer.data: return Response(serializer.data, status=status.HTTP_200_OK) else: return Response(status=status.HTTP_204_NO_CONTENT) @action( methods=['get'], detail=True, url_path='live_stocks', url_name='live_stocks', name='live_stocks' ) def live_stocks(self, request, pk=None): """ list of herd live_stocks""" herd = self.get_object() queryset = herd.live_stock_herd.all() # get herd live_stocks # paginate queryset page = self.paginate_queryset(queryset) if page is not None: # noqa serializer = LiveStockSerializer(page, many=True) return self.get_paginated_response(serializer.data) class RancherViewSet(BaseViewSet, RancherDashboardService, SoftDeleteMixin, viewsets.ModelViewSet, DynamicSearchMixin): queryset = Rancher.objects.all() serializer_class = RancherSerializer search_fields = [ "ranching_farm", "first_name", "last_name", "mobile", "national_code", "birthdate", "nationality", "address", "province__name", "city__name", ] def list(self, request, *args, **kwargs): """ list of ranchers """ search = self.filter_query(self.get_queryset().order_by('-modify_date')) # search & filter page = self.paginate_queryset(search) if page is not None: # noqa serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) @action( methods=['get'], detail=True, url_path='herds', url_name='herds', name='herds' ) def herds_by_rancher(self, request, pk=None): """ list of rancher herds """ rancher = self.get_object() queryset = rancher.herd.all().order_by('-modify_date') # get rancher herds # paginate queryset page = self.paginate_queryset(queryset) if page is not None: # noqa serializer = HerdSerializer(page, many=True) return self.get_paginated_response(serializer.data) @action( methods=['get'], detail=True, url_path='rancher_plans', url_name='rancher_plans', name='rancher_plans' ) def rancher_incentive_plans(self, request, pk=None): """ return list of rancher plans with information """ rancher = self.get_object() # rancher object page = self.paginate_queryset(rancher.plans.all()) if page is not None: # noqa serializer = product_serializers.IncentivePlanRancherSerializer(page, many=True) return self.get_paginated_response(serializer.data) @action( methods=['get'], detail=False, url_path='rancher_main_dashboard', url_name='rancher_main_dashboard', name='rancher_main_dashboard' ) def rancher_main_dashboard(self, request, pk=None): """ rancher main dashboard """ query_param = self.request.query_params # noqa query_string = query_param.get('search', None) rancher_dashboard_data = self.get_main_dashboard( self, rancher_search_fields=self.search_fields, herd_search_fields=HerdViewSet.search_fields, query_string=query_string, ) return Response(rancher_dashboard_data) @action( methods=['get'], detail=True, url_path='rancher_dashboard', url_name='rancher_dashboard', name='rancher_dashboard' ) def rancher_dashboard(self, request, pk=None): """ rancher dashboard """ rancher = self.get_object() query_param = self.request.query_params # noqa query_string = query_param.get('search', None) rancher_dashboard_data = self.get_rancher_dashboard( self, rancher=rancher ) return Response(rancher_dashboard_data) @action( methods=['get'], detail=True, url_path='rancher_dashboard_by_quota_usage', url_name='rancher_dashboard_by_quota_usage', name='rancher_dashboard_by_quota_usage' ) def ranchers_dashboard_by_quota_usage(self, request, pk=None): """ rancher dashboard """ rancher = self.get_object() query_param = self.request.query_params # noqa query_string = query_param.get('search', None) rancher_dashboard_data = self.get_rancher_dashboard_by_quota_usage( self, rancher=rancher ) return Response(rancher_dashboard_data) @action( methods=['get'], detail=True, url_path='rancher_dashboard_by_product_usage', url_name='rancher_dashboard_by_product_usage', name='rancher_dashboard_by_product_usage' ) def rancher_dashboard_by_product_usage(self, request, pk=None): """ rancher dashboard """ rancher = self.get_object() query_param = self.request.query_params # noqa query_string = query_param.get('search', None) rancher_dashboard_data = self.get_rancher_dashboard_by_product_usage( self, rancher=rancher ) return Response(rancher_dashboard_data) class RancherOrganizationLinkViewSet( BaseViewSet, SoftDeleteMixin, viewsets.ModelViewSet, RancherOrganizationService, QuotaDashboardService, DynamicSearchMixin ): queryset = RancherOrganizationLink.objects.select_related('organization', 'rancher') serializer_class = RancherOrganizationLinkSerializer search_fields = [ "rancher__ranching_farm", "rancher__first_name", "rancher__last_name", "rancher__mobile", "rancher__national_code", "rancher__birthdate", "rancher__nationality", "rancher__address", "rancher__province__name", "rancher__city__name", "organization__name" ] @action( methods=['get'], detail=False, name='org_linked_rancher_list', url_name='org_linked_rancher_list', url_path='org_linked_rancher_list', ) def org_linked_rancher_list(self, request): """ list of organizations with rancher information """ query_params = self.request.query_params # noqa if not 'org_id' in query_params.keys(): org = get_organization_by_user(request.user) else: org = Organization.objects.get(id=query_params.get('org_id')) result = self.orgs_linked_rancher(org=org, org_type_key='CO') page = self.paginate_queryset(result) # paginate queryset if page is not None: return self.get_paginated_response(page) return Response(result) @action( methods=['get'], detail=True, url_name='org_ranchers', url_path='org_ranchers', name='org_ranchers' ) def org_ranchers(self, request, pk=None): """ list of ranchers by organization """ org_id = pk queryset = self.get_queryset().filter(organization_id=org_id) page = self.paginate_queryset(queryset) if page is not None: # noqa serializer = self.serializer_class(page, many=True) return self.get_paginated_response(serializer.data) return Response(status=status.HTTP_200_OK) @action( methods=['get'], detail=True, url_name='org_ranchers_quota_dashboard', url_path='org_ranchers_quota_dashboard', name='org_ranchers_quota_dashboard' ) def org_ranchers_quota_dashboard(self, request, pk=None): """ dashboard of Org ranchers report by quota """ org_obj = Organization.objects.get(id=pk) dashboard_data = self.get_dashboard(self, org=org_obj) return Response(dashboard_data) @action( methods=['get'], detail=True, url_name='org_ranchers_product_dashboard', url_path='org_ranchers_product_dashboard', name='org_ranchers_product_dashboard' ) def org_ranchers_product_dashboard(self, request, pk=None): """ dashboard of Org ranchers report by quota """ org_obj = Organization.objects.get(id=pk) # get organization quota stats and get product ids org_quota_stat = OrganizationQuotaStats.objects.select_related('organization', 'quota').filter( organization=org_obj, quota__is_closed=False ) products = {f'{stat.quota.product.name}': stat.quota.product.id for stat in org_quota_stat} dashboard_data = self.get_dashboard_by_product(self, organization=org_obj, products=products) return Response(dashboard_data)