import base64
import io
import os
from PIL import Image
from rest_framework import generics
from rm_gallery.models import *
from rm_gallery.serializer import *
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import pagination
from rest_framework import filters as searchfilter
from django_filters import rest_framework as filters
from rest_framework.response import Response
from django.db.models import Q
from django.core.files.uploadedfile import InMemoryUploadedFile
from rest_framework.exceptions import NotFound

from rm_gallery_api.settings import MEDIA_ROOT

class StandardSetPagination(pagination.PageNumberPagination):
    page_size = 20 # default amount records in current page
    page_size_query_param = 'page_size'
    max_page_size = 1000 # max number of records in current page by using query param above

class StandardItemSetPagination(pagination.PageNumberPagination):
    page_size = 20 # default amount records in current page
    page_size_query_param = 'page_size'
    max_page_size = 1000 # max number of records in current page by using query param above

    def getBrandList(self,brandDistinct,languageId):
        brandList = []
        for i in brandDistinct:
            currentBrand = Brand.objects.filter(id = i['brandId'])
            brandList.append(BrandSerializer(currentBrand[0],context={'languageId':languageId}).data)
        return brandList
    
    def getDepartmentList(self,departmentDistinct,languageId):
        departmentList = []
        for i in departmentDistinct:
            currentDepartment = Department.objects.filter(id = i['departmentId'])
            departmentList.append(DepartmentSerializer(currentDepartment[0],context={'languageId':languageId}).data)
        return departmentList

    def getNewArrivalFilter(self,newArrivalIdVal,search):
        if search is not None:
            priceVals = Item.objects.filter(isApproved=True).filter(newArrivalId = newArrivalIdVal).filter(item_itemlanguage__name__icontains=search).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(newArrivalId = newArrivalIdVal).filter(item_itemlanguage__name__icontains=search).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(newArrivalId = newArrivalIdVal).filter(item_itemlanguage__name__icontains=search).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(newArrivalId = newArrivalIdVal).filter(item_itemlanguage__name__icontains=search).values('departmentId').distinct()
        else:
            priceVals = Item.objects.filter(isApproved=True).filter(newArrivalId = newArrivalIdVal).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(newArrivalId = newArrivalIdVal).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(newArrivalId = newArrivalIdVal).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(newArrivalId = newArrivalIdVal).values('departmentId').distinct()
        
        if not priceVals['min_price']:
            priceVals['min_price']=0
        if not priceVals['max_price']:
            priceVals['max_price']=1

        if priceVals['min_price'] > 0 and priceVals['max_price'] > 0:
            if priceVals['min_price'] == priceVals['max_price']:
                priceVals['min_price'] = 1
        
        if not discountVals['min_discount']:
            discountVals['min_discount']=0
        if not discountVals['max_discount']:
            discountVals['max_discount']=1
        
        if discountVals['min_discount'] > 0 and discountVals['max_discount'] > 0:
            if discountVals['min_discount'] == discountVals['max_discount']:
                discountVals['min_discount'] = 1
        
        brandList = []
        for brand in brandDistinct:
            brandList.append({'id':brand['brandId']})
        
        departmentList = []
        for department in departmentDistinct:
            departmentList.append({'id':department['departmentId']})
        return priceVals,discountVals,brandList,departmentList

    def getIsTopFilter(self,isTopVal,search):
            if(str(isTopVal) == 'true'):
                if search is not None:
                    priceVals = Item.objects.filter(isApproved=True).filter(isTop = True).filter(item_itemlanguage__name__icontains=search).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
                    discountVals = Item.objects.filter(isApproved=True).filter(isTop = True).filter(item_itemlanguage__name__icontains=search).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
                    brandDistinct = Item.objects.filter(isApproved=True).filter(isTop = True).filter(item_itemlanguage__name__icontains=search).values('brandId').distinct()
                    departmentDistinct = Item.objects.filter(isApproved=True).filter(isTop = True).filter(item_itemlanguage__name__icontains=search).values('departmentId').distinct()
                else:
                    priceVals = Item.objects.filter(isApproved=True).filter(isTop = True).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
                    discountVals = Item.objects.filter(isApproved=True).filter(isTop = True).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
                    brandDistinct = Item.objects.filter(isApproved=True).filter(isTop = True).values('brandId').distinct()
                    departmentDistinct = Item.objects.filter(isApproved=True).filter(isTop = True).values('departmentId').distinct()
                
                if not priceVals['min_price']:
                    priceVals['min_price']=0
                if not priceVals['max_price']:
                    priceVals['max_price']=1

                if priceVals['min_price'] > 0 and priceVals['max_price'] > 0:
                    if priceVals['min_price'] == priceVals['max_price']:
                        priceVals['min_price'] = 1
                
                if not discountVals['min_discount']:
                    discountVals['min_discount']=0
                if not discountVals['max_discount']:
                    discountVals['max_discount']=1
                
                if discountVals['min_discount'] > 0 and discountVals['max_discount'] > 0:
                    if discountVals['min_discount'] == discountVals['max_discount']:
                        discountVals['min_discount'] = 1
                
                brandList = []
                for brand in brandDistinct:
                    brandList.append({'id':brand['brandId']})
                
                departmentList = []
                for department in departmentDistinct:
                    departmentList.append({'id':department['departmentId']})

                return priceVals,discountVals,brandList,departmentList
    
    def getIsFavoriteFilter(self,isFavoriteVal,search):
            if(str(isFavoriteVal) == 'true'):
                if search is not None:
                    priceVals = Item.objects.filter(isApproved=True).filter(isFavorite = True).filter(item_itemlanguage__name__icontains=search).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
                    discountVals = Item.objects.filter(isApproved=True).filter(isFavorite = True).filter(item_itemlanguage__name__icontains=search).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
                    brandDistinct = Item.objects.filter(isApproved=True).filter(isFavorite = True).filter(item_itemlanguage__name__icontains=search).values('brandId').distinct()
                    departmentDistinct = Item.objects.filter(isApproved=True).filter(isFavorite = True).filter(item_itemlanguage__name__icontains=search).values('departmentId').distinct()
                else:
                    priceVals = Item.objects.filter(isApproved=True).filter(isFavorite = True).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
                    discountVals = Item.objects.filter(isApproved=True).filter(isFavorite = True).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
                    brandDistinct = Item.objects.filter(isApproved=True).filter(isFavorite = True).values('brandId').distinct()
                    departmentDistinct = Item.objects.filter(isApproved=True).filter(isFavorite = True).values('departmentId').distinct()

                if not priceVals['min_price']:
                    priceVals['min_price']=0
                if not priceVals['max_price']:
                    priceVals['max_price']=1

                if priceVals['min_price'] > 0 and priceVals['max_price'] > 0:
                    if priceVals['min_price'] == priceVals['max_price']:
                        priceVals['min_price'] = 1
                
                if not discountVals['min_discount']:
                    discountVals['min_discount']=0
                if not discountVals['max_discount']:
                    discountVals['max_discount']=1
                
                if discountVals['min_discount'] > 0 and discountVals['max_discount'] > 0:
                    if discountVals['min_discount'] == discountVals['max_discount']:
                        discountVals['min_discount'] = 1

                brandList = []
                for brand in brandDistinct:
                    brandList.append({'id':brand['brandId']})
                
                departmentList = []
                for department in departmentDistinct:
                    departmentList.append({'id':department['departmentId']})

                return priceVals,discountVals,brandList,departmentList

    def getMostDiscountFilter(self,search):
        if search is not None:
            priceVals = Item.objects.filter(isApproved=True).filter(item_sku__discount__gt=0).filter(item_itemlanguage__name__icontains=search).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(item_sku__discount__gt=0).filter(item_itemlanguage__name__icontains=search).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(item_sku__discount__gt=0).filter(item_itemlanguage__name__icontains=search).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(item_sku__discount__gt=0).filter(item_itemlanguage__name__icontains=search).values('departmentId').distinct()
        else:    
            priceVals = Item.objects.filter(isApproved=True).filter(item_sku__discount__gt=0).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(item_sku__discount__gt=0).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(item_sku__discount__gt=0).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(item_sku__discount__gt=0).values('departmentId').distinct()
            
        if not priceVals['min_price']:
            priceVals['min_price']=0
        if not priceVals['max_price']:
            priceVals['max_price']=1

        if priceVals['min_price'] > 0 and priceVals['max_price'] > 0:
            if priceVals['min_price'] == priceVals['max_price']:
                priceVals['min_price'] = 1

        if not discountVals['min_discount']:
            discountVals['min_discount']=0
        if not discountVals['max_discount']:
            discountVals['max_discount']=1
                
        if discountVals['min_discount'] > 0 and discountVals['max_discount'] > 0:
            if discountVals['min_discount'] == discountVals['max_discount']:
                discountVals['min_discount'] = 1

        brandList = []
        for brand in brandDistinct:
            brandList.append({'id':brand['brandId']})
        
        departmentList = []
        for department in departmentDistinct:
            departmentList.append({'id':department['departmentId']})

        return priceVals,discountVals,brandList,departmentList
    
    def getDepartmentFilter(self,departmentIdVal,search):
        if search is not None:
            priceVals = Item.objects.filter(isApproved=True).filter(departmentId = departmentIdVal).filter(item_itemlanguage__name__icontains=search).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(departmentId = departmentIdVal).filter(item_itemlanguage__name__icontains=search).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(departmentId = departmentIdVal).filter(item_itemlanguage__name__icontains=search).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(departmentId = departmentIdVal).filter(item_itemlanguage__name__icontains=search).values('departmentId').distinct()

        else:
            priceVals = Item.objects.filter(isApproved=True).filter(departmentId = departmentIdVal).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(departmentId = departmentIdVal).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(departmentId = departmentIdVal).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(departmentId = departmentIdVal).values('departmentId').distinct()

        if not priceVals['min_price']:
            priceVals['min_price']=0
        if not priceVals['max_price']:
            priceVals['max_price']=1

        if priceVals['min_price'] > 0 and priceVals['max_price'] > 0:
            if priceVals['min_price'] == priceVals['max_price']:
                priceVals['min_price'] = 1
        
        if not discountVals['min_discount']:
            discountVals['min_discount']=0
        if not discountVals['max_discount']:
            discountVals['max_discount']=1
        
        if discountVals['min_discount'] > 0 and discountVals['max_discount'] > 0:
            if discountVals['min_discount'] == discountVals['max_discount']:
                discountVals['min_discount'] = 1

        brandList = []
        for brand in brandDistinct:
            brandList.append({'id':brand['brandId']})
        
        departmentList = []
        for department in departmentDistinct:
            departmentList.append({'id':department['departmentId']})

        return priceVals,discountVals,brandList,departmentList

    def getSupplierFilter(self,supplierIdVal,search):
        if search is not None:
            priceVals = Item.objects.filter(isApproved=True).filter(supplierId = supplierIdVal).filter(item_itemlanguage__name__icontains=search).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(supplierId = supplierIdVal).filter(item_itemlanguage__name__icontains=search).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(supplierId = supplierIdVal).filter(item_itemlanguage__name__icontains=search).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(supplierId = supplierIdVal).filter(item_itemlanguage__name__icontains=search).values('departmentId').distinct()

        else:
            priceVals = Item.objects.filter(isApproved=True).filter(supplierId = supplierIdVal).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(supplierId = supplierIdVal).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(supplierId = supplierIdVal).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(supplierId = supplierIdVal).values('departmentId').distinct()

        if not priceVals['min_price']:
            priceVals['min_price']=0
        if not priceVals['max_price']:
            priceVals['max_price']=1

        if priceVals['min_price'] > 0 and priceVals['max_price'] > 0:
            if priceVals['min_price'] == priceVals['max_price']:
                priceVals['min_price'] = 1
        
        if not discountVals['min_discount']:
            discountVals['min_discount']=0
        if not discountVals['max_discount']:
            discountVals['max_discount']=1
        
        if discountVals['min_discount'] > 0 and discountVals['max_discount'] > 0:
            if discountVals['min_discount'] == discountVals['max_discount']:
                discountVals['min_discount'] = 1

        brandList = []
        for brand in brandDistinct:
            brandList.append({'id':brand['brandId']})
        
        departmentList = []
        for department in departmentDistinct:
            departmentList.append({'id':department['departmentId']})

        return priceVals,discountVals,brandList,departmentList

    def getBrandFilter(self,brandIdVal,search):
        if search is not None:
            priceVals = Item.objects.filter(isApproved=True).filter(brandId = brandIdVal).filter(item_itemlanguage__name__icontains=search).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(brandId = brandIdVal).filter(item_itemlanguage__name__icontains=search).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(brandId = brandIdVal).filter(item_itemlanguage__name__icontains=search).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(brandId = brandIdVal).filter(item_itemlanguage__name__icontains=search).values('departmentId').distinct()

        else:
            priceVals = Item.objects.filter(isApproved=True).filter(brandId = brandIdVal).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(brandId = brandIdVal).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(brandId = brandIdVal).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(brandId = brandIdVal).values('departmentId').distinct()

        if not priceVals['min_price']:
            priceVals['min_price']=0
        if not priceVals['max_price']:
            priceVals['max_price']=1

        if priceVals['min_price'] > 0 and priceVals['max_price'] > 0:
            if priceVals['min_price'] == priceVals['max_price']:
                priceVals['min_price'] = 1
        
        if not discountVals['min_discount']:
            discountVals['min_discount']=0
        if not discountVals['max_discount']:
            discountVals['max_discount']=1
        
        if discountVals['min_discount'] > 0 and discountVals['max_discount'] > 0:
            if discountVals['min_discount'] == discountVals['max_discount']:
                discountVals['min_discount'] = 1

        brandList = []
        for brand in brandDistinct:
            brandList.append({'id':brand['brandId']})
        
        departmentList = []
        for department in departmentDistinct:
            departmentList.append({'id':department['departmentId']})

        return priceVals,discountVals,brandList,departmentList

    def getStandardFilter(self,search):
        if search is not None:
            priceVals = Item.objects.filter(isApproved=True).filter(item_itemlanguage__name__icontains=search).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.filter(isApproved=True).filter(item_itemlanguage__name__icontains=search).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.filter(isApproved=True).filter(item_itemlanguage__name__icontains=search).values('brandId').distinct()
            departmentDistinct = Item.objects.filter(isApproved=True).filter(item_itemlanguage__name__icontains=search).values('departmentId').distinct()
        else:    
            priceVals = Item.objects.all().filter(isApproved=True).aggregate(min_price=Min('item_sku__price'), max_price=Max('item_sku__price'))
            discountVals = Item.objects.all().filter(isApproved=True).aggregate(min_discount=Min('item_sku__discount'), max_discount=Max('item_sku__discount'))
            brandDistinct = Item.objects.all().filter(isApproved=True).values('brandId').distinct()
            departmentDistinct = Item.objects.all().filter(isApproved=True).values('departmentId').distinct()

        if priceVals is not None:
            if not priceVals['min_price']:
                priceVals['min_price']=0
            if not priceVals['max_price']:
                priceVals['max_price']=1
            
            if priceVals['min_price'] > 0 and priceVals['max_price'] > 0:
                if priceVals['min_price'] == priceVals['max_price']:
                    priceVals['min_price'] = 1
        
        if discountVals is not None:
            if not discountVals['min_discount']:
                discountVals['min_discount']=0
            if not discountVals['max_discount']:
                discountVals['max_discount']=1
        
            if discountVals['min_discount'] > 0 and discountVals['max_discount'] > 0:
                if discountVals['min_discount'] == discountVals['max_discount']:
                    discountVals['min_discount'] = 1

        brandList = []
        for brand in brandDistinct:
            brandList.append({'id':brand['brandId']})
        
        departmentList = []
        for department in departmentDistinct:
            departmentList.append({'id':department['departmentId']})

        return priceVals,discountVals,brandList,departmentList

    def get_paginated_response(self, data):
        search = self.request.query_params.get('search',None)

        newArrivalIdVal = self.request.query_params.get('newArrivalId',None)
        isTopVal = self.request.query_params.get('isTop',None)
        isFavoriteVal = self.request.query_params.get('isFavorite',None)
        isDiscount = self.request.query_params.get('isDiscount',None)
        departmentIdVal = self.request.query_params.get('departmentId',None)
        supplierIdVal = self.request.query_params.get('supplierId',None)
        brandIdVal = self.request.query_params.get('brandId',None)
        
        priceVals = None
        discountVals = None
        filterBrandList = []
        filterDepartmentList = []
        if (newArrivalIdVal is not None):
            priceVals,discountVals,filterBrandList,filterDepartmentList = self.getNewArrivalFilter(newArrivalIdVal,search)
        elif(isTopVal is not None):
            priceVals,discountVals,filterBrandList,filterDepartmentList = self.getIsTopFilter(isTopVal,search)
        elif(isFavoriteVal is not None):
            priceVals,discountVals,filterBrandList,filterDepartmentList = self.getIsFavoriteFilter(isFavoriteVal,search)
        elif(isDiscount is not None):
            if isDiscount == '1' or (isDiscount == 'True' or isDiscount == 'true'):
                priceVals,discountVals,filterBrandList,filterDepartmentList = self.getMostDiscountFilter(search)
        elif(departmentIdVal is not None):
            priceVals,discountVals,filterBrandList,filterDepartmentList = self.getDepartmentFilter(departmentIdVal,search)
        elif(supplierIdVal is not None):
            priceVals,discountVals,filterBrandList,filterDepartmentList = self.getSupplierFilter(supplierIdVal,search)
        elif(brandIdVal is not None):
            priceVals,discountVals,filterBrandList,filterDepartmentList = self.getBrandFilter(brandIdVal,search)
        else:
            priceVals,discountVals,filterBrandList,filterDepartmentList = self.getStandardFilter(search)

        if(priceVals is not None):
            return Response({
                'count': self.page.paginator.count,
                'next': self.get_next_link(),
                'previous': self.get_previous_link(),
                "minPrice": priceVals['min_price'],
                "maxPrice": priceVals['max_price'],
                "minDiscount": discountVals['min_discount'],
                "maxDiscount": discountVals['max_discount'],
                'brandList':filterBrandList,
                'departmentList':filterDepartmentList,
                'results': data,
            })
        
        return Response({
                'count': self.page.paginator.count,
                'next': self.get_next_link(),
                'previous': self.get_previous_link(),
                'results': data,
            })

