from django.shortcuts import render
from django.contrib import auth,messages
from django.shortcuts import render,redirect
from django.contrib.auth.decorators import login_required,user_passes_test
from django.utils.decorators import method_decorator
from mainApp.serializers import *
from mainApp.models import *
from rest_framework.response import Response
from django.contrib.auth.models import  Group, Permission
from rest_framework import status
from django.http import JsonResponse,HttpResponse
from rest_framework.views import APIView
#import json , requests
from django.conf import settings as stg
from datetime import datetime,date,timedelta
from django.db.models import Count,Sum
import json
from django.utils import timezone
from itertools import chain # Join Multiple Querysets From Different Base Models Django
#from django.core import serializers

#import urllib
#https://stackoverflow.com/questions/16041232/django-delete-filefield


############## GENERAL_TOOLS #################
def getClinicId(request):
    try :
        clinicId =  request.session['clinicId'] if 'clinicId' in request.session else request.user.groups.first().clinic.id
    except :
        clinicId = None
    return clinicId
############## END GENERAL_TOOLS #################

############## GENERAL_APIS #################
class NetProfitApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_NetProfit'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        return render(request,"mainApp/generalPages/earnings.html",{'activePage':'NetProfit'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_Earning'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        startDate = datetime.strptime(data["startDate"], '%Y-%m-%dT%H:%M:%S')
        endDate = datetime.strptime(data["endDate"], '%Y-%m-%dT%H:%M:%S')
        income_info = []
        total_income = 0
        PatientExternalPayment_info = PatientExternalPayment.objects.filter(created_at__range=[startDate,endDate]).aggregate(total=Sum('amount_paid'))
        extrnl_pymnt = PatientExternalPayment_info["total"]
        if extrnl_pymnt :
            medical_service_obj = {"medicalservice_str":"مدفوعات إضافية",
                "medicalservice_price":"",
                "medicalservice_count":"",
                "medicalservice_total":extrnl_pymnt}
            total_income=total_income + extrnl_pymnt
            income_info.append(medical_service_obj)
        medicalServices = MedicalService.objects.all()
        PatientVisits_info = PatientVisit.objects.filter(created_at__range=[startDate,endDate]).values("medicalservice").annotate(Count('medicalservice'),total=Sum('amount_paid'))
        Expenses_info=[]
        for obj in PatientVisits_info :
            response_obj = {}
            medicalservice_id=obj["medicalservice"]
            medicalService__ = medicalServices.get(id=medicalservice_id)
            medical_service_obj = {"medicalservice_str":medicalService__.name,
            "medicalservice_price":medicalService__.price,
            # "medicalservice_id":medicalservice_id ,
            "medicalservice_count":obj["medicalservice__count"],
            "medicalservice_total":obj["total"]}
            response_obj.update(medical_service_obj)
            income_info.append(medical_service_obj)
            total_income=total_income + obj["total"]

        # surgerys = Surgery.objects.all()
        # ptSurgerys_info = PtSurgery.objects.filter(created_at__range=[startDate,endDate]).values("surgery").annotate(Count('surgery'),total=Sum('amount_paid'))
        # Expenses_info=[]
        # for obj in ptSurgerys_info :
        #     response_obj = {}
        #     surgery_id=obj["surgery"]
        #     surgery__ = surgerys.get(id=surgery_id)
        #     surgery_obj = {"medicalservice_str":surgery__.name,
        #     "medicalservice_price":surgery__.price,
        #     # "surgery_id":surgery_id ,
        #     "medicalservice_count":obj["surgery__count"],
        #     "medicalservice_total":obj["total"]}
        #     response_obj.update(surgery_obj)
        #     income_info.append(surgery_obj)
        #     total_income=total_income + obj["total"]

        Expenses_info = Expense.objects.filter(
            created_by__in=User.objects.filter(groups__id__in=Group.objects.all().values_list("id")),
            created_on__range=[startDate,endDate]
            ).values("item").annotate(Count('item'),total=Sum('price'))
        expense_info = []
        total_expense = 0
        expenseItems = ExpenseItem.objects.all()
        for obj in Expenses_info :
            #response_obj = {}
            item_id=obj["item"]
            expenseItem__ = expenseItems.get(id=item_id)
            expense_item_obj = {"expenseItem_str":expenseItem__.name,
            "expenseItem_count":obj["item__count"],
            "expenseItem_total":obj["total"]}
            #response_obj.update(expense_item_obj)
            expense_info.append(expense_item_obj)
            total_expense=total_expense + obj["total"]

        return Response({
            "income_info":income_info,"total_income":total_income,
            "expense_info":expense_info,"total_expense":total_expense,
        },status=status.HTTP_201_CREATED)

class PrintReportApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.PrintReport'), login_url='/main/login/'))
    def post(self,request):
        #request.data._mutable = True
        report_name=request.data.get("report_name")
        master_pk=request.data.get("master_pk")
        context={}
        if report_name == "prescription_pv" :#master_pk is patient visit used to collect all data
            template_name = "clinicReports/{}/prescription_pv.html".format(request.session['reports_code'])
            visit_id=master_pk
            next_consult=request.data.get("next_consult")
            doctor_notes= request.data.get("doctor_notes")
            patientVisitObj = PatientVisit.objects.get(pk=visit_id)
            if doctor_notes != "NoContent" : patientVisitObj.doctor_notes=doctor_notes
            patientVisitObj.next_consult=next_consult if next_consult and int(next_consult) > 0 else 0
            patientVisitObj.save()
            context.update({"patientVisit":patientVisitObj})
            patient=Patient.objects.get(pk=patientVisitObj.patient.pk)
            if next_consult or int(next_consult) >= 0 :
                todayObj = date.today()
                next_consult_day = todayObj+timedelta(days=int(next_consult))
                patient.next_consult = next_consult_day
                patient.save()
                #if next_consult_day > patient.next_consult :
            # else :
            #     patient.next_consult = next_consult_day
            #     patient.save()
            context.update({"patient":patient})
            presDrugItems=PresDrugItem.objects.filter(patient_visit=patientVisitObj)
            presDrugItems_serialized=PresDrugItemSerializer(presDrugItems,many=True)
            context.update({"presDrugItems":presDrugItems_serialized.data})
            presRadiologyItems=PresRadiologyItem.objects.filter(patient_visit=patientVisitObj)
            presRadiologyItems_serialized=PresRadiologyItemSerializer(presRadiologyItems,many=True)
            context.update({"presRadiologyItems":presRadiologyItems_serialized.data})
            presTestItems=PresTestItem.objects.filter(patient_visit=patientVisitObj)
            presTestItems_serialized=PresTestItemSerializer(presTestItems,many=True)
            context.update({"presTestItems":presTestItems_serialized.data})
            return render(request,template_name,context)
        elif report_name == "prescription_ps" :#master_pk is patient session Item  used to collect all data
            template_name = "clinicReports/{}/prescription_ps.html".format(request.session['reports_code'])
            psi_id=master_pk
            psiObj = PatientSessionItem.objects.get(pk=psi_id)
            #patient=Patient.objects.get(pk=ptntSsnItmObj.patient_session.patient.pk)
            context.update({"patient":psiObj.patient_session.patient})
            #user prescription items 
            presDrugItems=PresPsiDrugItem.objects.filter(psi=psiObj)
            presDrugItems_serialized= PresPsiDrugItemSerializer(presDrugItems,many=True)
            context.update({"presDrugItems":presDrugItems_serialized.data})
            presRadiologyItems= PresPsiRadiologyItem.objects.filter(psi=psiObj)
            presRadiologyItems_serialized= PresPsiRadiologyItemSerializer(presRadiologyItems,many=True)
            context.update({"presRadiologyItems":presRadiologyItems_serialized.data})
            presTestItems= PresPsiTestItem.objects.filter(psi=psiObj)
            presTestItems_serialized= PresPsiTestItemSerializer(presTestItems,many=True)
            context.update({"presTestItems":presTestItems_serialized.data})

            return render(request,template_name,context) 
        elif report_name == "exercises_ps":#master_pk is patient session Item  used to collect all data
            template_name = "clinicReports/{}/exercises_ps.html".format(request.session['reports_code'])
            psi_id=master_pk
            psiObj = PatientSessionItem.objects.get(pk=psi_id)
            #patient=Patient.objects.get(pk=ptntSsnItmObj.patient_session.patient.pk)
            context.update({"patient":psiObj.patient_session.patient})
            PsiExrszItems= PsiExrszItem.objects.filter(psi=psiObj)
            PsiExrszItems_serialized= PsiExrszItemSerializer(PsiExrszItems,many=True)
            context.update({"PsiExrszItems":PsiExrszItems_serialized.data})
            return render(request,template_name,context) 

class GeneralReportApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_GeneralReport'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        #Patient.objects.all().values_list('location',flat=True).distinct().count().annotate(total=Sum('location'))
        #patients =Patient.objects.values("location__name","found_way__name")
        locations = Patient.objects.values("location__name").annotate(Count('location'))
        found_ways = Patient.objects.values("found_way__name").annotate(Count('found_way'))
        locations_names = [l['location__name'] for l in locations]
        locations_count = [l['location__count'] for l in locations]
        ways_names = [w['found_way__name'] for w in found_ways]
        ways_count = [w['found_way__count'] for w in found_ways]
        return render(request,"mainApp/generalPages/general_reports.html",{
            "locations_names":locations_names,"locations_count":locations_count,
            "ways_names":ways_names,"ways_count":ways_count,
            'activePage':'GeneralReport'})

############## END GENERAL_APIS #################

############## User%Module #################

def login(request):
    if request.method == "POST":
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        user = auth.authenticate(username=username, password=password)
        if user is not None:
            auth.login(request, user)
            user_clinic = user.groups.first().clinic
            request.session['clinicName'] = user_clinic.name
            request.session['clinicId'] = user_clinic.id
            request.session['clinicIcon'] = user_clinic.icon_img.url
            request.session['reports_code'] = user_clinic.reports_code
            if request.user.is_authenticated and request.user.is_superuser : return redirect('mainApp:welcome')
            elif request.user.is_authenticated :return redirect('receptionApp:welcome')
            else : return render(request,'mainApp/userPages/login.html')
        else:
            return render(request, 'mainApp/userPages/login.html', {'error_message': 'إسم المستخدم أو كلمة المرور خطأ'})

    if request.user.is_authenticated and request.user.is_superuser : return redirect('mainApp:welcome')
    elif request.user.is_authenticated :return redirect('receptionApp:welcome')
    else : return render(request,'mainApp/userPages/login.html')

@login_required(login_url='mainApp:login')
@user_passes_test(lambda u: u.has_perm('screen.view_welcomeAdmins'), login_url='/main/login/')
def welcome(request):
    user_clinic_image = Clinic.objects.get(id=request.session['clinicId']).welcome_img.url
    return render(request,'welcome.html',{"user_clinic_image":user_clinic_image})

@login_required(login_url='mainApp:login')
def logout(request):
    if 'clinicName' in request.session: del request.session['clinicName']
    auth.logout(request)
    return redirect('/main/login/')