class StandardSKUSetPagination(pagination.PageNumberPagination):
    page_size = 20 # default amount records in current page
    page_size_query_param = 'page_size'
    max_page_size = 1000 # max number of records in current page by using query param above

    def get_paginated_response(self, data):
        priceVals = SKU.objects.filter().aggregate(min_price=Min('price'), max_price=Max('price'))
        discountVals = SKU.objects.filter().aggregate(min_discount=Min('discount'), max_discount=Max('discount'))

        if priceVals is not None:
            if not priceVals['min_price']:
                priceVals['min_price']=0
            if not priceVals['max_price']:
                priceVals['max_price']=1
            
            if priceVals['min_price'] > 0 and priceVals['max_price'] > 0:
                if priceVals['min_price'] == priceVals['max_price']:
                    priceVals['min_price'] = 1
        
        if discountVals is not None:
            if not discountVals['min_discount']:
                discountVals['min_discount']=0
            if not discountVals['max_discount']:
                discountVals['max_discount']=1
        
            if discountVals['min_discount'] > 0 and discountVals['max_discount'] > 0:
                if discountVals['min_discount'] == discountVals['max_discount']:
                    discountVals['min_discount'] = 1

        if(priceVals is not None):
            return Response({
                'count': self.page.paginator.count,
                'next': self.get_next_link(),
                'previous': self.get_previous_link(),
                "minPrice": priceVals['min_price'],
                "maxPrice": priceVals['max_price'],
                "minDiscount": discountVals['min_discount'],
                "maxDiscount": discountVals['max_discount'],
                'results': data,
            })
        
        return Response({
                'count': self.page.paginator.count,
                'next': self.get_next_link(),
                'previous': self.get_previous_link(),
                'results': data,
            })    

class DashboardDataView(generics.ListAPIView):
    serializer_class = DashboardDataSerializer

    def calculateTaxes(self):
        # results = [
        #     myRecharge 
        #     for myRecharge in Recharge.objects.all()
        #     if myRecharge.getTaxesIsPaid == 0
        # ]
        # for r in results:
        #     print(r.id)
        
        sumTaxes = 0
        rechargeList = Recharge.objects.filter(~Q(id__in = Payment.objects.filter(taxesId__gt = 0).filter(rechargeId__gt = 0).exclude(rechargeId = None).values('rechargeId')))
        for selected in rechargeList:
            serializer = RechargeSerializer(selected).data
            sumTaxes = sumTaxes + serializer['sumTaxes']

        purchaseOrderList = PurchaseOrder.objects.filter(~Q(id__in = Payment.objects.filter(taxesId__gt = 0).filter(purchaseOrderId__gt = 0).exclude(purchaseOrderId = None).values('purchaseOrderId')))
        for selected in purchaseOrderList:
            serializer = PurchaseOrderSerializer(selected).data
            sumTaxes = sumTaxes + serializer['taxes']
        
        return sumTaxes

    def getDashboardData(self):
        
        countItems = Item.objects.count()
        sumPaymentTotal = Payment.objects.aggregate(Sum('total'))

        if sumPaymentTotal['total__sum'] is None:
            sumPaymentTotal['total__sum'] = 0

        sumPaymentPaid= Payment.objects.aggregate(Sum('paid'))

        if sumPaymentPaid['paid__sum'] is None:
            sumPaymentPaid['paid__sum'] = 0

        sumPaymentChange = Payment.objects.aggregate(Sum('change'))

        if sumPaymentChange['change__sum'] is None:
            sumPaymentChange['change__sum'] = 0

        inTrans = TransactionType.objects.filter(keyName__icontains='InTrans')
        outTrans = TransactionType.objects.filter(keyName__icontains='OutTrans')
        countTransactionIn = 0
        sumTransactionInTotal = 0
        sumTransactionInPaid = 0
        countTransactionOut = 0
        sumTransactionOutTotal = 0
        sumTransactionOutPaid = 0
        if inTrans.__len__() > 0:
            countTransactionIn = Payment.objects.filter(transactionTypeId = inTrans[0].id).count()
            sumTransactionInTotal = Payment.objects.filter(transactionTypeId = inTrans[0].id).aggregate(Sum('total'))

            if sumTransactionInTotal['total__sum'] is None:
                sumTransactionInTotal['total__sum'] = 0

            sumTransactionInPaid = Payment.objects.filter(transactionTypeId = inTrans[0].id).aggregate(Sum('paid'))
            
            if sumTransactionInPaid['paid__sum'] is None:
                sumTransactionInPaid['paid__sum'] = 0

        if outTrans.__len__() > 0:
            countTransactionOut = Payment.objects.filter(transactionTypeId = outTrans[0].id).count()
            sumTransactionOutTotal = Payment.objects.filter(transactionTypeId = outTrans[0].id).aggregate(Sum('total'))

            if sumTransactionOutTotal['total__sum'] is None:
                sumTransactionOutTotal['total__sum'] = 0

            sumTransactionOutPaid = Payment.objects.filter(transactionTypeId = outTrans[0].id).aggregate(Sum('paid'))

            if sumTransactionOutPaid['paid__sum'] is None:
                sumTransactionOutPaid['paid__sum'] = 0
        
        sumTotalIn = sumTransactionInTotal['total__sum']
        sumPaidIn = sumTransactionInPaid['paid__sum']

        sumTotalOut = sumTransactionOutTotal['total__sum']
        sumPaidOut = sumTransactionOutPaid['paid__sum']
        
        balanceTotal = sumTotalIn - sumTotalOut
        balancePaid = sumPaidIn - sumPaidOut

        sumTaxes = self.calculateTaxes()

        dashboardData = DashboardData(
            countItems,
            sumPaymentTotal['total__sum'],
            sumPaymentPaid['paid__sum'],
            sumPaymentChange['change__sum'],
            countTransactionIn,
            sumTransactionInTotal['total__sum'],
            sumTransactionInPaid['paid__sum'],
            countTransactionOut,
            sumTransactionOutTotal['total__sum'],
            sumTransactionOutPaid['paid__sum'],
            balanceTotal,
            balancePaid,
            sumTaxes,
            )
        return [
            dashboardData
        ]

    def getSupplierDashboardData(self,supplierId):
        countItems = Item.objects.filter(supplierId=supplierId).count()
        sumPaymentTotal = Payment.objects.filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).aggregate(Sum('total'))

        if sumPaymentTotal['total__sum'] is None:
            sumPaymentTotal['total__sum'] = 0

        sumPaymentPaid= Payment.objects.filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).aggregate(Sum('paid'))

        if sumPaymentPaid['paid__sum'] is None:
            sumPaymentPaid['paid__sum'] = 0

        sumPaymentChange = Payment.objects.filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).aggregate(Sum('change'))

        if sumPaymentChange['change__sum'] is None:
            sumPaymentChange['change__sum'] = 0

        inTrans = TransactionType.objects.filter(keyName__icontains='InTrans')
        outTrans = TransactionType.objects.filter(keyName__icontains='OutTrans')
        countTransactionIn = 0
        sumTransactionInTotal = 0
        sumTransactionInPaid = 0
        countTransactionOut = 0
        sumTransactionOutTotal = 0
        sumTransactionOutPaid = 0
        if inTrans.__len__() > 0:
            countTransactionIn = Payment.objects.filter(transactionTypeId = inTrans[0].id).filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).count()
            sumTransactionInTotal = Payment.objects.filter(transactionTypeId = inTrans[0].id).filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).aggregate(Sum('total'))

            if sumTransactionInTotal['total__sum'] is None:
                sumTransactionInTotal['total__sum'] = 0

            sumTransactionInPaid = Payment.objects.filter(transactionTypeId = inTrans[0].id).filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).aggregate(Sum('paid'))
            
            if sumTransactionInPaid['paid__sum'] is None:
                sumTransactionInPaid['paid__sum'] = 0

        if outTrans.__len__() > 0:
            countTransactionOut = Payment.objects.filter(transactionTypeId = outTrans[0].id).filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).count()
            sumTransactionOutTotal = Payment.objects.filter(transactionTypeId = outTrans[0].id).filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).aggregate(Sum('total'))

            if sumTransactionOutTotal['total__sum'] is None:
                sumTransactionOutTotal['total__sum'] = 0

            sumTransactionOutPaid = Payment.objects.filter(transactionTypeId = outTrans[0].id).filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).aggregate(Sum('paid'))

            if sumTransactionOutPaid['paid__sum'] is None:
                sumTransactionOutPaid['paid__sum'] = 0
    
        dashboardData = DashboardData(
            countItems,
            sumPaymentTotal['total__sum'],
            sumPaymentPaid['paid__sum'],
            sumPaymentChange['change__sum'],
            countTransactionOut,
            sumTransactionOutTotal['total__sum'],
            sumTransactionOutPaid['paid__sum'],
            countTransactionIn,
            sumTransactionInTotal['total__sum'],
            sumTransactionInPaid['paid__sum'],
            0,
            0,
            0
            )
        return [
            dashboardData
        ]

    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        supplierId = self.request.query_params.get('supplierId')
        if isDashboard is not None and supplierId is not None:
            raise NotFound({"Error":"Invalid Parameters"})
        elif isDashboard is not None:
            if int(isDashboard) == 1:
                return self.getDashboardData()
            else:
                raise NotFound({"Error":"Invalid Parameters"})
        elif supplierId is not None:
            if int(supplierId) > 0:
                return self.getSupplierDashboardData(supplierId)
            else:
                raise NotFound({"Error":"Invalid Parameters"})
        else:
            raise NotFound({"Error":"Invalid Parameters"})

class SettingsList(generics.ListCreateAPIView):
    queryset = Settings.objects.all()
    serializer_class = SettingsSerializer

class SettingsDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Settings.objects.all()
    serializer_class = SettingsSerializer

class LanguageList(generics.ListCreateAPIView):
    serializer_class = LanguageSerializer
    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return Language.objects.all()
        else:
            return Language.objects.filter(isEnabled = True)

class LanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Language.objects.all()
    serializer_class = LanguageSerializer

class AppContentList(generics.ListCreateAPIView):
    queryset = AppContent.objects.all()
    serializer_class = AppContentSerializer

    def perform_create(self, serializer, format=None):
        imageBase64 = self.request.data.get('imageBase64')
        if(imageBase64 is not None):
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            keyName = self.request.data.get('keyName')
            description = self.request.data.get('description')
            navigateTo = self.request.data.get('navigateTo')
            isSliderFlag = self.request.data.get('isSliderFlag')
            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')

            serializer.save(
                keyName = keyName,
                description = description,
                navigateTo = navigateTo,
                isSliderFlag = isSliderFlag,
                image=newImage,
                createdDate=newCreatedDate,
                updatedDate=newUpdatedDate)
        else:
            serializer.save()

class AppContentDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = AppContent.objects.all()
    serializer_class = AppContentSerializer

    def perform_update(self, serializer, format=None):
        imageBase64 = self.request.data.get('imageBase64')
        if(imageBase64 is not None):
            oldImageName = self.request.data.get('oldImageName')
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            id = self.request.data.get('id')
            if(oldImageName is not None):
                if(oldImageName != 'holder'):
                    if os.path.exists(MEDIA_ROOT+'/appcontents/appcontent_'+str(id)+'/'+oldImageName+'.'+imageExtension):
                        os.remove(MEDIA_ROOT+'/appcontents/appcontent_'+str(id)+'/'+oldImageName+'.'+imageExtension)

            keyName = self.request.data.get('keyName')
            description = self.request.data.get('description')
            navigateTo = self.request.data.get('navigateTo')
            isSliderFlag = self.request.data.get('isSliderFlag')
            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')

            serializer.save(
                    keyName = keyName,
                    description = description,
                    navigateTo = navigateTo,
                    isSliderFlag = isSliderFlag,
                    image=newImage,
                    createdDate=newCreatedDate,
                    updatedDate=newUpdatedDate)
        else:
            serializer.save()

class SocialLinkList(generics.ListCreateAPIView):
    queryset = SocialLink.objects.all()
    serializer_class = SocialLinkSerializer

class SocialLinkDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SocialLink.objects.all()
    serializer_class = SocialLinkSerializer

class ProviderList(generics.ListCreateAPIView):
    queryset = Provider.objects.all()
    serializer_class = ProviderSerializer

class ProviderDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Provider.objects.all()
    serializer_class = ProviderSerializer

class ProviderLanguageList(generics.ListCreateAPIView):
    queryset = ProviderLanguage.objects.all()
    serializer_class = ProviderLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['providerId','languageId']

class ProviderLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ProviderLanguage.objects.all()
    serializer_class = ProviderLanguageSerializer

class ItemCostList(generics.ListCreateAPIView):
    queryset = ItemCost.objects.all()
    serializer_class = ItemCostSerializer
    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return ItemCost.objects.all()
        else:
            return ItemCost.objects.filter(isEnabled = True)

class ItemCostDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ItemCost.objects.all()
    serializer_class = ItemCostSerializer

class FeesList(generics.ListCreateAPIView):
    serializer_class = FeesSerializer
    
    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return Fees.objects.all().order_by('-id')
        else:
            return Fees.objects.all().filter(isEnabled = True)[:1]

class FeesDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Fees.objects.all()
    serializer_class = FeesSerializer

class TaxesList(generics.ListCreateAPIView):
    serializer_class = TaxesSerializer
    
    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return Taxes.objects.all().order_by('-price')
        else:
            return Taxes.objects.all().order_by('-price')[:1]

class TaxesDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Taxes.objects.all()
    serializer_class = TaxesSerializer

class OrderFromList(generics.ListCreateAPIView):
    queryset = OrderFrom.objects.all()
    serializer_class = OrderFromSerializer

class OrderFromDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = OrderFrom.objects.all()
    serializer_class = OrderFromSerializer