### users api
class UsersApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_siteUsers'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        clinic_groups= Group.objects.filter(clinic_id=getClinicId(request))
        #clinic_groups= Group.objects.all()
        clinic_users=User.objects.filter(groups__in=clinic_groups)
        clinic_groups_serialized = GroupSerializer(clinic_groups,many=True)
        clinic_users_serialized = UserSerializerCust(clinic_users,many=True)
        return render(request,"mainApp/userPages/app_users.html",{"all_users": clinic_users_serialized.data,"all_groups": clinic_groups_serialized.data,'activePage':'appUsers'})

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_siteUsers'), login_url='/main/login/'))
    def post(self,request):
        context = {}
        context.update({"created_by":request.user.id})
        selected_group_id = request.data["group_id"]
        context.update({"group_id":selected_group_id})
        serializedObj= UserSerializer(data = request.data,context=context)
        if serializedObj.is_valid():
            serializedObj.save()
            userObj = User.objects.get(pk=serializedObj.data["id"])
            userObj.groups.clear()
            userObj.groups.add(selected_group_id)
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)    
class UserApi(APIView):
    def get_object(self,pk):
        try:
            return User.objects.get(pk=pk)
        except User.DoesNotExist:
            return None 

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_siteUsers'), login_url='/main/login/'))
    def get(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            serializeobj= UserSerializerCust(obj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else :Response(status=status.HTTP_204_NO_CONTENT)
        
 ##### edit password if is password =1 and edit all feilds else password when ispassword =0
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_siteUsers'), login_url='/main/login/'))
    def put(self,request,pk):
        ispassword=request.POST.get("ispassword")
        userObj=self.get_object(pk)
        if userObj :
            if ispassword == '0' :
                try:
                    context = {}
                    context.update({"created_by":request.user.id})
                    selected_group_id = request.data["group_id"]
                    context.update({"group_id":selected_group_id})
                    serializeobj= UserWithoutPasswordSerializer(userObj,data=request.data,context=context)
                    data=request.data
                    if serializeobj.is_valid():
                        serializeobj.save()
                        userObj.groups.clear()
                        userObj.groups.add(data['group_id'])
                        return Response(status=status.HTTP_200_OK)
                    else:
                        return Response(serializeobj.errors,status=status.HTTP_400_BAD_REQUEST)
                except Exception as err_msg: 
                        return Response({"err_msg":err_msg},status=status.HTTP_405_METHOD_NOT_ALLOWED)# old error was cant edit :!
            else :
                serializeobj= UserPasswordSerializer(userObj,data=request.data)
                if serializeobj.is_valid():
                    serializeobj.save()
                    return Response(status=status.HTTP_200_OK)
                else :return Response(serializeobj.errors,status=status.HTTP_400_BAD_REQUEST)   
        else :Response(status=status.HTTP_204_NO_CONTENT)
        

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_siteUsers'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except:
                return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

### groups API
class GroupsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_siteGroups'), login_url='/main/login/'))
    def get(self,request):
        # get all groups and all permssions of content typ app_lablel = screen
        if not getClinicId(request) : return redirect('/main/login/')
        all_groups= Group.objects.filter(clinic_id=getClinicId(request))
        #all_groups= Group.objects.all()
        all_groups_serialized = GroupSerializer(all_groups,many=True)
        # return Response({"all_groups": all_groups_serialized.data})
        return render(request,"mainApp/userPages/groups.html",{"all_groups": all_groups_serialized.data,'activePage':'appGroups'})

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_siteGroups'), login_url='/main/login/'))
    def post(self,request):
        # post new group only without premssions
        if not getClinicId(request) : return redirect('/main/login/')
        serializeobj= GroupSerializer(data=request.data)
        if serializeobj.is_valid():
            serializeobj.save()
            return Response(serializeobj.data,status=status.HTTP_201_CREATED)
        else : return Response(serializeobj.errors,status=status.HTTP_400_BAD_REQUEST)
class GroupApi(APIView):
    def get_object(self,pk):
        try:
            return Group.objects.get(pk=pk)
        except Group.DoesNotExist:
            return None   
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_siteGroups'), login_url='/main/login/'))
    def get(self,request,pk):
        #get this group and it's permissions
        obj=self.get_object(pk)
        if obj :
            group_obj= GroupWithPermissionsSerializer(obj)#with permissions
            all_Permissions= Permission.objects.filter(content_type__app_label="screen").order_by('id')
            lst = list(range(0,all_Permissions.count(),4))
            screens = []
            for cnt in lst:
                screen = []
                screen.append(PermissionSerializer(all_Permissions[cnt]).data)
                screen.append(PermissionSerializer(all_Permissions[cnt+1]).data)
                screen.append(PermissionSerializer(all_Permissions[cnt+2]).data)
                screen.append(PermissionSerializer(all_Permissions[cnt+3]).data)
                screens.append(screen)
            return Response({"group":group_obj.data,"all_permissions": screens},status=status.HTTP_200_OK)
        

    # update group permissions to with new list
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_siteGroups'), login_url='/main/login/'))
    def put(self,request,pk):
        data=request.data
        isgroupEdit=request.POST.get("isgroupEdit")
        permissionslist=request.POST.getlist("permissions[]")
        obj=self.get_object(pk)
        if isgroupEdit == '1' :
            serializeobj= GroupSerializer(obj,data)
            if serializeobj.is_valid():
                serializeobj.save()
                return Response(status=status.HTTP_200_OK)
            else : Response(serializeobj.errors,status=status.HTTP_400_BAD_REQUEST)  
        else:
            serializeobj= GroupSerializer(obj,data)
            if serializeobj.is_valid():
                serializeobj.save()
                obj.permissions.clear()
                for perm in permissionslist:
                    obj.permissions.add(perm)
                return Response(serializeobj.data,status=status.HTTP_200_OK)
            else :return Response(serializeobj.errors,status=status.HTTP_400_BAD_REQUEST)
        return Response(serializeobj.errors,status=status.HTTP_400_BAD_REQUEST) 


 
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_siteGroups'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            if obj.user_set.all().count() == 0:
                try:
                    obj.delete()
                    return Response(status=status.HTTP_204_NO_CONTENT)
                except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
            else:
                return Response(data ="يرجي حذف البيانات المرتبطة أولا لحذف هذا العنصر !!!",status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

# check if user is admin or not to enable editing
def IsAdmin(userId):
    userGroupName = User.objects.get(auth_user_id=userId).group.name
    if userGroupName == "superadmin":return True
    else :return False

############## END User%Module #################

############## Finance%Module #################

class ExpenseItemsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_ExpenseItem'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_expense_items =ExpenseItem.objects.all()
        all_expense_items_serialized=ExpenseItemSerializer(all_expense_items,many=True)
        return render(request,"mainApp/financePages/expense_items.html",{"all_expense_items":all_expense_items_serialized.data,'activePage':'ExpenseItems'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_ExpenseItem'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= ExpenseItemSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class ExpenseItemApi(APIView):
    def get_object(self,pk):
        try:
            return ExpenseItem.objects.get(pk=pk)
        except ExpenseItem.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_ExpenseItem'), login_url='/main/login/'))        
    def get(self,request,pk): 
        expense_itemObj=self.get_object(pk)
        if expense_itemObj :
            serializeobj= ExpenseItemSerializer(expense_itemObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_ExpenseItem'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= ExpenseItemSerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

            

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_ExpenseItem'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)
from django.urls import reverse
class MedServiceReportDoctor(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_MedServiceReportDoctor'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        medical_services = MedicalService.objects.filter(is_service=True).values("id","name")
        doctors =User.objects.filter(is_doctor=True,is_active=True).values("id","first_name","last_name")
        med_service_url = reverse('mainApp:MedServiceReportDoctor')
        return render(request,"mainApp/financePages/med_service/doctor.html",{
            "medical_services":medical_services,
            "doctors":doctors,
            'activePage':'MedServiceReportDoctor'})

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_MedServiceReportDoctor'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        startDate = data["startDate"]
        startDateTime= datetime.strptime(startDate,"%Y-%m-%d")
        endDate = data["endDate"]
        endDateTime= datetime.strptime(endDate,"%Y-%m-%d").replace(hour=23,minute=59,second=59) 
        doctor = data["doctor"]
        medicalservice=data["medicalservice"]
        if medicalservice == "0" :
            visits = PatientVisit.objects.filter(created_at__gte = startDateTime , created_at__lte=endDateTime,doctor_id=doctor,visit_status="4F").order_by("created_at")
        else : 
            visits = PatientVisit.objects.filter(created_at__gte = startDateTime , created_at__lte=endDateTime,doctor_id=doctor,medicalservice_id=medicalservice,visit_status="4F").order_by("created_at")
       
        serializer= MedServiceDoctorSerializer(visits,many=True)
        return Response(serializer.data,status=status.HTTP_200_OK)


class MedServiceReportHalf(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_MedServiceReportHalf'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        medical_services = MedicalService.objects.filter(is_service=True).values("id","name")
        doctors =User.objects.filter(is_doctor=True,is_active=True).values("id","first_name","last_name")
        med_service_url = reverse('mainApp:MedServiceReportHalf')
        return render(request,"mainApp/financePages/med_service/doctor.html",{
            "medical_services":medical_services,
            "doctors":doctors,
            "med_service_url":med_service_url,
            'activePage':'MedServiceReportHalf'})

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_MedServiceReportHalf'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        startDate = data["startDate"]
        startDateTime= datetime.strptime(startDate,"%Y-%m-%d")
        endDate = data["endDate"]
        endDateTime= datetime.strptime(endDate,"%Y-%m-%d").replace(hour=23,minute=59,second=59)
        doctor=data["doctor"]
        medicalservice=data["medicalservice"]
        if medicalservice == "0" :
            visits = PatientVisit.objects.filter(created_at__gte = startDateTime , created_at__lte=endDateTime,doctor_id=doctor,visit_status="4F").order_by("created_at")
        else : 
            visits = PatientVisit.objects.filter(created_at__gte = startDateTime , created_at__lte=endDateTime,doctor_id=doctor,medicalservice_id=medicalservice,visit_status="4F").order_by("created_at")
       
        serializer= MedServiceHalfSerializer(visits,many=True)
        return Response(serializer.data,status=status.HTTP_200_OK)

class CheckCenterReportApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CheckupReportCenter'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        return render(request,"mainApp/financePages/checkup/center.html",{'activePage':'CheckupReport_Center'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CheckupReportCenter'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        startDate = data["startDate"]
        endDate = data["endDate"]
        c_visits = PatientVisit.objects.filter(created_at__gte = startDate , created_at__lte=endDate,medicalservice__is_service=False,visit_status="4F").order_by("created_at","doctor")
        serializer= CheckupVisitSerializer(c_visits,many=True)
        return Response(serializer.data,status=status.HTTP_200_OK)

class CheckDoctorReportApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CheckupReportDoc'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        doctors =User.objects.filter(is_doctor=True,is_active=True).values("id","first_name","last_name")
        return render(request,"mainApp/financePages/checkup/doctor.html",{
            "doctors":doctors,
            'activePage':'CheckupReport_Doc'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CheckupReportDoc'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        startDate = data["startDate"]
        endDate = data["endDate"]
        doctor = data["doctor"]
        c_visits = PatientVisit.objects.filter(created_at__gte = startDate , created_at__lte=endDate,medicalservice__is_service=False,visit_status="4F",doctor_id=doctor).order_by("created_at")
        serializer= CheckupVisitSerializer(c_visits,many=True)
        return Response(serializer.data,status=status.HTTP_200_OK)

class CheckOperatorReportApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CheckupReportOp'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        return render(request,"mainApp/financePages/checkup/operator.html",{'activePage':'CheckupReport_Op'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CheckupReportOp'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        startDate = data["startDate"]
        endDate = data["endDate"]
        c_visits = PatientVisit.objects.filter(created_at__gte = startDate , created_at__lte=endDate,medicalservice__is_service=False,visit_status="4F").order_by("created_at")
        serializer= CheckupVisitSerializer(c_visits,many=True)
        return Response(serializer.data,status=status.HTTP_200_OK)



############## END Finance%Module #################
##############  PatientReports%Module #################
class CommonDiseasesReportApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CommonDiseasesReport'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        return render(request,"mainApp/patientReports/common_diseases.html",{
            "commond_diseases":CommonDisease.objects.all().values("id","name"),
            'activePage':'CommonDiseasesReport'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CommonDiseasesReport'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        data=request.data
        disease_id = data["disease"]
        patient_ids = PatientInfo.objects.filter(disease_id=disease_id).values_list('patient_id',flat=True)
        patients = Patient.objects.filter(id__in=patient_ids).order_by('birth_date')
        serializer= PatientCustomSerializer(patients,many=True)
        return Response(serializer.data,status=status.HTTP_200_OK)
############## END PatientReports%Module #################

############## END Finance%Module #################

############## AdditionalInfo%Module #################
class FoundWaysApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_FoundWay'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        found_ways =FoundWay.objects.all()
        serializer=FoundWaySerializer(found_ways,many=True)
        return render(request,"mainApp/additionalPages/found_ways.html",{"all_ways":serializer.data,'activePage':'FoundWays'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_FoundWay'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= FoundWaySerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class FoundWayApi(APIView):
    def get_object(self,pk):
        try:
            return FoundWay.objects.get(pk=pk)
        except FoundWay.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_FoundWay'), login_url='/main/login/'))        
    def get(self,request,pk): 
        companyObj=self.get_object(pk)
        if companyObj :
            serializeobj= FoundWaySerializer(companyObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_FoundWay'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= FoundWaySerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)          

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_FoundWay'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)


class NationalitiesApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_nationality'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        Nationalities =Nationality.objects.all()
        serializer=NationalitySerializer(Nationalities,many=True)
        return render(request,"mainApp/additionalPages/nationalities.html",{"all_nationalities":serializer.data,'activePage':'Nationalities'})
    #@method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_nationality'), login_url='/main/login/'))    
    def post(self,request):
        #if not getClinicId(request) : return redirect('/main/login/')
        nationality_serializer= NationalitySerializer(data=request.data)
        if nationality_serializer.is_valid():
            nationality = nationality_serializer.save()
            # Create a Location with the same name as the Nationality
            location_data = {'name': nationality.name, 'nationality': nationality.id}
            location_serializer = LocationSerializer(data=location_data)
            if location_serializer.is_valid():
                location_serializer.save()
                # Create a City with the same name as the Nationality
                city_data = {'name': nationality.name, 'location': location_serializer.data['id']}
                city_serializer = CitySerializer(data=city_data)
                if city_serializer.is_valid():
                    city_serializer.save()
                    return Response({'message': 'Nationality, Location, and City created successfully!'},
                                    status=status.HTTP_201_CREATED)
            # If there's an issue with Location creation, delete the created Nationality
            nationality.delete()
            return Response(location_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        else :return Response(nationality_serializer.errors,status=status.HTTP_400_BAD_REQUEST)

class NationalityApi(APIView):
    def get_object(self,pk):
        try:
            return Nationality.objects.get(pk=pk)
        except Nationality.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_nationality'), login_url='/main/login/'))        
    def get(self,request,pk): 
        NationalityObj=self.get_object(pk)
        if NationalityObj :
            serializeobj= NationalitySerializer(NationalityObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_nationality'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= NationalitySerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)          

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_nationality'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

class LocationsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Location'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        locations =Location.objects.all()
        nationalities =Nationality.objects.all()
        serializer=LocationSerializer(locations,many=True)
        return render(request,"mainApp/additionalPages/locations.html",{"all_locations":serializer.data,"nationalities":nationalities,'activePage':'Locations'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_Location'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= LocationSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class LocationApi(APIView):
    def get_object(self,pk):
        try:
            return Location.objects.get(pk=pk)
        except Location.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Location'), login_url='/main/login/'))        
    def get(self,request,pk): 
        companyObj=self.get_object(pk)
        if companyObj :
            serializeobj= LocationSerializer(companyObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_Location'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= LocationSerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)          

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_Location'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

class CitiesApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_nationality'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        nationalities =Nationality.objects.all()
        locations =Location.objects.all()
        cities =City.objects.all()
        serializer=CitySerializer(cities,many=True)
        return render(request,"mainApp/additionalPages/cities.html",{
            "all_cities":serializer.data,"nationalities":nationalities,"locations":locations,
            'activePage':'Cities'})
    
    #@method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_City'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= CitySerializer(data=request.data)
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data ,status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class CityApi(APIView):
    def get_object(self,pk):
        try:
            return City.objects.get(pk=pk)
        except City.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_City'), login_url='/main/login/'))        
    def get(self,request,pk): 
        CityObj=self.get_object(pk)
        if CityObj :
            serializeobj= CitySerializer(CityObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_City'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= CitySerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)          

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_City'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

class PatientJobsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Job'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        jobs =PatientJob.objects.all()
        serializer=PatientJobSerializer(jobs,many=True)
        return render(request,"mainApp/additionalPages/patient_jobs.html",{"all_jobs":serializer.data,'activePage':'PatientJobs'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_Job'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= PatientJobSerializer(data=request.data)
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class PatientJobApi(APIView):
    def get_object(self,pk):
        try:
            return PatientJob.objects.get(pk=pk)
        except PatientJob.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Job'), login_url='/main/login/'))        
    def get(self,request,pk): 
        patientJobObj=self.get_object(pk)
        if patientJobObj :
            serializeobj= PatientJobSerializer(patientJobObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_Job'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= PatientJobSerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)          

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_Job'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

class HourSlotsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_HourSlot'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        hour_slots =HourSlot.objects.all()
        serializer=HourSlotSerializer(hour_slots,many=True)
        return render(request,"mainApp/hourSlotPages/hour_slots.html",{"all_hour_slots":serializer.data,'activePage':'HourSlots'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_HourSlot'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= HourSlotSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class HourSlotApi(APIView):
    def get_object(self,pk):
        try:
            return HourSlot.objects.get(pk=pk)
        except HourSlot.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_HourSlot'), login_url='/main/login/'))        
    def get(self,request,pk): 
        obj=self.get_object(pk)
        if obj :
            serializeobj= HourSlotSerializer(obj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_HourSlot'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= HourSlotSerializer(obj,data=request.data,partial=True)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)          

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_HourSlot'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

class WeekDaysApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_WeekDay'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        hour_slots =WeekDay.objects.all()
        serializer=WeekDaySerializer(hour_slots,many=True)
        return render(request,"mainApp/WeekDayPages/hour_slots.html",{"all_hour_slots":serializer.data,'activePage':'WeekDaysAlex'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_WeekDay'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= WeekDaySerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class WeekDayApi(APIView):
    def get_object(self,pk):
        try:
            return WeekDay.objects.get(pk=pk)
        except WeekDay.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_WeekDay'), login_url='/main/login/'))        
    def get(self,request,pk): 
        obj=self.get_object(pk)
        if obj :
            serializeobj= WeekDaySerializer(obj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_WeekDay'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= WeekDaySerializer(obj,data=request.data,partial=True)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)          

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_WeekDay'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)


###### Diseases تشخيصات الأمراض الشائعة ########
class DiseasesApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Disease'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_diseases =CommonDisease.objects.all()
        serializer=CommonDiseaseSerializer(all_diseases,many=True)
        return render(request,"mainApp/patientPages/diseases.html",{"all_diseases":serializer.data,'activePage':'CommonDiseases'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_Disease'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        request.data._mutable = True
        #request.data.update({"clinic": getClinicId(request)})
        serializedObj= CommonDiseaseSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data,status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class DiseaseApi(APIView):
    def get_object(self,pk):
        try:
            return CommonDisease.objects.get(pk=pk)
        except CommonDisease.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Disease'), login_url='/main/login/'))        
    def get(self,request,pk): 
        obj=self.get_object(pk)
        if obj :
            serializeobj= CommonDiseaseSerializer(obj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_Disease'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= CommonDiseaseSerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_Disease'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

############## END AdditionalInfo%Module #################
############## MedicalService%Module #################
from surgeryApp.models import Surgery,PtSurgery
from surgeryApp.serializers import SurgerySerializer
class DoctorsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Doctors'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        doctors =User.objects.filter(is_doctor=True,is_active=True).values("id","first_name","last_name")
        medical_services =MedicalService.objects.all().order_by("is_service")
        ms_serializer=MedicalServiceSerializer(medical_services,many=True)
        surgeries = Surgery.objects.all().order_by("is_service")
        surgery_serializer=SurgerySerializer(surgeries,many=True)
        return render(request,"mainApp/med_servicePages/doctors.html",{
            "doctors":doctors,
            "medical_services":ms_serializer.data,
            "surgeries":surgery_serializer.data,
            'activePage':'Doctors'})

class DoctorApi(APIView):
    def get_object(self,pk):
        try:
            return User.objects.get(pk=pk)
        except User.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Organization'), login_url='/main/login/'))        
    def get(self,request,pk):
        if not getClinicId(request) : return redirect('/main/login/')
        doctorObj=self.get_object(pk)
        if doctorObj :
            mdclSrvcDocObjs =  MedicalServiceDoctor.objects.filter(doctor=doctorObj)
            msd_serializer= MedicalServiceDoctorSerializer(mdclSrvcDocObjs,many=True)
            return Response(msd_serializer.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_Organization'), login_url='/main/login/'))    
    def post(self,request,pk):
        if not getClinicId(request) : return redirect('/main/login/')
        try:
            request.data._mutable = True
            newPricesJson = request.data.get("newPrices")
            newPricesLst = json.loads(newPricesJson)
            mdclSrvcOrgObjs =  MedicalServiceDoctor.objects.filter(doctor_id=pk)
            for obj in newPricesLst :
                if mdclSrvcOrgObjs.filter(medicalservice_id=obj["medicalservice"]).exists():
                    mdclSrvcOrgObj = mdclSrvcOrgObjs.get(medicalservice_id=obj["medicalservice"])
                    mdclSrvcOrgObj.doctor_price=obj["doctor_price"]
                    mdclSrvcOrgObj.save()
                else :
                    newObj = MedicalServiceDoctor(medicalservice_id=obj["medicalservice"],doctor_id=pk,doctor_price=obj["doctor_price"])
                    newObj.save()
            return Response(status=status.HTTP_200_OK)
        except :return Response(status=status.HTTP_400_BAD_REQUEST)

class MedicalServicesApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_medicalService'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_medical_services =MedicalService.objects.all().order_by("is_service")
        all_medical_services_serialized=MedicalServiceSerializer(all_medical_services,many=True)
        return render(request,"mainApp/med_servicePages/medical_services.html",{"all_medical_services":all_medical_services_serialized.data,'activePage':'MedicalServices'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_medicalService'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= MedicalServiceSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class MedicalServiceApi(APIView):
    def get_object(self,pk):
        try:
            return MedicalService.objects.get(pk=pk)
        except MedicalService.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_medicalService'), login_url='/main/login/'))        
    def get(self,request,pk): 
        medical_serviceObj=self.get_object(pk)
        if medical_serviceObj :
            serializeobj= MedicalServiceSerializer(medical_serviceObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_medicalService'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= MedicalServiceSerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

            

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_medicalService'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)


############## END MedicalService%Module #################

############## Patient%Module #################

class PatientsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_patients'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_patients =Patient.objects.all()
        max_code = all_patients.aggregate(Max('code'))
        if max_code["code__max"] : new_code_value = int(max_code["code__max"])+1
        else : new_code_value = 1
        #all_patients_serialized=PatientSerializer(all_patients,many=True)
        marital_status_choices = ChoiceField(choices=MARITAL_STATUS_CHOICES)
        return render(request,"mainApp/patientPages/patients.html",{
        #"all_patients":all_patients_serialized.data,
        "all_patients":all_patients,
        "foundWays":FoundWay.objects.all(),
        "locations":Location.objects.all(),
        "nationalities":Nationality.objects.all(),
        "jobs":PatientJob.objects.all(),
        "marital_status":marital_status_choices.choices,
        "new_code_value":new_code_value,'activePage':'Patients'})
    #@method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_patients'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        request.data._mutable = True
        # request.data.update({"organization": None if request.data.get('organization') == "0" else request.data.get('organization')})
        # request.data.update({"company": None if request.data.get('company') == "0" else request.data.get('company')})
        request.data.update({"created_by":request.user.id})
        serializedObj= PatientSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data , status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class PatientApi(APIView):
    def get_object(self,pk):
        try:
            return Patient.objects.get(pk=pk)
        except Patient.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_patients'), login_url='/main/login/'))        
    def get(self,request,pk): 
        patientObj=self.get_object(pk)
        if patientObj :
            patient_serialized=PatientSerializer(patientObj)
            context = {"patient":patient_serialized.data,'activePage':'Patients'}
            patientVisitObjs = PatientVisit.objects.filter(patient=patientObj,visit_status__in=["1I","4F"]).order_by('-visit_day')
            patientVisitObjs_serialized = PatientVisitMiniSerializer(patientVisitObjs,many=True)
            context.update({'patientVisitObjs':patientVisitObjs_serialized.data})
            try : 
                patientInfoObj = PatientInfo.objects.get(patient=patientObj)
                context.update({'pI':patientInfoObj})
            except PatientInfo.DoesNotExist:
                context.update({'pI':None})
            
            medical_services =MedicalService.objects.all().values('id', 'name','price')
            context.update({"medical_services":medical_services,})           
            blood_type_choices = ChoiceField(choices=BLOOD_TYPE_CHOICES)
            context.update({"blood_types":blood_type_choices.choices,})
            context.update({"pageTitle":patientObj.fullname,})
            context.update({"all_diseases":CommonDisease.objects.all().values("id","name"),})

            return render(request,"mainApp/patientPages/patient.html",context)

        #     serializeobj= PatientSerializer(obj)
        #     return Response(serializeobj.data,status=status.HTTP_200_OK)
        # else : return Response(status=status.HTTP_404_NOT_FOUND)

    #@method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_patients'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        request.data._mutable = True
        request.data.update({"created_by":request.user.id})
        # request.data.update({"organization": None if request.data["organization"] == "0" else request.data["organization"]})
        # request.data.update({"company": None if request.data["company"] == "0" else request.data["company"]})
        serializedObj= PatientSerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

            

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_patients'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

class PatientInfoApi(APIView):
    def get_object(self,pk):
        try:
            return PatientInfo.objects.get(patient=pk)
        except PatientInfo.DoesNotExist:
            return None    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_patient_info'), login_url='/main/login/'))        
    def put(self,request,pk):
        obj=self.get_object(pk)
        request.data._mutable = True
        request.data.update({"last_update_by":request.user.id})
        request.data.update({"disease":None if request.data["disease"] == "0" else request.data["disease"]})
        #request.data.update({"last_update_at":timezone.now()})
        request.data.update({"patient":pk})
        if obj : 
            serializedObj= PatientInfoSerializer(obj,data=request.data)
        else :
            serializedObj= PatientInfoSerializer(data=request.data)
        if serializedObj.is_valid():
            serializedObj.save()
            last_update_at = datetime.strptime(serializedObj.data["last_update_at"], "%Y-%m-%dT%H:%M:%S.%f").strftime("%H:%M:%S.%f %Y-%m-%d")
            return Response(last_update_at,status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class PatientPaymentApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.show_patient_payment'), login_url='/main/login/'))        
    def get(self,request,patient_pk):       
        filtered_patient_visits =PatientVisit.objects.filter(patient_id=patient_pk).values('created_at','medicalservice__name','amount_required','amount_paid','amount_remaining','created_by__first_name','created_by__last_name').order_by("-created_at")
        filtered_external_payments =PatientExternalPayment.objects.filter(patient_id=patient_pk).values('created_at','amount_paid','note','created_by__first_name','created_by__last_name').order_by("-created_at")
        visits_sessions_extPayments = chain(filtered_patient_visits, filtered_external_payments) #Join Multiple Querysets From Different Base Models Django
        data_sorted = sorted(visits_sessions_extPayments, key=lambda x: x['created_at'], reverse=True)# sort list of dict by value of Key (created_at)
        data_sorted_json = [json.dumps(i,default=jsonSerializerIfDateTime) for i in data_sorted] 
        return JsonResponse({"visits_sessions_extPayments":data_sorted_json})

class PatientBalanceApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.show_patient_balance'), login_url='/main/login/'))        
    def get(self,request,patient_pk):
        pV =PatientVisit.objects.filter(patient_id=patient_pk).aggregate(total_amount_required=Sum('amount_required'),total_amount_paid=Sum('amount_paid'))
        #{'total_amount_required': 3800, 'total_amount_paid': 3250, 'total_amount_remaining': 550}
        eP =PatientExternalPayment.objects.filter(patient_id=patient_pk).aggregate(total_amount_paid=Sum('amount_paid'))
        #{'total_amount_paid': 800}
        total_amount_required_pv = pV["total_amount_required"] if pV["total_amount_required"] != None else 0
        total_amount_paid_pv = pV["total_amount_paid"] if pV["total_amount_paid"] != None else 0
        #total_amount_remaining_pv = pV["total_amount_remaining"] if pV["total_amount_remaining"] != None else 0 
        total_amount_paid_ep = eP["total_amount_paid"] if eP["total_amount_paid"] != None else 0
        total_balance = (total_amount_required_pv ) - (total_amount_paid_pv+total_amount_paid_ep)
        p = Patient.objects.get(pk=patient_pk)
        p.balance=total_balance
        p.save()
        return JsonResponse({"total_balance":total_balance})

class PtAttachmentsApi(APIView):
    #@method_decorator(user_passes_test(lambda u: u.has_perm('screen.show_pt_attachment'), login_url='/main/login/'))        
    def get(self,request,patient_pk):       
        p_attachments =PtAttachment.objects.filter(patient_id=patient_pk).order_by("-created_at")
        p_attachments_srl=PtAttachmentSerializer(p_attachments,many=True)
        return Response(p_attachments_srl.data , status=status.HTTP_201_CREATED)
    #@method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_pt_attachment'), login_url='/main/login/'))    
    def post(self,request,patient_pk):
        if not getClinicId(request) : return redirect('/main/login/')
        request.data._mutable = True
        request.data.update({"created_by":request.user.id})
        request.data.update({"patient":patient_pk})
        images = request.FILES.getlist("pa_file")
        request.data.update({"pa_file":images[0]})
        images.pop(0)
        serializedObj= PtAttachmentSerializer(data=request.data)
        if serializedObj.is_valid():
            serializedObj.save()
            if len(images) > 1:
                image_objs = []
                for img in images:
                    img_obj = {
                        "image":img,
                        "pt_attachment":serializedObj.data["id"]
                    }
                    image_objs.append(img_obj)
                attaches = ExtraPtAttachmentSerializer(data=image_objs,many=True)
                if attaches.is_valid():
                    attaches.save()
                else :return Response(attaches.errors,status=status.HTTP_400_BAD_REQUEST)
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)
class PtAttachmentApi(APIView):
    def get_object(self,pk):
        try:
            return PtAttachment.objects.get(pk=pk)
        except PtAttachment.DoesNotExist:
            return None    

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_medicalService'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        request.data._mutable = True
        request.data.update({"created_by":request.user.id})
        serializedObj= PtAttachmentUpdateSerializer(obj,data=request.data)
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

############## END Patient%Module #################

############## PatientVisit%Module #################

class CurrentVisitsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CurrentVisits'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_patient_visits =PatientVisit.objects.exclude(visit_status="4F").order_by("visit_status","-entry_datetime")
        all_patient_visits_serialized=PatientVisitSerializer(all_patient_visits,many=True)
        return render(request,"mainApp/pt_visitPages/current_visits.html",{"all_patient_visits":all_patient_visits_serialized.data,'activePage':'CurrentVisits'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_PatientVisit'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= PatientVisitSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)
class PatientDetailVisitsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_PatientVisit'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        request.data._mutable = True
        request.data.update({"visit_day":timezone.now().date()})
        request.data.update({"created_by":request.user.id})
        request.data.update({"amount_required":request.data.get("service_price")})
        request.data.update({"visit_status":"1I"})
        request.data.update({"entry_datetime":timezone.now()})
        serializedObj= PatientDetailVisitSerializer(data=request.data, context={})
        if serializedObj.is_valid():
            serializedObj.save()
            return Response((serializedObj.data)["id"],status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)
class PatientVisitApi(APIView):
    def get_object(self,pk):
        try:
            return PatientVisit.objects.get(pk=pk)
        except PatientVisit.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_PatientVisit'), login_url='/main/login/'))        
    def get(self,request,pk): 
        patient_visitObj=self.get_object(pk)
        if patient_visitObj :
            serializeobj= PatientVisitSerializer(patient_visitObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_PatientVisit'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        newStatus = request.data.get("newStatus")
        doctor_notes = request.data.get("doctor_notes")
        if newStatus == "discount_and_note" :
            doctor_discount = request.data.get("doctor_discount")
            next_consult = request.data.get("next_consult")
            ptnt = Patient.objects.get(id=obj.patient.id)
            if next_consult or int(next_consult) >= 0 :
                #obj.next_consult_days = next_consult
                todayObj = date.today()
                next_consult_day = todayObj+timedelta(days=int(next_consult))
                if next_consult_day > ptnt.next_consult :
                    ptnt.next_consult = next_consult_day
                    ptnt.save()
            # if doctor_discount and int(doctor_discount) > 0 : 
            #     obj.doctor_discount = doctor_discount
            #     ptnt.debt =ptnt.debt  - int(doctor_discount)
            if doctor_notes : obj.doctor_notes = doctor_notes
            ptnt.save()
            obj.save()
            return Response(status=status.HTTP_200_OK)
        if newStatus == "next_and_note" :
            next_consult = request.data.get("next_consult")
            ptnt = Patient.objects.get(id=obj.patient.id)
            if next_consult and int(next_consult) > 0 :
                obj.next_consult_days = next_consult
                todayObj = date.today()
                ptnt.next_consult = todayObj+timedelta(days=int(next_consult))
            if doctor_notes : obj.doctor_notes = doctor_notes
            ptnt.save()
            obj.save()
            return Response(status=status.HTTP_200_OK)
        
        #else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)          

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_PatientVisit'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

'''
class CanceledVisitsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_CanceledVisits'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        return render(request,"mainApp/pt_visitPages/canceled_visits.html",{'activePage':'CanceledVisits'})
    #@method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_PatientVisit'), login_url='/main/login/'))    
    def post(self,request):
            if not getClinicId(request) : return redirect('/main/login/')
            request.data._mutable = True
            request.data.update({"created_by":request.user.id})
            serializedObj= CanceledVisitSerializer(data=request.data)
            if serializedObj.is_valid():
                serializedObj.save()
                return Response(status=status.HTTP_201_CREATED)
            else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class FilterCanceledVisitsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_PatientVisit'), login_url='/main/login/'))    
    def post(self,request):
            if not getClinicId(request) : return redirect('/main/login/')
            data=request.data
            startDate = data["startDate"]
            endDate = data["endDate"]
            c_visits = CanceledVisit.objects.filter(created_at__gte = startDate , created_at__lte=endDate).order_by("created_at")
            serializer= CanceledVisitCustomSerializer(c_visits,many=True)
            return Response(serializer.data,status=status.HTTP_200_OK)
'''
############## END PatientVisit%Module #################

############## Prescription%Module #################

###### Drugs الأدوية########
class DrugsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Drug'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_drugs =Drug.objects.all()
        all_drugs_serialized=DrugSerializer(all_drugs,many=True)
        return render(request,"mainApp/prescriptionPages/drugs.html",{"all_drugs":all_drugs_serialized.data,'activePage':'Drugs'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_Drug'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        request.data._mutable = True
        #request.data.update({"clinic": getClinicId(request)})
        serializedObj= DrugSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data,status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class DrugApi(APIView):
    def get_object(self,pk):
        try:
            return Drug.objects.get(pk=pk)
        except Drug.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Drug'), login_url='/main/login/'))        
    def get(self,request,pk): 
        drugObj=self.get_object(pk)
        if drugObj :
            serializeobj= DrugSerializer(drugObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_Drug'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= DrugSerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_Drug'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

###### Radiologys   الأشعة########
class RadiologysApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Radiology'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_radiologys =Radiology.objects.all()
        all_radiologys_serialized=RadiologySerializer(all_radiologys,many=True)
        return render(request,"mainApp/prescriptionPages/radiologys.html",{"all_radiologys":all_radiologys_serialized.data,'activePage':'Radiologys'})
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_Radiology'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        serializedObj= RadiologySerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data,status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class RadiologyApi(APIView):
    def get_object(self,pk):
        try:
            return Radiology.objects.get(pk=pk)
        except Radiology.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Radiology'), login_url='/main/login/'))        
    def get(self,request,pk): 
        radiologyObj=self.get_object(pk)
        if radiologyObj :
            serializeobj= RadiologySerializer(radiologyObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_Radiology'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= RadiologySerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_Radiology'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

###### MedicalTests   التحاليل الطبية########
class MedicalTestsApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_MedicalTest'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_medical_tests =MedicalTest.objects.all()
        all_medical_tests_serialized=MedicalTestSerializer(all_medical_tests,many=True)
        return render(request,"mainApp/prescriptionPages/medical_tests.html",{"all_medical_tests":all_medical_tests_serialized.data,'activePage':'MedicalTests'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_MedicalTest'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        request.data._mutable = True
        #request.data.update({"clinic": getClinicId(request)})
        serializedObj= MedicalTestSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data,status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class MedicalTestApi(APIView):
    def get_object(self,pk):
        try:
            return MedicalTest.objects.get(pk=pk)
        except MedicalTest.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_MedicalTest'), login_url='/main/login/'))        
    def get(self,request,pk): 
        medical_testObj=self.get_object(pk)
        if medical_testObj :
            serializeobj= MedicalTestSerializer(medical_testObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_MedicalTest'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= MedicalTestSerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_MedicalTest'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

##### TimeTodos  توقيتات الإستخدام########
class TimeTodosApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_TimeTodo'), login_url='/main/login/'))
    def get(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        all_time_todos =TimeTodo.objects.all()
        all_time_todos_serialized=TimeTodoSerializer(all_time_todos,many=True)
        return render(request,"mainApp/prescriptionPages/time_todos.html",{"all_time_todos":all_time_todos_serialized.data,'activePage':'TimeTodos'})
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.add_TimeTodo'), login_url='/main/login/'))    
    def post(self,request):
        if not getClinicId(request) : return redirect('/main/login/')
        request.data._mutable = True
        #request.data.update({"clinic": getClinicId(request)})
        serializedObj= TimeTodoSerializer(data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data,status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

class TimeTodoApi(APIView):
    def get_object(self,pk):
        try:
            return TimeTodo.objects.get(pk=pk)
        except TimeTodo.DoesNotExist:
            return None    
    
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_TimeTodo'), login_url='/main/login/'))        
    def get(self,request,pk): 
        time_todoObj=self.get_object(pk)
        if time_todoObj :
            serializeobj= TimeTodoSerializer(time_todoObj)
            return Response(serializeobj.data,status=status.HTTP_200_OK)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.edit_TimeTodo'), login_url='/main/login/'))
    def put(self,request,pk):
        obj=self.get_object(pk)
        serializedObj= TimeTodoSerializer(obj,data=request.data)
        #list_error=""
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(status=status.HTTP_200_OK)
        else : return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_TimeTodo'), login_url='/main/login/'))
    def delete(self,request,pk):
        obj=self.get_object(pk)
        if obj :
            try:
                obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

###### PrescriptionApi  ########
class PrescriptionApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.view_Prescription'), login_url='/main/login/'))
    def get(self,request,visit_id):
        context={'activePage':'PatientVisits'}
        try : 
            patientVisitObj = PatientVisit.objects.get(pk=visit_id)
        except PatientVisit.DoesNotExist:
            return redirect("mainApp:PatientsApi")  
        context.update({"pV":patientVisitObj})
        patient=Patient.objects.get(pk=patientVisitObj.patient.pk)
        context.update({"patient":patient})
        #all data from tables 
        all_time_todos = TimeTodo.objects.all()
        context.update({"all_time_todos":all_time_todos})
        all_drugs = Drug.objects.all()
        all_drugs_srlzd=DrugMiniSerializer(all_drugs,many=True)
        context.update({"all_drugs":all_drugs_srlzd.data})
        all_medical_tests = MedicalTest.objects.all()
        context.update({"all_medical_tests":all_medical_tests})
        all_radiologys = Radiology.objects.all()
        context.update({"all_radiologys":all_radiologys})
        #user prescription items 
        presDrugItems=PresDrugItem.objects.filter(patient_visit=patientVisitObj)
        presDrugItems_serialized=PresDrugItemSerializer(presDrugItems,many=True)
        context.update({"presDrugItems":presDrugItems_serialized.data})
        presRadiologyItems=PresRadiologyItem.objects.filter(patient_visit=patientVisitObj)
        presRadiologyItems_serialized=PresRadiologyItemSerializer(presRadiologyItems,many=True)
        context.update({"presRadiologyItems":presRadiologyItems_serialized.data})
        presTestItems=PresTestItem.objects.filter(patient_visit=patientVisitObj)
        presTestItems_serialized=PresTestItemSerializer(presTestItems,many=True)
        context.update({"presTestItems":presTestItems_serialized.data})
        return render(request,"mainApp/prescriptionPages/prescription_pv.html",context)

    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.Add_Prescription_Item'), login_url='/main/login/'))
    def post(self,request,visit_id):
        request.data._mutable = True
        request.data.update({"patient_visit":visit_id})
        item_type=request.data.get("item_type")
        if item_type == "1D" : serializedObj= PresDrugItemSerializer(data=request.data)
        elif item_type == "2T" :  serializedObj= PresTestItemSerializer(data=request.data)
        elif item_type == "3R" : serializedObj= PresRadiologyItemSerializer(data=request.data)
        else :return Response({},status=status.HTTP_400_BAD_REQUEST)
        if serializedObj.is_valid():
            serializedObj.save()
            return Response(serializedObj.data,status=status.HTTP_201_CREATED)
        else :return Response(serializedObj.errors,status=status.HTTP_400_BAD_REQUEST)

###### PrescriptionApi  ########
class PrescriptionItemApi(APIView):
    @method_decorator(user_passes_test(lambda u: u.has_perm('screen.delete_Prescription_Item'), login_url='/main/login/'))
    def delete(self,request,item_pk):
        item_type=request.data.get("item_type")
        if item_type == "Drug" : itemObj = PresDrugItem.objects.get(pk=item_pk)
        elif item_type == "Test" :  itemObj = PresTestItem.objects.get(pk=item_pk)
        elif item_type == "Radiology" : itemObj = PresRadiologyItem.objects.get(pk=item_pk)
        else : itemObj = None
        if itemObj :
            try:
                itemObj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            except Exception as err_msg: 
                    return Response(data ="{}".format(str(err_msg)),status=status.HTTP_405_METHOD_NOT_ALLOWED)
        else : return Response(status=status.HTTP_404_NOT_FOUND)

############## END Prescription%Module #################

###### {Pres}   ########
class PresApi(APIView):
    def get(self,request):
        return render(request,"mainApp/pres2.html",)

###### {CompanyRptApi}   ########
class CompanyRptApi(APIView):
    def get(self,request):
        all_PatientVisit = PatientVisit.objects.all()
        return render(request,"mainApp/company_rpt.html",{"all_PatientVisit":all_PatientVisit})



# ###### DrugUsages    الجرعات########