class OrderFromLanguageList(generics.ListCreateAPIView):
    queryset = OrderFromLanguage.objects.all()
    serializer_class = OrderFromLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['orderFromId','languageId']

class OrderFromLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = OrderFromLanguage.objects.all()
    serializer_class = OrderFromLanguageSerializer

class CancelTypeList(generics.ListCreateAPIView):
    queryset = CancelType.objects.all()
    serializer_class = CancelTypeSerializer

class CancelTypeDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = CancelType.objects.all()
    serializer_class = CancelTypeSerializer

class CancelTypeLanguageList(generics.ListCreateAPIView):
    queryset = CancelTypeLanguage.objects.all()
    serializer_class = CancelTypeLanguageSerializer

class CancelTypeLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = CancelTypeLanguage.objects.all()
    serializer_class = CancelTypeLanguageSerializer

class ReturnCostList(generics.ListCreateAPIView):
    serializer_class = ReturnCostSerializer
    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return ReturnCost.objects.all().order_by('-cost')
        else:
            return ReturnCost.objects.all().order_by('-cost')[:1]

class ReturnCostDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ReturnCost.objects.all()
    serializer_class = ReturnCostSerializer

class ReturnStatusList(generics.ListCreateAPIView):
    queryset = ReturnStatus.objects.all()
    serializer_class = ReturnStatusSerializer

class ReturnStatusDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ReturnStatus.objects.all()
    serializer_class = ReturnStatusSerializer

class ReturnStatusLanguageList(generics.ListCreateAPIView):
    queryset = ReturnStatusLanguage.objects.all()
    serializer_class = ReturnStatusLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['returnStatusId','languageId']

class ReturnStatusLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ReturnStatusLanguage.objects.all()
    serializer_class = ReturnStatusLanguageSerializer

class TrackStatusList(generics.ListCreateAPIView):
    queryset = TrackStatus.objects.all()
    serializer_class = TrackStatusSerializer

class TrackStatusDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = TrackStatus.objects.all()
    serializer_class = TrackStatusSerializer

class TrackStatusLanguageList(generics.ListCreateAPIView):
    queryset = TrackStatusLanguage.objects.all()
    serializer_class = TrackStatusLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['trackStatusId','languageId']

class TrackStatusLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = TrackStatusLanguage.objects.all()
    serializer_class = TrackStatusLanguageSerializer

class PaymentMethodList(generics.ListCreateAPIView):
    serializer_class = PaymentMethodSerializer

    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return PaymentMethod.objects.all()
        else:
            return PaymentMethod.objects.filter(isEnabled = True)
        
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['keyName','isEnabled']

class PaymentMethodDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PaymentMethod.objects.all()
    serializer_class = PaymentMethodSerializer

class PaymentMethodLanguageList(generics.ListCreateAPIView):
    queryset = PaymentMethodLanguage.objects.all()
    serializer_class = PaymentMethodLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['paymentMethodId','languageId']

class PaymentMethodLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PaymentMethodLanguage.objects.all()
    serializer_class = PaymentMethodLanguageSerializer

class EligibleTypeList(generics.ListCreateAPIView):
    queryset = EligibleType.objects.all()
    serializer_class = EligibleTypeSerializer

class EligibleTypeDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = EligibleType.objects.all()
    serializer_class = EligibleTypeSerializer

class EligibleTypeLanguageList(generics.ListCreateAPIView):
    queryset = EligibleTypeLanguage.objects.all()
    serializer_class = EligibleTypeLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['eligibleTypeId','languageId']
   
class EligibleTypeLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = EligibleTypeLanguage.objects.all()
    serializer_class = EligibleTypeLanguageSerializer

class CountryList(generics.ListCreateAPIView):
    queryset = Country.objects.all()
    serializer_class = CountrySerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['isActive']

class CountryDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Country.objects.all()
    serializer_class = CountrySerializer

class CountryLanguageList(generics.ListCreateAPIView):
    queryset = CountryLanguage.objects.all()
    serializer_class = CountryLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['countryId','languageId']
   
class CountryLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = CountryLanguage.objects.all()
    serializer_class = CountryLanguageSerializer

class CityList(generics.ListCreateAPIView):
    queryset = City.objects.all()
    serializer_class = CitySerializer
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['countryId','isActive']
    search_fields = ['name']

class CityDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = City.objects.all()
    serializer_class = CitySerializer

class CityLanguageList(generics.ListCreateAPIView):
    queryset = CityLanguage.objects.all()
    serializer_class = CityLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['cityId','languageId']

class CityLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = CityLanguage.objects.all()
    serializer_class = CityLanguageSerializer

class ZoneList(generics.ListCreateAPIView):
    queryset = Zone.objects.all()
    serializer_class = ZoneSerializer
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['cityId','isActive']
    search_fields = ['name']

class ZoneDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Zone.objects.all()
    serializer_class = ZoneSerializer

class ZoneLanguageList(generics.ListCreateAPIView):
    queryset = ZoneLanguage.objects.all()
    serializer_class = ZoneLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['zoneId','languageId']

class ZoneLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ZoneLanguage.objects.all()
    serializer_class = ZoneLanguageSerializer

class DistrictList(generics.ListCreateAPIView):
    queryset = District.objects.all()
    serializer_class = DistrictSerializer
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['zoneId','isActive']
    search_fields = ['name']

class DistrictDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = District.objects.all()
    serializer_class = DistrictSerializer

class DistrictLanguageList(generics.ListCreateAPIView):
    queryset = DistrictLanguage.objects.all()
    serializer_class = DistrictLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['districtId','languageId']

class DistrictLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = DistrictLanguage.objects.all()
    serializer_class = DistrictLanguageSerializer

class GetDistrictPriceList(generics.ListAPIView):
    serializer_class = DistrictPriceSerializer
    
    def getPrice(self,selectedCityId,selectedZoneId,isInternal,isStandard):
        selectedDeliveryPriceList = []
        deliveryPriceList = []
        if isStandard == False:
            deliveryPriceCityZoneList = DeliveryPriceCityZone.objects.filter(Q(cityId = selectedCityId) | Q(zoneId = selectedZoneId))
            for selected in deliveryPriceCityZoneList:
                selectedDeliveryPriceList = DeliveryPrice.objects.filter(id=selected.deliveryPriceId.id).filter(isInternal = isInternal).filter(isStandard=False).filter(isEnabled=True)
                if selectedDeliveryPriceList.__len__() > 0:
                    deliveryPriceList.append(selectedDeliveryPriceList[0])
        else: 
            selectedDeliveryPriceList = DeliveryPrice.objects.filter(isInternal = isInternal).filter(isStandard=True).filter(isEnabled=True)
            if selectedDeliveryPriceList.__len__() > 0:
                deliveryPriceList.append(selectedDeliveryPriceList[0])
        

        if deliveryPriceList.__len__() > 0:
            maxValue = max(deliveryPriceList, key=lambda item: item.price)
            return maxValue
        
        return 0

    def getDistrictPrice(self,languageId,districtId,deliveryManId,isInternal,isStandard):
        selectedDistrict = None
        selectedDistrictName = None
        selectedZone = None
        selectedZoneName = None
        selectedCity = None
        selectedCityName = None
        selectedCountry = None
        selectedCountryName = None
        selectedDeliveryPrice = None

        if isStandard == False:
            selectedDistrict = District.objects.get(id = districtId)
            if selectedDistrict is not None:
                districtLanguageList = DistrictLanguage.objects.filter(districtId = selectedDistrict.id).filter(languageId=languageId)
                if districtLanguageList.__len__() > 0:
                    selectedDistrictName = districtLanguageList[0].name
                
                selectedZone = Zone.objects.get(id = selectedDistrict.zoneId.id)
                if selectedZone is not None:
                    zoneLanguageList = ZoneLanguage.objects.filter(zoneId = selectedZone.id).filter(languageId=languageId)
                    if zoneLanguageList.__len__() > 0:
                        selectedZoneName = zoneLanguageList[0].name
                    
                    selectedCity = City.objects.get(id = selectedZone.cityId.id)
                    if selectedCity is not None:
                        cityLanguageList = CityLanguage.objects.filter(cityId = selectedCity.id).filter(languageId=languageId)
                        if cityLanguageList.__len__() > 0:
                            selectedCityName = cityLanguageList[0].name
                        
                        selectedCountry = Country.objects.get(id = selectedCity.countryId.id)
                        if selectedCountry is not None:
                            countryLanguageList = CountryLanguage.objects.filter(countryId = selectedCountry.id).filter(languageId=languageId)
                            if countryLanguageList.__len__() > 0:
                                selectedCountryName = countryLanguageList[0].name

            maxPrice = 0
            if selectedCity is not None and selectedZone is not None:
                selectedDeliveryPrice = self.getPrice(selectedCity.id,selectedZone.id,isInternal,isStandard)
                maxPrice = selectedDeliveryPrice.price
        else:
            selectedDeliveryPrice = self.getPrice(None,None,isInternal,isStandard)
            maxPrice = selectedDeliveryPrice.price

        if selectedDeliveryPrice is not None and deliveryManId is not None:
            selectedDeliveryManPrice = DeliveryManPrice.objects.filter(deliveryPriceId = selectedDeliveryPrice.id).filter(deliveryManId = deliveryManId)
            if selectedDeliveryManPrice.__len__() > 0:
                if selectedDeliveryManPrice[0].price > selectedDeliveryPrice.price:
                    maxPrice = selectedDeliveryManPrice[0].price
                else:
                    maxPrice = selectedDeliveryPrice.price

        if isStandard == False:
            return [
                DistrictPrice(
                    countryId=selectedCountry.id,
                    country=selectedCountryName,
                    cityId=selectedCity.id,
                    city=selectedCityName,
                    zoneId=selectedZone.id,
                    zone=selectedZoneName,
                    districtId=selectedDistrict.id,
                    district=selectedDistrictName,
                    price=maxPrice
                    )
            ]
        else:
            if isInternal == True:
                return [
                        DistrictPrice(
                        countryId=None,
                        country=None,
                        cityId=None,
                        city=None,
                        zoneId=None,
                        zone=None,
                        districtId=None,
                        district=None,
                        deliveryPriceId=int(selectedDeliveryPrice.id),
                        price=maxPrice
                        )
            ]
            else:
                return [
                        DistrictPrice(
                        countryId=None,
                        country=None,
                        cityId=None,
                        city=None,
                        zoneId=None,
                        zone=None,
                        districtId=None,
                        district=None,
                        deliveryPriceId=None,
                        price=maxPrice
                        )
            ]

    def get_queryset(self):
        languageId = self.request.query_params.get('languageId')
        districtId = self.request.query_params.get('districtId')
        deliveryManId = self.request.query_params.get('deliveryManId')
        isInternal = self.request.query_params.get('isInternal')
        isStandard = self.request.query_params.get('isStandard')

        isInternalVal = None
        isStandardVal = None
        
        if isInternal is None:
            raise NotFound({"Error":"Required isInternal Parameter"})
        else:
            if isInternal == '1' or (isInternal == 'True' or isInternal == 'true'):
                isInternalVal = True
            elif isInternal == '0' or (isInternal == 'False' or isInternal == 'false'):
                isInternalVal = False
            else:
                raise NotFound({"Error":"Invalid isInternal Parameter"})

        if isStandard is None:
            raise NotFound({"Error":"Required isStandard Parameter"})
        else:
            if isStandard == '1' or (isStandard == 'True' or isStandard == 'true'):
                isStandardVal = True
            elif isStandard == '0' or (isStandard == 'False' or isStandard == 'false'):
                isStandardVal = False
            else:
                raise NotFound({"Error":"Invalid isStandard Parameter"})

        if isStandardVal is not None:
            if isStandardVal == False:
                if languageId is None:
                    raise NotFound({"Error":"Required LanguageId Parameter"})
        
                if not languageId.isdigit():
                    raise NotFound({"Error":"Not a Number LanguageId Parameter"})
        
                if int(languageId) <= 0:
                    raise NotFound({"Error":"Invalid Primary Key LanguageId Parameter"})
        
                if districtId is None:
                    raise NotFound({"Error":"Required districtId Parameter"})
                
                if not districtId.isdigit():
                    raise NotFound({"Error":"Not a number districtId Parameter"})
                
                if int(districtId) <= 0:
                    raise NotFound({"Error":"Invalid Primary Key districtId Parameter"})

        if isInternalVal is not None:
            if isInternalVal == False:
                if deliveryManId is None:
                    raise NotFound({"Error":"Required deliveryManId Parameter"})
                
                if not deliveryManId.isdigit():
                    raise NotFound({"Error":"Not a number deliveryManId Parameter"})
                
                if int(deliveryManId) <= 0:
                    raise NotFound({"Error":"Invalid Primary Key deliveryManId Parameter"})
        
        return self.getDistrictPrice(languageId=languageId,districtId=districtId,isInternal=isInternalVal,isStandard=isStandardVal,deliveryManId=deliveryManId)
        
class GetAllDistrictList(generics.ListAPIView):
    serializer_class = AllDistrictSerializer

    def getAllDistricts(self,languageId):
        areaList = []
        countryList = Country.objects.filter(isActive = True)
        for country in countryList:
            countryLanguageList = CountryLanguage.objects.filter(countryId = country.id).filter(languageId=languageId)
            
            if countryLanguageList.__len__() > 0:
                cityList = City.objects.filter(countryId=country.id)
                for city in cityList:
                    cityLanguageList = CityLanguage.objects.filter(cityId = city.id).filter(languageId=languageId)

                    
                    if cityLanguageList.__len__() > 0:
                        zoneList = Zone.objects.filter(cityId = city.id)
                        for zone in zoneList:
                            zoneLanguageList = ZoneLanguage.objects.filter(zoneId = zone.id).filter(languageId=languageId)
                            
                            if zoneLanguageList.__len__() > 0:
                                districtList = District.objects.filter(zoneId = zone.id)

                                for district in districtList:
                                    districtLanguageList = DistrictLanguage.objects.filter(districtId = district.id).filter(languageId=languageId)
                                    
                                    if districtLanguageList.__len__() > 0:
                                        allDistrictData = AllDistrictData(
                                                countryId=country.id,
                                                country=countryLanguageList[0].name,
                                                cityId=city.id,
                                                city=cityLanguageList[0].name,
                                                zoneId=zone.id,
                                                zone=zoneLanguageList[0].name,
                                                districtId=district.id,
                                                district=districtLanguageList[0].name,
                                            )
                                        areaList.append(allDistrictData)
        return areaList

    def get_queryset(self):
        languageId = self.request.query_params.get('languageId')

        if languageId is None:
            raise NotFound({"Error":"Invalid Parameters"})
        
        if not languageId.isdigit():
            raise NotFound({"Error":"Invalid Parameters"})
        
        if int(languageId) <= 0:
            raise NotFound({"Error":"Invalid Parameters"})
        
        return self.getAllDistricts(languageId)

class DeliveryPriceList(generics.ListCreateAPIView):
    serializer_class = DeliveryPriceSerializer

    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return DeliveryPrice.objects.all()
        else:
            return DeliveryPrice.objects.filter(isEnabled=True)
        
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['isInternal','isStandard',]

class DeliveryPriceDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = DeliveryPrice.objects.all()
    serializer_class = DeliveryPriceSerializer

class DeliveryPriceCityZoneList(generics.ListCreateAPIView):
    queryset = DeliveryPriceCityZone.objects.all().order_by('id')
    serializer_class = DeliveryPriceCityZoneSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['deliveryPriceId','cityId','zoneId']

class DeliveryPriceCityZoneDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = DeliveryPriceCityZone.objects.all()
    serializer_class = DeliveryPriceCityZoneSerializer

class DepartmentList(generics.ListCreateAPIView):
    serializer_class = DepartmentSerializer
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['isSelected','departmentId','isPopular','keyName']
    search_fields = ['department_departmentlanguage__name',]

    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return Department.objects.all().order_by('id')
        else:
            return Department.objects.filter(isVisible=True).order_by('id')

    def perform_create(self, serializer, format=None):
        imageBase64 = self.request.data.get('imageBase64')
        if(imageBase64 is not None):
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            isSelected = self.request.data.get('isSelected')
            isPopular = self.request.data.get('isPopular')
            totalViews = self.request.data.get('totalViews')
            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')
            departmentId = self.request.data.get('departmentId')

            if departmentId is not None:
                department = Department.objects.get(id = str(departmentId))
                serializer.save(
                    isSelected = isSelected,
                    isPopular = isPopular, 
                    totalViews = totalViews,
                    image=newImage,
                    createdDate=newCreatedDate, 
                    updatedDate=newUpdatedDate,
                    departmentId = department)
            else:
                serializer.save(
                    isSelected = isSelected,
                    isPopular = isPopular, 
                    totalViews = totalViews,
                    image=newImage,
                    createdDate=newCreatedDate, 
                    updatedDate=newUpdatedDate,)
        else:
            serializer.save()

class Departmentetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Department.objects.all()
    serializer_class = DepartmentSerializer

    def perform_update(self, serializer, format=None):
        imageBase64 = self.request.data.get('imageBase64')
        if imageBase64 is not None:
            oldImageName = self.request.data.get('oldImageName')
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            id = self.request.data.get('id')
            if(oldImageName is not None):
                if os.path.exists(MEDIA_ROOT+'/departments/department_'+str(id)+'/'+oldImageName+'.'+imageExtension):
                    os.remove(MEDIA_ROOT+'/departments/department_'+str(id)+'/'+oldImageName+'.'+imageExtension)

            isSelected = self.request.data.get('isSelected')
            isPopular = self.request.data.get('isPopular')
            totalViews = self.request.data.get('totalViews')
            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')
            departmentId = self.request.data.get('departmentId')

            if departmentId is not None:
                department = Department.objects.get(id = str(departmentId))
                serializer.save(
                    isSelected = isSelected,
                    isPopular = isPopular, 
                    totalViews = totalViews,
                    image=newImage,
                    createdDate=newCreatedDate, 
                    updatedDate=newUpdatedDate,
                    departmentId = department)
            else:
                serializer.save(
                    isSelected = isSelected,
                    isPopular = isPopular, 
                    totalViews = totalViews,
                    image=newImage,
                    createdDate=newCreatedDate, 
                    updatedDate=newUpdatedDate,)
        else:
            serializer.save()

class DepartmentLanguageList(generics.ListCreateAPIView):
    queryset = DepartmentLanguage.objects.all()
    serializer_class = DepartmentLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['departmentId','languageId']

class DepartmentLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = DepartmentLanguage.objects.all()
    serializer_class = DepartmentLanguageSerializer

class BrandList(generics.ListCreateAPIView):
    serializer_class = BrandSerializer
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['keyName']
    search_fields = ['brand_brandlanguage__name']

    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return Brand.objects.all()
        else:
            return Brand.objects.filter(isVisible=True)

    def perform_create(self, serializer, format=None):
        imageBase64 = self.request.data.get('imageBase64')
        if(imageBase64 is not None):
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')

            serializer.save(image=newImage,createdDate=newCreatedDate, updatedDate=newUpdatedDate)
        else:
            serializer.save()

class BrandDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Brand.objects.all()
    serializer_class = BrandSerializer

    def perform_update(self, serializer, format=None):
        imageBase64 = self.request.data.get('imageBase64')
        if imageBase64 is not None:
            oldImageName = self.request.data.get('oldImageName')
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            id = self.request.data.get('id')
            if(oldImageName is not None):
                if os.path.exists(MEDIA_ROOT+'/brands/brand_'+str(id)+'/'+oldImageName+'.'+imageExtension):
                    os.remove(MEDIA_ROOT+'/brands/brand_'+str(id)+'/'+oldImageName+'.'+imageExtension)

            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')

            serializer.save(image=newImage,createdDate=newCreatedDate, updatedDate=newUpdatedDate)
        else:
            serializer.save()

class BrandLanguageList(generics.ListCreateAPIView):
    queryset = BrandLanguage.objects.all()
    serializer_class = BrandLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['brandId','languageId']

class BrandLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = BrandLanguage.objects.all()
    serializer_class = BrandLanguageSerializer

class SubscriptionStatusList(generics.ListCreateAPIView):
    queryset = SubscriptionStatus.objects.all()
    serializer_class = SubscriptionStatusSerializer

class SubscriptionStatusDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SubscriptionStatus.objects.all()
    serializer_class = SubscriptionStatusSerializer

class SubscriptionStatusLanguageList(generics.ListCreateAPIView):
    queryset = SubscriptionStatusLanguage.objects.all()
    serializer_class = SubscriptionStatusLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['subscriptionStatusId','languageId']

class SubscriptionStatusLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SubscriptionStatusLanguage.objects.all()
    serializer_class = SubscriptionStatusLanguageSerializer

class SubscriptionOptionList(generics.ListCreateAPIView):
    queryset = SubscriptionOption.objects.all()
    serializer_class = SubscriptionOptionSerializer

class SubscriptionOptionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SubscriptionOption.objects.all()
    serializer_class = SubscriptionOptionSerializer

class SubscriptionOptionLanguageList(generics.ListCreateAPIView):
    queryset = SubscriptionOptionLanguage.objects.all()
    serializer_class = SubscriptionOptionLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['subscriptionOptionId','languageId']

class SubscriptionOptionLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SubscriptionOptionLanguage.objects.all()
    serializer_class = SubscriptionOptionLanguageSerializer

class SubscriptionTypeList(generics.ListCreateAPIView):
    queryset = SubscriptionType.objects.all()
    serializer_class = SubscriptionTypeSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['subscriptionOptionId','subscriptionOptionId__keyName','isEnabled']
    
class SubscriptionTypeDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SubscriptionType.objects.all()
    serializer_class = SubscriptionTypeSerializer

class SubscriptionTypeLanguageList(generics.ListCreateAPIView):
    queryset = SubscriptionTypeLanguage.objects.all()
    serializer_class = SubscriptionTypeLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['subscriptionTypeId','languageId']

class SubscriptionTypeLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SubscriptionTypeLanguage.objects.all()
    serializer_class = SubscriptionTypeLanguageSerializer

class TransactionTypeList(generics.ListCreateAPIView):
    queryset = TransactionType.objects.all()
    serializer_class = TransactionTypeSerializer

class TransactionTypeDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = TransactionType.objects.all()
    serializer_class = TransactionTypeSerializer

class TransactionTypeLanguageList(generics.ListCreateAPIView):
    queryset = TransactionTypeLanguage.objects.all()
    serializer_class = TransactionTypeLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['transactionTypeId','languageId']

class TransactionTypeLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = TransactionTypeLanguage.objects.all()
    serializer_class = TransactionTypeLanguageSerializer

class NewArrivalList(generics.ListCreateAPIView):
    serializer_class = NewArrivalSerializer
    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return NewArrival.objects.all().order_by('-createdDate')
        else:
            return NewArrival.objects.all().order_by('-createdDate')[:1]

    def perform_create(self, serializer, format=None):

        imageBase64 = self.request.data.get('imageBase64')
        if(imageBase64 is not None):
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')

            serializer.save(image=newImage,createdDate=newCreatedDate, updatedDate=newUpdatedDate)
        else:
            serializer.save()

class NewArrivalDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = NewArrival.objects.all()
    serializer_class = NewArrivalSerializer

    def perform_update(self, serializer, format=None):
        imageBase64 = self.request.data.get('imageBase64')
        if(imageBase64 is not None):
            oldImageName = self.request.data.get('oldImageName')
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            id = self.request.data.get('id')
            if(oldImageName is not None):
                if os.path.exists(MEDIA_ROOT+'/newarrivals/newarrival_'+str(id)+'/'+oldImageName+'.'+imageExtension):
                    os.remove(MEDIA_ROOT+'/newarrivals/newarrival_'+str(id)+'/'+oldImageName+'.'+imageExtension)

            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')

            serializer.save(image=newImage,createdDate=newCreatedDate, updatedDate=newUpdatedDate)
        else:
            serializer.save()

class NewArrivalLanguageList(generics.ListCreateAPIView):
    queryset = NewArrivalLanguage.objects.all()
    serializer_class = NewArrivalLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['newArrivalId','languageId']

class NewArrivalLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = NewArrivalLanguage.objects.all()
    serializer_class = NewArrivalLanguageSerializer

class CouponList(generics.ListCreateAPIView):
    queryset = Coupon.objects.all().order_by('-id')
    serializer_class = CouponSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['code']

class CouponDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Coupon.objects.all()
    serializer_class = CouponSerializer

class ClientList(generics.ListCreateAPIView):
    queryset = Client.objects.all().order_by('id')
    serializer_class = ClientSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['email','password',]
    search_fields = ['firstName','lastName','client_phone__phone']

class ClientDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Client.objects.all()
    serializer_class = ClientSerializer

class ClientPhoneList(generics.ListCreateAPIView):
    queryset = ClientPhone.objects.all()
    serializer_class = ClientPhoneSerializer
    filter_backends = [searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['clientId']
    search_fields = ['phone']

class ClientPhoneDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ClientPhone.objects.all()
    serializer_class = ClientPhoneSerializer

class ClientCreditCardList(generics.ListCreateAPIView):
    queryset = ClientCreditCard.objects.all()
    serializer_class = ClientCreditCardSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId']

class ClientCreditCardDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ClientCreditCard.objects.all()
    serializer_class = ClientCreditCardSerializer

class ClientAddressBookList(generics.ListCreateAPIView):
    queryset = ClientAddressBook.objects.all()
    serializer_class = ClientAddressBookSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId']

class ClientAddressBookDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ClientAddressBook.objects.all()
    serializer_class = ClientAddressBookSerializer

class WalletList(generics.ListCreateAPIView):
    #permission_classes=(permissions.IsAuthenticated,)
    queryset = Wallet.objects.all().order_by('clientId')
    serializer_class = WalletSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId']

class WalletDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Wallet.objects.all()
    serializer_class = WalletSerializer

class TransactionList(generics.ListCreateAPIView):
    queryset = Transaction.objects.all().order_by('-id')
    serializer_class = TransactionSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['walletId','transactionTypeId']

class TransactionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Transaction.objects.all()
    serializer_class = TransactionSerializer

class ShoppingCartList(generics.ListCreateAPIView):
    queryset = ShoppingCart.objects.all()
    serializer_class = ShoppingCartSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId']

class ShoppingCartDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ShoppingCart.objects.all()
    serializer_class = ShoppingCartSerializer

class ShoppingCartDashboardList(generics.ListCreateAPIView):
    queryset = ShoppingCart.objects.all()
    serializer_class = ShoppingCartSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId']

class PurchaseOrderFilter(filters.FilterSet):
    currentDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='gte')
    previousDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='lt')
    isValidAndPaid = filters.BooleanFilter(field_name='purchaseorder_shippingitem__isValidAndPaid',lookup_expr='exact')
    
    class Meta:
        model = PurchaseOrder
        fields = [
            'paymentMethodId',
            'orderFromId',
            'couponId',
            'clientId',
            'isCanceled',
            'isRefunded',
            'sessionId',
            'createdDate',
            'isValidAndPaid'
            ]

class PurchaseOrderList(generics.ListCreateAPIView):
    queryset = PurchaseOrder.objects.all().order_by('-id')
    serializer_class = PurchaseOrderSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_class = PurchaseOrderFilter
    search_fields = ['id','sessionId']

class PurchaseOrderDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PurchaseOrder.objects.all()
    serializer_class = PurchaseOrderSerializer

class SupplierList(generics.ListCreateAPIView):
    queryset = Supplier.objects.all().order_by('id')
    serializer_class = SupplierSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['email','password']
    search_fields = ['name']

class SupplierDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Supplier.objects.all()
    serializer_class = SupplierSerializer

class SupplierPhoneList(generics.ListCreateAPIView):
    queryset = SupplierPhone.objects.all().order_by('id')
    serializer_class = SupplierPhoneSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['supplierId','phone']

class SupplierPhoneDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SupplierPhone.objects.all()
    serializer_class = SupplierPhoneSerializer

class SupplierCreditCardList(generics.ListCreateAPIView):
    queryset = SupplierCreditCard.objects.all()
    serializer_class = SupplierCreditCardSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['supplierId']

class SupplierCreditCardDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SupplierCreditCard.objects.all()
    serializer_class = SupplierCreditCardSerializer

class SupplierDocumentList(generics.ListCreateAPIView):
    queryset = SupplierDocument.objects.all()
    serializer_class = SupplierDocumentSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['supplierId']

    def perform_create(self, serializer, format=None):
        fileDocumentBase64 = self.request.data.get('fileDocumentBase64')
        if(fileDocumentBase64 is not None):
            data = base64.b64decode(fileDocumentBase64.encode('UTF-8'))
            
            supplierId = self.request.data.get('supplierId')
            fileDocumentName = self.request.data.get('fileDocumentName')
            contentType = self.request.data.get('contentType')
            fileDocumentExtension = self.request.data.get('fileDocumentExtension')

            parentPath = MEDIA_ROOT+'/suppliers/'
            childPath = MEDIA_ROOT+'/suppliers/supplier_'+str(supplierId)
            
            if os.path.exists(parentPath) != True:
                    os.mkdir(parentPath)

            if os.path.exists(childPath) != True:
                    os.mkdir(childPath)
            
            filePath = childPath+'/'+fileDocumentName
            
            file = open(file=filePath,mode='wb+')
            file.write(data)

            newFile = InMemoryUploadedFile(file=file, field_name='fileDocument', name=fileDocumentName,
                                            size=file.tell(), charset=None, content_type=contentType+'/'+fileDocumentExtension.upper())
            
            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')
            
            supplier = Supplier.objects.get(id = str(supplierId))
            
            serializer.save(
                fileName = fileDocumentName,
                contentType = contentType,
                fileDocument=newFile,
                supplierId = supplier,
                createdDate=newCreatedDate,
                updatedDate=newUpdatedDate)
            
            os.remove(filePath)
            file.close()
        else:
            serializer.save()

class SupplierDocumentDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SupplierDocument.objects.all()
    serializer_class = SupplierDocumentSerializer

class SubscriptionList(generics.ListCreateAPIView):
    queryset = Subscription.objects.all().order_by('-id')
    serializer_class = SubscriptionSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['supplierId','subscriptionTypeId']

class SubscriptionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Subscription.objects.all()
    serializer_class = SubscriptionSerializer

class DeliveryManList(generics.ListCreateAPIView):
    queryset = DeliveryMan.objects.all().order_by('id')
    serializer_class = DeliveryManSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['email','password']
    search_fields = ['name']

class DeliveryManDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = DeliveryMan.objects.all()
    serializer_class = DeliveryManSerializer

class DeliveryManPhoneList(generics.ListCreateAPIView):
    queryset = DeliveryManPhone.objects.all()
    serializer_class = DeliveryManPhoneSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['deliveryManId','phone']

class DeliveryManPhoneDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = DeliveryManPhone.objects.all()
    serializer_class = DeliveryManPhoneSerializer

class DeliveryManPriceList(generics.ListCreateAPIView):
    queryset = DeliveryManPrice.objects.all().order_by('id')
    serializer_class = DeliveryManPriceSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['deliveryManId','deliveryPriceId']

class DeliveryManPriceDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = DeliveryManPrice.objects.all()
    serializer_class = DeliveryManPriceSerializer

class ShippingItemList(generics.ListCreateAPIView):
    queryset = ShippingItem.objects.all().order_by('-id')
    serializer_class = ShippingItemSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['purchaseOrderId']

class ShippingItemDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ShippingItem.objects.all()
    serializer_class = ShippingItemSerializer

class ShippingAddressFilter(filters.FilterSet):
    currentDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='gte')
    previousDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='lt')
    
    class Meta:
        model = ShippingAddress
        fields = ['shippingItemId',
                  'trackNumber',
                  'phone',
                  'deliveryManId',
                  'currentDate',
                  'previousDate']

class ShippingAddressList(generics.ListCreateAPIView):
    serializer_class = ShippingAddressSerializer
    pagination_class = StandardSetPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = ShippingAddressFilter

    def get_queryset(self):
        trackNumber = self.request.query_params.get('trackNumber')
        deliveryManId = self.request.query_params.get('deliveryManId')
        notAssignedDeliveryMan = self.request.query_params.get('notAssignedDeliveryMan')
        if trackNumber is not None:
            return ShippingAddress.objects.filter(trackNumber=trackNumber).filter(shippingItemId__purchaseOrderId__isCanceled=False).order_by('-shippingItemId')
        elif notAssignedDeliveryMan is not None:
            if notAssignedDeliveryMan == '1':
                return ShippingAddress.objects.filter(deliveryManId__isnull=True).filter(shippingItemId__purchaseOrderId__isCanceled=False).exclude(trackNumber='').order_by('-shippingItemId')
            elif notAssignedDeliveryMan == '0':
                return ShippingAddress.objects.filter(deliveryManId__isnull=False).filter(shippingItemId__purchaseOrderId__isCanceled=False).exclude(trackNumber='').order_by('-shippingItemId')
        elif deliveryManId is not None:
             return ShippingAddress.objects.filter(deliveryManId=deliveryManId).filter(shippingItemId__purchaseOrderId__isCanceled=False).order_by('-shippingItemId')
        else:
            return ShippingAddress.objects.filter(shippingItemId__purchaseOrderId__isCanceled=False).order_by('-shippingItemId')

class ShippingAddressDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ShippingAddress.objects.all().order_by('-shippingItemId')
    serializer_class = ShippingAddressSerializer

class TrackList(generics.ListCreateAPIView):
    queryset = Track.objects.all().order_by('-id')
    serializer_class = TrackSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['shippingAddressId','trackStatusId']

class TrackDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Track.objects.all()
    serializer_class = TrackSerializer

class SalesOrderList(generics.ListCreateAPIView):
    queryset = SalesOrder.objects.all().order_by('-createdDate')
    serializer_class = SalesOrderSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['supplierId','shippingItemId']
    pagination_class = StandardSetPagination

class SalesOrderDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SalesOrder.objects.all()
    serializer_class = SalesOrderSerializer

class ItemFilter(filters.FilterSet):
    totalViews = filters.NumberFilter(field_name='totalViews',lookup_expr='gte')
    amount = filters.NumberFilter(field_name='item_sku__amount',lookup_expr='lte')
    min_price = filters.NumberFilter(field_name='item_sku__price',lookup_expr='gte')
    max_price = filters.NumberFilter(field_name='item_sku__price',lookup_expr='lte')
    discount_gt = filters.NumberFilter(field_name='item_sku__discount',lookup_expr='gt')
    brandId = filters.ModelMultipleChoiceFilter(field_name='brandId',to_field_name='id',queryset=Brand.objects.all())
    class Meta:
        model = Item
        fields = [
            'id',
            'keyName',
            'isApproved',
            'isTop',
            'isFavorite',
            'departmentId',
            'brandId',
            'supplierId',
            'newArrivalId',
            'item_sku__amount',
            'discount_gt',
            'min_price',
            'max_price',
            'amount',
            'totalViews',
            'linkId',
            ]

class ItemList(generics.ListCreateAPIView):
    serializer_class = ItemSerializer
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_class = ItemFilter
    search_fields = ['item_itemlanguage__name','id','keyName']
    pagination_class = StandardItemSetPagination

    def get_queryset(self):
        isDashboard = self.request.query_params.get('isDashboard')
        if isDashboard == '1':
            return Item.objects.order_by('id').distinct()
        else:
            selectedSettings = Settings.objects.all().first()
            isEnableFreeSubscription = False
            if selectedSettings is not None:
                isEnableFreeSubscription = selectedSettings.isEnableFreeSubscriptionForSupplier

            if isEnableFreeSubscription == True:
                return Item.objects.order_by('-createdDate').filter(isApproved=True)
            else:
                statusList = SubscriptionStatus.objects.filter(keyName = 'active')
                if statusList.__len__() > 0:
                    return Item.objects.order_by('-createdDate').filter(isApproved=True).filter(supplierId__supplier_subscription__subscriptionStatusId=statusList[0].id)

class ItemDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer

class ItemLanguageList(generics.ListCreateAPIView):
    queryset = ItemLanguage.objects.all()
    serializer_class = ItemLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['itemId','languageId']

class ItemLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ItemLanguage.objects.all()
    serializer_class = ItemLanguageSerializer

class FeatureBulletList(generics.ListCreateAPIView):
    queryset = FeatureBullet.objects.all()
    serializer_class = FeatureBulletSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['itemId']
    pagination_class = StandardSetPagination

class FeatureBulletDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = FeatureBullet.objects.all()
    serializer_class = FeatureBulletSerializer

class FeatureBulletLanguageList(generics.ListCreateAPIView):
    queryset = FeatureBulletLanguage.objects.all()
    serializer_class = FeatureBulletLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['featureBulletId','languageId']

class FeatureBulletLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = FeatureBulletLanguage.objects.all()
    serializer_class = FeatureBulletLanguageSerializer

#Change Start

class EligibleList(generics.ListCreateAPIView):
    queryset = Eligible.objects.all()
    serializer_class = EligibleSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['itemId','eligibleTypeId']

class EligibleDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Eligible.objects.all()
    serializer_class = EligibleSerializer

#Change End

class SKUFilter(filters.FilterSet):
    amount = filters.NumberFilter(field_name='amount',lookup_expr='lte')
    min_price = filters.NumberFilter(field_name='price',lookup_expr='gte')
    max_price = filters.NumberFilter(field_name='price',lookup_expr='lte')
    discount_gt = filters.NumberFilter(field_name='discount',lookup_expr='gt')
    class Meta:
        model = SKU
        fields = [
            'keyName',
            'discount_gt',
            'min_price',
            'max_price',
            'amount',
            'itemId',
            'itemId__departmentId',
            'itemId__brandId',
            'itemId__supplierId',
            'itemId__newArrivalId',
            'itemId__isTop',
            'itemId__isFavorite',
            'itemId__isApproved',
            ]

class SKUList(generics.ListCreateAPIView):
    queryset = SKU.objects.all().order_by('-id')
    serializer_class = SKUSerializer
    pagination_class = StandardSKUSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_class = SKUFilter
    search_fields = ['id','name','keyName']

    def perform_create(self, serializer, format=None):
        imageBase64 = self.request.data.get('imageBase64')
        newImage = None
        if(imageBase64 is not None):
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            currentName = self.request.data.get('name')
            price =self.request.data.get('price')
            discount = self.request.data.get('discount')
            amount = self.request.data.get('amount') 
            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')
            itemId = self.request.data.get('itemId')

            item = Item.objects.get(id = str(itemId))

            #todayDate = datetime.now()

            lastSKU = SKU.objects.last()
            newId = 1
            if lastSKU is not None:
                newId = lastSKU.id + 1
            
            #skuName = currentName+str(itemId)+str(newId)+str(todayDate.year)+str(todayDate.month)+str(todayDate.day)+str(todayDate.hour)+str(todayDate.minute)+str(todayDate.second)
            skuName = currentName+str(itemId)+str(newId)
            data = serializer.save(
                image=newImage,
                name = skuName,
                price = price,
                discount = discount,
                amount = amount,
                createdDate = newCreatedDate,
                updatedDate = newUpdatedDate,
                itemId = item)
                
            #skuName = currentName+str(itemId)+str(data.id)+str(todayDate.year)+str(todayDate.month)+str(todayDate.day)+str(todayDate.hour)+str(todayDate.minute)+str(todayDate.second)
            skuName = currentName+str(itemId)+str(data.id)
                
            data.name = skuName

            data.save()
        else:
            currentName = self.request.data.get('name')
            price =self.request.data.get('price')
            discount = self.request.data.get('discount')
            amount = self.request.data.get('amount') 
            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')
            itemId = self.request.data.get('itemId')

            item = Item.objects.get(id = str(itemId))

            #todayDate = datetime.now()

            lastSKU = SKU.objects.last()
            newId = 1
            if lastSKU is not None:
                newId = lastSKU.id + 1
            
            #skuName = currentName+str(itemId)+str(newId)+str(todayDate.year)+str(todayDate.month)+str(todayDate.day)+str(todayDate.hour)+str(todayDate.minute)+str(todayDate.second)
            skuName = currentName+str(itemId)+str(newId)

            data = serializer.save(
                name = skuName,
                price = price,
                discount = discount,
                amount = amount,
                createdDate = newCreatedDate,
                updatedDate = newUpdatedDate,
                itemId = item)
                
            #skuName = currentName+str(itemId)+str(data.id)+str(todayDate.year)+str(todayDate.month)+str(todayDate.day)+str(todayDate.hour)+str(todayDate.minute)+str(todayDate.second)
            skuName = currentName+str(itemId)+str(data.id)
            
            data.name = skuName

            data.save()

class SKUDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SKU.objects.all()
    serializer_class = SKUSerializer

    def perform_update(self, serializer, format=None):
        imageBase64 = self.request.data.get('imageBase64')
        if(imageBase64 is not None):
            oldImageName = self.request.data.get('oldImageName')
            imageExtension = self.request.data.get('imageExtension')
            data = base64.b64decode(imageBase64.encode('UTF-8'))
            buf = io.BytesIO(data)
            img = Image.open(buf)
            img_io = io.BytesIO()
            img.save(img_io, format=imageExtension.upper())
            name = self.request.data.get('imageName')
            newImage = InMemoryUploadedFile(file=img_io, field_name='image', name=name,
                                            size=img_io.tell(), charset=None, content_type='image/'+imageExtension.upper())

            id = self.request.data.get('id')
            itemId = self.request.data.get('itemId')
            if(oldImageName is not None):
                if os.path.exists(MEDIA_ROOT+'/items/item_'+str(itemId)+'/sku_'+str(id)+'/images/'+oldImageName+'.'+imageExtension):
                    os.remove(MEDIA_ROOT+'/items/item_'+str(itemId)+'/sku_'+str(id)+'/images/'+oldImageName+'.'+imageExtension)

            skuName = self.request.data.get('name')
            price =self.request.data.get('price')
            discount = self.request.data.get('discount')
            amount = self.request.data.get('amount')
            newCreatedDate = self.request.data.get('createdDate')
            newUpdatedDate = self.request.data.get('updatedDate')
            
            item = Item.objects.get(id = str(itemId))

            serializer.save(image=newImage,
            name = skuName,
            price = price,
            discount = discount,
            amount = amount,
            createdDate = newCreatedDate,
            updatedDate = newUpdatedDate,
            item = item)
        else:
            serializer.save()

#SKU Option Views

class SKUOptionList(generics.ListCreateAPIView):
    queryset = SKUOption.objects.all()
    serializer_class = SKUOptionSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['skuId']

class SKUOptionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SKUOption.objects.all()
    serializer_class = SKUOptionSerializer

class SKUOptionLanguageList(generics.ListCreateAPIView):
    queryset = SKUOptionLanguage.objects.all()
    serializer_class = SKUOptionLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['skuOptionId','languageId']

class SKUOptionLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SKUOptionLanguage.objects.all()
    serializer_class = SKUOptionLanguageSerializer

#SKU Description Views

class SKUDescriptionList(generics.ListCreateAPIView):
    queryset = SKUDescription.objects.all()
    serializer_class = SKUDescriptionSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['skuId']

class SKUDescriptionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SKUDescription.objects.all()
    serializer_class = SKUDescriptionSerializer

class SKUDescriptionLanguageList(generics.ListCreateAPIView):
    queryset = SKUDescriptionLanguage.objects.all()
    serializer_class = SKUDescriptionLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['skuDescriptionId','languageId']

class SKUDescriptionLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SKUDescriptionLanguage.objects.all()
    serializer_class = SKUDescriptionLanguageSerializer

class ItemSubscriptionList(generics.ListCreateAPIView):
    queryset = ItemSubscription.objects.all().order_by('-id')
    serializer_class = ItemSubscriptionSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['itemId','subscriptionTypeId']

class ItemSubscriptionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ItemSubscription.objects.all()
    serializer_class = ItemSubscriptionSerializer

class ShoppingCartItemList(generics.ListCreateAPIView):
    queryset = ShoppingCartItem.objects.all().order_by('-id')
    serializer_class = ShoppingCartItemSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['shoppingCartId','skuId']

class ShoppingCartItemDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ShoppingCartItem.objects.all()
    serializer_class = ShoppingCartItemSerializer

class PurchaseShippingItemList(generics.ListCreateAPIView):
    queryset = PurchaseShippingItem.objects.all().order_by('id')
    serializer_class = PurchaseShippingItemSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['shippingItemId','skuId']

class PurchaseShippingItemDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PurchaseShippingItem.objects.all()
    serializer_class = PurchaseShippingItemSerializer

class RequestReturnFilter(filters.FilterSet):
    currentDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='gte')
    previousDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='lt')
    
    class Meta:
        model = RequestReturn
        fields = [
            'returnStatusId',
            'purchaseShippingItemId',
            'purchaseShippingItemId__shippingItemId',
            'returnStatusId__keyName',
            'currentDate',
            'previousDate',
            'createdDate'
            ]

class RequestReturnList(generics.ListCreateAPIView):
    queryset = RequestReturn.objects.all().order_by('-id')
    serializer_class = RequestReturnSerializerDetail
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_class = RequestReturnFilter

class RequestReturnDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = RequestReturn.objects.all()
    serializer_class = RequestReturnSerializerDetail

class SalesOrderItemList(generics.ListCreateAPIView):
    queryset = SalesOrderItem.objects.all().order_by('id')
    serializer_class = SalesOrderItemSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['salesOrderId','skuId']

class SalesOrderItemDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SalesOrderItem.objects.all()
    serializer_class = SalesOrderItemSerializer

class FavoriteList(generics.ListCreateAPIView):
    queryset = Favorite.objects.all().order_by('id')
    serializer_class = FavoriteSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId','itemId']

class FavoriteDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Favorite.objects.all()
    serializer_class = FavoriteSerializer

class ClientItemRateReviewList(generics.ListCreateAPIView):
    queryset = ClientItemRateReview.objects.all().order_by('-id')
    serializer_class = ClientItemRateReviewSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId','itemId']

class ClientItemRateReviewDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ClientItemRateReview.objects.all()
    serializer_class = ClientItemRateReviewSerializer

class ClientSupplierRateReviewList(generics.ListCreateAPIView):
    queryset = ClientSupplierRateReview.objects.all().order_by('-id')
    serializer_class = ClientSupplierRateReviewSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId','supplierId']

class ClientSupplierRateReviewDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ClientSupplierRateReview.objects.all()
    serializer_class = ClientSupplierRateReviewSerializer

class FeedbackList(generics.ListCreateAPIView):
    queryset = Feedback.objects.all().order_by('-id')
    serializer_class = FeedbackSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId']

class FeedbackDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Feedback.objects.all().order_by('-id')
    serializer_class = FeedbackSerializer

class RequestList(generics.ListCreateAPIView):
    queryset = Request.objects.all().order_by('-id')
    serializer_class = RequestSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['clientId','isDone']

class RequestDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Request.objects.all()
    serializer_class = RequestSerializer

class PolicyTypeList(generics.ListCreateAPIView):
    queryset = PolicyType.objects.all()
    serializer_class = PolicyTypeSerializer

class PolicyTypeDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PolicyType.objects.all()
    serializer_class = PolicyTypeSerializer

class PolicyHeaderFilter(filters.FilterSet):
    policyTypeName = filters.ModelMultipleChoiceFilter(field_name='policyTypeId__name',to_field_name='name',queryset=PolicyType.objects.all())
    class Meta:
        model = PolicyHeader
        fields = [
            'policyTypeId',
            'policyTypeName',
            ]

class PolicyHeaderList(generics.ListCreateAPIView):
    queryset = PolicyHeader.objects.all()
    serializer_class = PolicyHeaderSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_class = PolicyHeaderFilter
    #filterset_fields = ['policyTypeId','policyTypeId__name']

class PolicyHeaderDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PolicyHeader.objects.all()
    serializer_class = PolicyHeaderSerializer

class PolicyHeaderLanguageList(generics.ListCreateAPIView):
    queryset = PolicyHeaderLanguage.objects.all()
    serializer_class = PolicyHeaderLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['policyHeaderId','languageId']

class PolicyHeaderLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PolicyHeaderLanguage.objects.all()
    serializer_class = PolicyHeaderLanguageSerializer

class PolicyDescriptionList(generics.ListCreateAPIView):
    queryset = PolicyDescription.objects.all()
    serializer_class = PolicyDescriptionSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['policyHeaderId']

class PolicyDescriptionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PolicyDescription.objects.all()
    serializer_class = PolicyDescriptionSerializer

class PolicyDescriptionLanguageList(generics.ListCreateAPIView):
    queryset = PolicyDescriptionLanguage.objects.all()
    serializer_class = PolicyDescriptionLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['policyDescriptionId','languageId']

class PolicyDescriptionLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PolicyDescriptionLanguage.objects.all()
    serializer_class = PolicyDescriptionLanguageSerializer

class RechargeFilter(filters.FilterSet):
    startDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='gte')
    endDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='lte')
    
    class Meta:
        model = Recharge
        fields = [
            'taxesId',
            'sessionId',
            'paymentMethodId',
            'description',
            'startDate',
            'endDate',
            ]

class RechargeList(generics.ListCreateAPIView):
    queryset = Recharge.objects.all().order_by('-id')
    serializer_class = RechargeSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_class = RechargeFilter
    search_fields = ['description']

class RechargeDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Recharge.objects.all()
    serializer_class = RechargeSerializer

class PaymentFilter(filters.FilterSet):
    startDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='gte')
    endDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='lte')
    
    class Meta:
        model = Payment
        fields = [
            'transactionTypeId',
            'purchaseOrderId',
            'subscriptionId',
            'itemSubscriptionId',
            'taxesId',
            'salesOrderId',
            'deliveryManId',
            'rechargeId',
            'startDate',
            'description',
            'endDate',
            ]

class PaymentList(generics.ListCreateAPIView):
    queryset = Payment.objects.all().order_by('-id')
    serializer_class = PaymentSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_class = PaymentFilter
    search_fields = ['descriptionDetail']

class PaymentDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Payment.objects.all()
    serializer_class = PaymentSerializer

class SupplierPaymentList(generics.ListAPIView):
    serializer_class = PaymentSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_class = PaymentFilter
    search_fields = ['descriptionDetail']

    def get_queryset(self):
        supplierId = self.request.query_params.get('supplierId')
        if supplierId is not None:
            result = Payment.objects.filter(Q(salesOrderId__supplierId = supplierId) | Q(subscriptionId__supplierId = supplierId)).order_by('-id')
            return result
        else:
            raise NotFound({"Error":"Invalid Parameters"})

class AccessoryList(generics.ListCreateAPIView):
    queryset = Accessory.objects.all().order_by('id')
    serializer_class = AccessorySerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter]
    search_fields = ['name']

class AccessoryDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Accessory.objects.all()
    serializer_class = AccessorySerializer

class AccessoryTransactionList(generics.ListCreateAPIView):
    queryset = AccessoryTransaction.objects.all().order_by('-id')
    serializer_class = AccessoryTransactionSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['transactionTypeId','accessoryId']

class AccessoryTransactionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = AccessoryTransaction.objects.all()
    serializer_class = AccessoryTransactionSerializer

class EmployeeList(generics.ListCreateAPIView):
    queryset = Employee.objects.all().order_by('id')
    serializer_class = EmployeeSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['email','password']
    search_fields = ['fullName',]

class EmployeeDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Employee.objects.all()
    serializer_class = EmployeeSerializer

# Link Type

class LinkTypeList(generics.ListCreateAPIView):
    queryset = LinkType.objects.all()
    serializer_class = LinkTypeSerializer

class LinkTypeDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = LinkType.objects.all()
    serializer_class = LinkTypeSerializer

# Link Status

class LinkStatusList(generics.ListCreateAPIView):
    queryset = LinkStatus.objects.all()
    serializer_class = LinkStatusSerializer

class LinkStatusDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = LinkStatus.objects.all()
    serializer_class = LinkStatusSerializer

class LinkStatusLanguageList(generics.ListCreateAPIView):
    queryset = LinkStatusLanguage.objects.all()
    serializer_class = LinkStatusLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['linkStatusId','languageId']

class LinkStatusLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = LinkStatusLanguage.objects.all()
    serializer_class = LinkStatusLanguageSerializer

# External Link

class ExternalLinkFilter(filters.FilterSet):
    updatedDate = filters.DateTimeFilter(field_name='updatedDate', lookup_expr='lt')
    
    class Meta:
        model = Externalink
        fields = [
            'linkStatusId',
            'externallink_externallinklanguage__url',
            'updatedDate',
            "externallink_item__departmentId"
            ]

class ExternalLinkList(generics.ListCreateAPIView):
    queryset = Externalink.objects.all().order_by('id')
    serializer_class = ExternalinkSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_class = ExternalLinkFilter
    search_fields = ['id',]

class ExternalLinkDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Externalink.objects.all().order_by('id')
    serializer_class = ExternalinkSerializer

class ExternalLinkLanguageList(generics.ListCreateAPIView):
    queryset = ExternalLinkLanguage.objects.all()
    serializer_class = ExternalLinkLanguageSerializer
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['externalLinkId','languageId']

class ExternalLinkLanguageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = ExternalLinkLanguage.objects.all()
    serializer_class = ExternalLinkLanguageSerializer