import datetime
import json
import sys
import traceback
from calendar import monthrange
from datetime import timezone
from datetime import datetime
from datetime import date
import numpy as np
import pandas as pd
import requests
from apscheduler.schedulers.background import BackgroundScheduler
from dateutil.relativedelta import relativedelta
from django.db.models import Q
from django.http import HttpResponse
from django.template import loader
from xhtml2pdf import pisa

from payrollservice.util.masterutil import CodeUtil
from npayroll.settings import APPLICATION_BE_URL, logger,PAYROLL_TEST,micro_userservice
from payrollservice.controller import emppaystructurecontroller
from payrollservice.data.response.empmonthlypayinforesponse import Employeemonthly_payinfoResponse
from payrollservice.models import Employeemonthly_payinfo, EmployeePaystructure, EmployeePaystructure_details, \
    Employeeadditional_allowance, Employeemonthlypay_details, EmployeePaystructure_deductions, \
    Employeemonthlypay_deductions, Payrollprocesschange, Employeeadvancedetails, Employeeadvancepayment
from payrollservice.service.auditservice import AudtiService
from payrollservice.service.empmonthlypaydeductionservice import Employeemonthlypay_deductionsService
from payrollservice.service.empmonthlypaydetailsservice import Employeemonthlypay_detailsService
from payrollservice.service.payrollmastermappingservice import PayrollmastermappingService
from payrollservice.service.payrollmastersservice import PaycomponentFlagmasterService, EmployeePFService, \
    CompanyContributionService
from payrollservice.util.payrollutil import Activestatus, Advancetype, ModifyStatus, Advancestatus, advancestatus, \
    get_pf_type, FlagRef_Type, payrolldeduction_val, bonus_calculatetype, PayrollDeductionType, net_pay_calc
from utilityservice.data.response.empmessage import Error
from utilityservice.data.response.nwisefinerror import NWisefinError
from utilityservice.data.response.nwisefinlist import NWisefinList
from utilityservice.data.response.nwisefinpaginator import NWisefinPaginator
from utilityservice.data.response.nwisefinsuccess import NWisefinSuccess, SuccessStatus, SuccessMessage
from utilityservice.permissions.util.dbutil import RoleList, ModuleList
from utilityservice.service.applicationconstants import ApplicationNamespace
from utilityservice.service.payroll_api_service import Payrollcommon_Apicall
from utilityservice.service.threadlocal import NWisefinThread
from utilityservice.data.response.nwisefinerrorconstants import ErrorDescription, ErrorMessage
from django.utils import timezone
from payrollservice.models.payrollmodels import Payapprovedqueue, PayrollTest, payrollschedular, \
    PayrollManualRunSchedular

def payroll_schedular():
    # from utilityservice.service.defaultscopeservice import DefaultScopeScheduler
    from hrmsmasterapiservice.hrmsmasterapi.masteranduserserviceapi import HrmsApiService
    scope = HrmsApiService().scope_for_multiple_entity(1)
    manual = EmployeemonthlypayService(scope)
    sched_val = BackgroundScheduler()
    sched_val.add_job(manual.payroll_ser_schedular, 'cron',hour=17,minute=34,id='payroll_manual_run')
    sched_val.start()
    return True
class EmployeemonthlypayService(NWisefinThread):
    def __init__(self, scope):
        super().__init__(scope)
        self._set_namespace(ApplicationNamespace.PAYROLL_SERVICE)

    def create_employeemonth_payinfo(self, request, data_obj, user_id):
        success_obj = NWisefinSuccess()
        success_obj.set_status(SuccessStatus.SUCCESS)
        if data_obj.get_id() is not None:
            emp_pay = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(id=data_obj.get_id()).update(
                                                                                employee_id=data_obj.get_employee_id(),
                                                                                standard_ctc=data_obj.get_standard_ctc(),
                                                                                payable_days=data_obj.get_payable_days(),
                                                                                paid_days=data_obj.get_paid_days(),
                                                                                pay_status=data_obj.get_pay_status(),
                                                                                pay_mode=data_obj.get_pay_mode(),
                                                                                pf_type=data_obj.get_pf_type(),
                                                                                is_tds=data_obj.get_is_tds(),
                                                                                gross_pay=data_obj.get_gross_pay(),
                                                                                take_home=data_obj.get_take_home(),
                                                                                updated_by=user_id,
                                                                                updated_date=timezone.now(),
                                                                                entity_id=self._entity_id())
            emp_pay = Employeemonthly_payinfo.objects.using(self._current_app_schema()).get(id=data_obj.get_id())
            audit_insert_data = AudtiService(self._scope()).audit_function(emp_pay, emp_pay.id, emp_pay.employee_id,
                                                                           Advancetype.employeemonthly_payinfo,
                                                                           ModifyStatus.UPDATE)
            success_obj.set_message(SuccessMessage.UPDATE_MESSAGE)
        else:
            emp_pay = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                                                                employee_id=data_obj.get_employee_id(),
                                                                standard_ctc=data_obj.get_standard_ctc(),
                                                                payable_days=data_obj.get_payable_days(),
                                                                paid_days=data_obj.get_paid_days(),
                                                                pay_status=data_obj.get_pay_status(),
                                                                pf_type=data_obj.get_pf_type(),
                                                                pay_mode=data_obj.get_pay_mode(),
                                                                gross_pay=data_obj.get_gross_pay(),
                                                                is_tds=data_obj.get_is_tds(),
                                                                take_home=data_obj.get_take_home(),
                                                                created_by=user_id,
                                                                entity_id=self._entity_id())
            audit_insert_data = AudtiService(self._scope()).audit_function(emp_pay, emp_pay.id, emp_pay.employee_id,
                                                                           Advancetype.employeemonthly_payinfo,
                                                                           ModifyStatus.CREATE)

            success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
        success_obj.id = emp_pay.id
        success_obj.gross_pay = str(emp_pay.gross_pay)
        return success_obj


    def employeemonth_pay_level_get(self, employee_id):
        emp_val = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active,employee_id=employee_id)
        return emp_val

    def employeemonthly_pay_get(self, id):
        empmonth = Employeemonthly_payinfo.objects.using((self._current_app_schema())).get(status=Activestatus.active, id=id)
        data_resp = Employeemonthly_payinfoResponse()
        data_resp.set_id(empmonth.id)
        data_resp.set_standard_ctc(empmonth.standard_ctc)
        data_resp.set_payable_days(empmonth.payable_days)
        data_resp.set_paid_days(empmonth.paid_days)
        data_resp.set_pay_status(empmonth.pay_status)
        data_resp.set_pay_mode(empmonth.pay_mode)
        data_resp.set_is_tds(empmonth.is_tds)
        data_resp.set_gross_pay(empmonth.gross_pay)
        data_resp.set_payroll_date(empmonth.payroll_date)
        data_resp.set_take_home(empmonth.take_home)
        # employee_pay_obj = Payrollcommon_Apicall(self._scope()).get_emp_pf_info(empmonth.pf_type)
        employee_pay_obj = EmployeePFService(self._scope()).get_emp_pf_info(empmonth.pf_type)
        # employee_pay_obj = EmployeePFService(self._scope()).get_emp_pf_info(empmonth.pf_type)
        data_resp.set_pf_type(employee_pay_obj)
        return data_resp


    def employeemonthly_pay_inactive(self, id, user_id):
        emp_month = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(id=id).update(status=Activestatus.inactive, updated_by=user_id,updated_date=timezone.now())
        if emp_month>0:
            success_obj = NWisefinSuccess()
            success_obj.set_status(SuccessStatus.SUCCESS)
            success_obj.set_message(SuccessMessage.DELETE_MESSAGE)
        else:
            success_obj = NWisefinError()
            success_obj.set_code(ErrorMessage.UNEXPECTED_ERROR)
            success_obj.set_description(ErrorDescription.INVALID_DATA)
        return success_obj

        # Get Employeemonthly_payinfo,Employeemonthlypay_details
    def employeemonthpay_fetch(self, request, employee_id, month, year,info_id):
        try:
            condition = Q(entity_id=self._entity_id(), status=Activestatus.active, employee_id=employee_id,
                          payroll_date__month=month, payroll_date__year=year, id=info_id)
            # employee_id = request.GET.get('employee_id')
            # month = request.GET.get('month')
            # year = request.GET.get('year')
            # if employee_id != None and employee_id != "":
            #     condition &= Q(employee_id=employee_id)
            # if month != None and month != "":
            #     condition &= Q(created_date__month=month)
            # if year !=None and year != "":
            #     condition &= Q(created_date__year=year)
            emp_info = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(condition)
            list_data = NWisefinList()
            for i in emp_info:
                data_resp = Employeemonthly_payinfoResponse()
                data_resp.set_id(i.id)
                apifunction = Payrollcommon_Apicall(self._scope())
                emp_data = apifunction.emp_details_payroll(i.employee_id)
                # emp_data = self.employee_details(emp_info.employee_id)
                data_resp.employee = emp_data
                data_resp.set_standard_ctc(i.standard_ctc)
                data_resp.set_payable_days(i.payable_days)
                data_resp.set_paid_days(i.paid_days)
                data_resp.set_pay_mode(i.pay_mode)
                data_resp.set_code(i.code)
                data_resp.set_pay_status(i.pay_status)
                data_resp.set_is_tds(i.is_tds)
                data_resp.set_gross_pay(i.gross_pay)
                data_resp.set_payroll_date(i.payroll_date)
                data_resp.set_take_home(i.take_home)
                # employee_pay_obj = Payrollcommon_Apicall(self._scope()).get_emp_pf_info(i.pf_type)
                employee_pay_obj = EmployeePFService(self._scope()).get_emp_pf_info(i.pf_type)
                data_resp.pf_type = employee_pay_obj
                # employeepaydetail = self.emppaystrct_fetch(emp_info.id)
                # data_resp.Employeemonthlypay_details_data = employeepaydetail
                employeepaydetail = Employeemonthlypay_detailsService(self._scope()).employeemonthlypay_detail_get(i.id)
                data_resp.Employeempay_details_data = employeepaydetail
                earning_amount = round(float(employeepaydetail[0].sum_amount), 2)
                if i.is_deduct == 1:
                    employeepaydeduct = Employeemonthlypay_deductionsService(self._scope()).employeemonthpay_deduct(i.employee_id, month, year)
                    data_resp.deduction_data = employeepaydeduct
                    if len(employeepaydeduct) > 0:
                        deduct_amount = round(float(employeepaydeduct[0].sum_amount), 2)
                    else:
                        deduct_amount = float(0.00)
                else:
                    deduct_amount = float(0.00)
                net_pay = earning_amount - deduct_amount
                net_pay_calculate = net_pay_calc(net_pay)
                data_resp.Net_Pay = "{:.2f}".format(net_pay_calculate)
                # data_resp.month = month
                # data_resp.year = year
                import calendar
                month_name = calendar.month_name[int(month)].capitalize()
                data_resp.monthyear = f"{month_name} {year}"
                list_data.append(data_resp)
            return list_data
        except Exception as excep:
            obj = Error()
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(str(excep))
            return obj


    # #segment  Get Employeemonthly_payinfo,Employeemonthlypay_details
    def segment_employeemonthpay_fetch(self, request, employee_id, month, year, info_id):
        condition = Q(entity_id=self._entity_id(), status=Activestatus.active, employee_id=employee_id,
                      payroll_date__month=month, payroll_date__year=year, id=info_id)
        emp_info = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(condition)
        list_data = NWisefinList()
        for i in emp_info:
            data_resp = Employeemonthly_payinfoResponse()
            data_resp.set_id(i.id)
            apifunction = Payrollcommon_Apicall(self._scope())
            emp_data = apifunction.emp_details_payroll(i.employee_id)
            data_resp.employee = emp_data
            data_resp.set_standard_ctc(i.standard_ctc)
            data_resp.set_payable_days(i.payable_days)
            data_resp.set_paid_days(i.paid_days)
            data_resp.set_pay_mode(i.pay_mode)
            data_resp.set_code(i.code)
            data_resp.set_pay_status(i.pay_status)
            data_resp.set_is_tds(i.is_tds)
            data_resp.set_gross_pay(i.gross_pay)
            data_resp.set_payroll_date(i.payroll_date)
            data_resp.set_take_home(i.take_home)
            # employee_pay_obj = Payrollcommon_Apicall(self._scope()).get_emp_pf_info(i.pf_type)
            employee_pay_obj = EmployeePFService(self._scope()).get_emp_pf_info(i.pf_type)
            data_resp.pf_type = employee_pay_obj
            employeepaydetail = Employeemonthlypay_detailsService(self._scope()).segment_details(i.id)
            data_resp.segment_details = employeepaydetail
            if i.is_deduct == 1:
                employeepaydeduct = Employeemonthlypay_deductionsService(self._scope()).employeemonthpay_deduct(
                    i.employee_id, month, year)
                data_resp.deduction_data = employeepaydeduct
            list_data.append(data_resp)
        return list_data

        # summary Employeemonthly_payinfo,Employeemonthlypay_details,Employeemonthlypay_deductions
    def employeemonthpay_summary(self, request, vys_page,user_id):
        try:
            apifunction = Payrollcommon_Apicall(self._scope())
            condition = Q(entity_id=self._entity_id(), status=Activestatus.active)
            query = request.GET.get('employeename')
            month = request.GET.get('month')
            year = request.GET.get('year')
            pay_status = request.GET.get('paystatus')
            if query != None and query != "":
                apifunction = Payrollcommon_Apicall(self._scope())
                emp_list = apifunction.emp_arr_function(query)
                condition &= Q(employee_id__in=emp_list)
            if month != None and month != "":
                condition &= Q(payroll_date__month=month)
            if year != None and year != "":
                condition &= Q(payroll_date__year=year)
            if pay_status != None and pay_status != "":
                condition &= Q(pay_status=pay_status)
            module = ModuleList.Employee_Payroll
            hr_rights = apifunction.employee_role_check(user_id, module, None, None)
            if hr_rights == 1:
                emp_info = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(condition)[vys_page.get_offset():vys_page.get_query_limit()]
            else:
                emp_info = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(condition,employee_id=user_id)[vys_page.get_offset():vys_page.get_query_limit()]
            employeemon_obj_data = NWisefinList()
            if emp_info.count() > 0:
                employee_arr = [i.employee_id for i in emp_info]
                employee_data = apifunction.employee_data(employee_arr)
                id_arr = [i.id for i in emp_info]
                empmonth_details = Employeemonthlypay_detailsService(self._scope()).empmonthdetails_summary(id_arr)
                for empmonpay in emp_info:
                    data_resp = Employeemonthly_payinfoResponse()
                    data_resp.set_id(empmonpay.id)
                    data_resp.set_employee_val(empmonpay.employee_id, employee_data)
                    data_resp.set_standard_ctc(empmonpay.standard_ctc)
                    # data_resp.set_disability(empmonpay.disability)
                    data_resp.set_payable_days(empmonpay.payable_days)
                    data_resp.set_paid_days(empmonpay.paid_days)
                    data_resp.set_pay_mode(empmonpay.pay_mode)
                    data_resp.set_pay_status(empmonpay.pay_status)
                    data_resp.set_is_tds(empmonpay.is_tds)
                    data_resp.set_gross_pay(empmonpay.gross_pay)
                    data_resp.set_payroll_date(empmonpay.payroll_date)
                    if empmonpay.paid_date is not None:
                        data_resp.set_paid_date(empmonpay.paid_date)
                    else:
                        data_resp.paid_date = None
                    data_resp.set_take_home(empmonpay.take_home)
                    data_resp.set_remarks(empmonpay.remarks)
                    # employee_pay_obj = Payrollcommon_Apicall(self._scope()).get_emp_pf_info(empmonpay.pf_type)
                    employee_pay_obj = EmployeePFService(self._scope()).get_emp_pf_info(empmonpay.pf_type)
                    # employee_pay_obj = EmployeePFService(self._scope()).get_emp_pf_info(empmonpay.pf_type)
                    data_resp.pf_type = employee_pay_obj
                    data_resp.set_empmonthly_pay_val(empmonpay.id, empmonth_details)
                    if empmonpay.is_deduct == 1:
                        employeepaydeduct = Employeemonthlypay_deductionsService(self._scope()).employeemonthpay_deduct(empmonpay.employee_id, month, year)
                        data_resp.deduction_data = employeepaydeduct
                    else:
                        data_resp.deduction_data = []
                    data_resp.code = empmonpay.code
                    employeemon_obj_data.append(data_resp)
                vpage = NWisefinPaginator(emp_info, vys_page.get_index(), 10)
                employeemon_obj_data.set_pagination(vpage)
            else:
                vpage = NWisefinPaginator([], vys_page.get_index(), 10)
                employeemon_obj_data.set_pagination(vpage)
            return employeemon_obj_data
        except Exception as excep:
            obj = Error()
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(str(excep))
            return obj




    def employeemonthpay_excel(self, request,user_id):
        try:
            apifunction = Payrollcommon_Apicall(self._scope())
            condition = Q(entity_id=self._entity_id(), status=Activestatus.active)
            query = request.GET.get('employeename')
            month = request.GET.get('month')
            year = request.GET.get('year')
            pay_status = request.GET.get('paystatus')
            if query != None and query != "":
                emp_list = apifunction.emp_arr_function(query)
                condition &= Q(employee_id__in=emp_list)
            if month != None and month != "":
                condition &= Q(payroll_date__month=month)
            if year != None and year != "":
                condition &= Q(payroll_date__year=year)
            if pay_status != None and pay_status != "":
                condition &= Q(pay_status=pay_status)
            module = ModuleList.Employee_Payroll
            hr_rights = apifunction.employee_role_check(user_id, module, None,None)
            if hr_rights == 1:
                emp_info = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(condition)
            else:
                emp_info = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(condition,employee_id=user_id)
            employeemon_obj_data = NWisefinList()
            employee_arr = [i.employee_id for i in emp_info]
            apifunction = Payrollcommon_Apicall(self._scope())
            employee_data = apifunction.employee_data(employee_arr)
            for empmonpay in emp_info:
                data_resp = Employeemonthly_payinfoResponse()
                data_resp.set_employee_val1(empmonpay.employee_id, employee_data)
                # data_resp.set_standard_ctc(empmonpay.standard_ctc)
                data_resp.set_paid_days(empmonpay.paid_days)
                # data_resp.set_gross_pay(empmonpay.gross_pay)
                # data_resp.set_take_home(empmonpay.take_home)
                data = empmonpay.id
                print(data)
                data_resp.set_created_date(empmonpay.created_date)
                if empmonpay.paid_date is not None:
                    data_resp.set_paid_date(empmonpay.paid_date)
                else:
                    data_resp.paid_date = None
                data_resp.set_remarks(empmonpay.remarks)
                data_resp.set_created_date(empmonpay.created_date)
                employeepaydetail = Employeemonthlypay_detailsService(self._scope()).employeemonthlypay_detail_get(empmonpay.id)
                earning_amount = round(float(employeepaydetail[0].sum_amount),2)
                print(empmonpay.id)
                print(round(float(employeepaydetail[0].sum_amount),2))
                if empmonpay.is_deduct == 1:
                    employeepaydeduct = Employeemonthlypay_deductionsService(self._scope()).employeemonthpay_deduct(empmonpay.employee_id, month, year)
                    if len(employeepaydeduct) > 0:
                        deduct_amount = round(float(employeepaydeduct[0].sum_amount), 2)
                    else:
                        deduct_amount= float(0.00)
                else:
                    deduct_amount = float(0.00)
                net_pay = earning_amount - deduct_amount
                data_resp.Net_Pay = net_pay
                employeemon_obj_data.append(data_resp)
            return employeemon_obj_data
        except Exception as excep:
            obj = Error()
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(str(excep))
            return obj



    # maunal_run
    def details_manual_run(self):
        success_obj = NWisefinSuccess()
        try:
            schedular = payrollschedular.objects.using(self._current_app_schema()).create(start=timezone.now(), created_date=timezone.now(),created_by=1)
            from datetime import datetime
            date_time = datetime.now()
            month = int(date_time.strftime("%m"))
            year = int(date_time.strftime("%Y"))
            currentMonth = datetime.now().month
            currentYear = datetime.now().year
            logger.info("-----PAYROLL_MANUAL_RUN_START------")
            if PAYROLL_TEST == 'TRUE':
                emp_url = APPLICATION_BE_URL + '/payrollserv/payroll_test_attendance_summary'
            else:
                emp_url = APPLICATION_BE_URL + '/atdserv/payroll_attendance_summary'
            data = {"month": month, "year": year}
            json_data = json.dumps(data)
            ip_address = APPLICATION_BE_URL + '/usrserv/auth_token'
            username = 'apuser'
            password = '1234'
            logger.info("------EMPLOYEE ATTENDANCE API CALL BEFORE--------" + str(emp_url))
            datas = json.dumps({"username": username, "password": password, "entity_id": 1})
            resp = requests.post(ip_address, data=datas, verify=False)
            token_data = json.loads(resp.content.decode("utf-8"))
            headers = {"content-type": "application/json", "Authorization": "Token " + token_data["token"] + ""}
            logger.info("TOKEN DATAS" + str(datas) and "TOKEN GENERATE" + str(headers))
            resp_obj = requests.post("" + emp_url, params='', data=json_data, headers=headers, verify=False)
            logger.info("------EMPLOYEE ATTENDANCE API CALL AFTER RESPONSE STATUS CODE--------" + str(resp_obj.status_code))
            emp_data_values = json.loads(resp_obj.content.decode("utf-8"))
            data_get = emp_data_values.get('data')
            logger.info("------EMPLOYEE ATTENDANCE API CALL AFTER--------" + str(data_get))
            arr = []
            for j in data_get:
                emp_id = j['employee_id']
                arr.append(emp_id)
            obj_val = EmployeePaystructure.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id__in=arr)
            list_val = [i.id for i in obj_val]
            obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, emp_pay_id__in=list_val)

            for i in obj_val:
                for j in data_get:
                    if i.employee_id == j['employee_id']:
                        month_pay = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, payroll_date__month=month, payroll_date__year=year, employee_id=i.employee_id)
                        if month_pay.count() > 0:
                            allowance_date = Employeeadditional_allowance.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id, active_date__month__lte=currentMonth, end_date__month__gte=currentMonth, active_date__year__lte=currentYear, end_date__year__gte=currentYear)
                            for a in allowance_date:
                                employee = a.employee_id
                                type = a.type
                                # payroll_mastermap = Payrollcommon_Apicall(self._scope()).get_segment_based_paycom(a.type)
                                payroll_mastermap = PayrollmastermappingService(self._scope()).get_segment_based_paycom(a.type)
                                if payroll_mastermap == []:
                                    payroll_mastermap = None
                                active_date = a.active_date
                                end_date = a.end_date
                                amount = a.amount
                                details = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, empmonthly_pay__employee_id=i.employee_id, paycomponent=type, from_date=active_date, to_date=end_date, amount=amount)
                                if details.count() > 0:
                                    continue
                                else:
                                    if a.custom_deduct == 0:
                                        paid_days = j['paid_days']
                                        payable_days = j['payable_days']
                                        employee_id = i.employee_id
                                        gross_pay = (float(i.gross_pay) * paid_days) / payable_days
                                        take_home = (float(i.take_home ) * paid_days) / payable_days
                                        standard_ctc = (float(i.standard_ctc) * paid_days) / payable_days
                                        logger.info("------EMPLOYEE MONTHLY INFO GROSS_PAY AMOUNT--------" + str(gross_pay))
                                        obj_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                                                                                                                        employee_id=employee_id,
                                                                                                                        standard_ctc=standard_ctc,
                                                                                                                        payable_days=payable_days,
                                                                                                                        paid_days=paid_days,
                                                                                                                        take_home=take_home,
                                                                                                                        created_by=1,
                                                                                                                        # created_date=date_time,
                                                                                                                        payroll_date=date_time.date(),
                                                                                                                        gross_pay=gross_pay,
                                                                                                                        pay_status=Advancestatus.draft)
                                        apifunction = Payrollcommon_Apicall(self._scope())
                                        code = apifunction.payslip_gen_code(CodeUtil.Employeemonthly_payinfo, 1,
                                                                            i.employee_id)
                                        logger.info("-----Employeemonthly_payinfo Code-----" + str(code))
                                        obj_data.code = code
                                        obj_data.save()

                                        emp_details = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                                                                    empmonthly_pay_id=obj_data.id,
                                                                                                    paycomponent=type,
                                                                                                    from_date=active_date,
                                                                                                    to_date=end_date,
                                                                                                    created_by=1,
                                                                                                    # created_date=date_time,
                                                                                                    entity_id=self._entity_id(),
                                                                                                    segment=payroll_mastermap,
                                                                                                    amount=amount)
                                    else:
                                        dedcut_data1 = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                               deduct_date__month=month,
                                                                               deduct_date__year=year,
                                                                               employee_id=i.employee_id,
                                                                               paycomponent_id=type)
                                        if dedcut_data1.count() > 0:
                                            continue
                                        else:
                                            deduct_data = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                                                                        employee_id=employee,
                                                                                                        paycomponent_id=type,
                                                                                                        from_date=active_date,
                                                                                                        to_date=end_date,
                                                                                                        amount=amount,
                                                                                                        created_by=1,
                                                                                                        deduction_status=1,
                                                                                                        deduct_date=date_time.date())
                                                                                                        # created_date=date_time)
                                    continue
                        else:
                            paid_days = j['paid_days']
                            payable_days = j['payable_days']
                            employee_id = i.employee_id
                            is_esi = i.is_esi
                            pf_type = i.pf_type
                            gross_pay = (float(i.gross_pay) * paid_days) / payable_days
                            logger.info("------EMPLOYEE MONTHLY INFO GROSSPAY AMOUNT--------" + str(gross_pay))
                            #formula

                            take_home = (float(i.take_home) * paid_days) / payable_days
                            standard_ctc = (float(i.standard_ctc) * paid_days) / payable_days
                            obj_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                                                                                                            employee_id=employee_id,
                                                                                                            standard_ctc=standard_ctc,
                                                                                                            payable_days=payable_days,
                                                                                                            paid_days=paid_days,
                                                                                                            take_home=take_home,
                                                                                                            payroll_date=date_time.date(),
                                                                                                            created_by=1,
                                                                                                            gross_pay=gross_pay,
                                                                                                            pay_status=Advancestatus.draft,
                                                                                                            is_deduct=1)
                            apifunction = Payrollcommon_Apicall(self._scope())
                            code = apifunction.payslip_gen_code(CodeUtil.Employeemonthly_payinfo, 1, i.employee_id)
                            logger.info("-----Employeemonthly_payinfo Code-----" + str(code))
                            obj_data.code = code
                            obj_data.save()

                            if obj_data.id > 0:
                                monthly_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, emp_pay__employee_id=employee_id)
                                if monthly_details.count() > 0:
                                    for k in monthly_details:
                                        paycomponent = k.paycomponent
                                        paycomponent_type = k.paycomponent_type
                                        paycomponent_percentage = k.paycomponent_percentage
                                        segment_percentage = k.segment_percentage
                                        data_amt = k.amount
                                        segment = k.segment
                                        print(data_amt)
                                        company_contribution = k.company_contribution
                                        type = k.type
                                        from_date = k.from_date
                                        to_date = k.to_date
                                        if is_esi is (True or False) or get_pf_type(pf_type)['name'] == ('NORMAL_PF' or 'STANDARD_PF' or 'VIRTUAL_PF'):
                                            if company_contribution is True:
                                                from django.db.models import Sum
                                                # pf = Payrollcommon_Apicall(self._scope()).company_contribution_data(paycomponent)[0]
                                                pf = CompanyContributionService(self._scope()).company_contribution_data(paycomponent)[0]
                                                if get_pf_type(pf_type)['name'] == 'NORMAL_PF' or is_esi is (True or False):
                                                    # pf = CompanyContribution.objects.using(self._current_app_schema()).filter(status=1,id=paycomponent).values('id', 'name', 'percentage', 'amount')[0]
                                                    # flag_master=list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(map_id=pf.id).value_list('id'))
                                                    # flag_master = Payrollcommon_Apicall(self._scope()).list_of_map_id_data(pf['id'])
                                                    # flag_master = Payrollcommon_Apicall(self._scope()).cc_epf_based_paycom(pf['id'],FlagRef_Type.COMPANYCONTRIBUTION)
                                                    flag_master = PaycomponentFlagmasterService(self._scope()).cc_epf_based_paycom(pf['id'],FlagRef_Type.COMPANYCONTRIBUTION)
                                                    # flag_master = list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(status=1, map_id=pf['id']).values_list('ref_id', flat=True))
                                                    print(flag_master)
                                                    sum_amt = Employeemonthlypay_details.objects.using(
                                                        self._current_app_schema()).filter(status=Activestatus.active,
                                                                                           paycomponent__in=flag_master,
                                                                                           empmonthly_pay__employee_id=employee_id,
                                                                                           empmonthly_pay__payroll_date__month=month,
                                                                                           empmonthly_pay__payroll_date__year=year,
                                                                                           company_contribution=False).aggregate(
                                                        Sum('amount'))
                                                    logger.info( "------COMPANY CONTRIBUTION SUM_AMT--------" + str(sum_amt))
                                                    sum_prec = float(sum_amt['amount__sum']) * float(
                                                        pf['percentage']) / 100
                                                    if sum_amt['amount__sum'] != None:
                                                        print(sum_amt, 'iuh')
                                                        if pf['sal_amount'] == 0.00 or None:
                                                            if pf['amount'] < sum_prec:
                                                                amount = round(pf['amount'])
                                                            else:
                                                                amount = round(sum_prec)
                                                        else:
                                                            if is_esi is False:
                                                                amount = 0.00
                                                            else:
                                                                if sum_amt['amount__sum'] <= pf['sal_amount']:
                                                                    amount = round(sum_prec)
                                                                else:
                                                                    amount = 0.00
                                                    else:
                                                        amount = 0.00
                                                else:
                                                    amount = round(pf['amount'])
                                            elif type != None:
                                                # created_dated = k.created_date.month
                                                # if created_dated == month:
                                                if payrolldeduction_val(type)['name'] == 'MONTHLY':
                                                    amount = round(float(data_amt) * paid_days / float(payable_days))
                                                    logger.info("------MONTHLY AMOUNT--------" + str(amount))
                                                elif payrolldeduction_val(type)['name'] == 'QUERTELY' or 'HALFYEARLY' or 'YEARLY'or 'CUSTOM':
                                                    month_data = self.bonus_month(type, month, year, date_time,from_date,to_date)
                                                    if month_data is None:
                                                        continue
                                                    else:
                                                        for y in month_data:
                                                            emp_id = y['employee_id']
                                                            if employee_id == emp_id:
                                                                month_paid = y['paid_days']
                                                                month_payable = y['payable_days']
                                                                amount = round(float(data_amt) * month_paid / float(month_payable))
                                                                logger.info( "------'QUERTELY' or 'HALFYEARLY' or 'YEARLY' CALCULATION--------" + str(amount))
                                            elif company_contribution is False or type is False:
                                                cal_amount = float(gross_pay) * float(segment_percentage) / 100
                                                amount = float(cal_amount) * float(paycomponent_percentage) / 100


                                        else:
                                            amount = 0.00

                                        data = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                            empmonthly_pay_id=obj_data.id,
                                            paycomponent=paycomponent,
                                            paycomponent_type=paycomponent_type,
                                            paycomponent_percentage=paycomponent_percentage,
                                            company_contribution=company_contribution,
                                            segment=segment,
                                            amount=amount,
                                            type=type,
                                            created_by=1,
                                            segment_percentage=segment_percentage)
                                        logger.info( "------Employeemonthlypay_details Create success--------" + str(data.id))
                                        continue

                            deduction_data = EmployeePaystructure_deductions.objects.using(self._current_app_schema()).filter(status=Activestatus.active,employee_id=i.employee_id)
                            if deduction_data.count() > 0:
                                for g in deduction_data:
                                    if g.is_customdeduct == 1:
                                        deduction_status = 1
                                    else:
                                        deduction_status = -1
                                    employee_id = g.employee_id
                                    paycomponent_id = g.paycomponent_id
                                    type = g.type
                                    if type == PayrollDeductionType.CUSTOM:
                                        from_date = g.from_date
                                        to_date = g.to_date
                                    else:
                                        from_date = date_time.date()
                                        to_date = date_time.date()
                                    amount = g.amount
                                    # if (deduction_status == 1 and type == PayrollDeductionType.CUSTOM) or deduction_status == -1:
                                    if from_date.month <= month and to_date.month >= month and from_date.year <= year and to_date.year >= year:
                                        logger.info('--------------------------PAYSTRUCTURE DEDUCT TO MONTHLY DEDUCT DATA CUSTOM DEDUCTION-----------------------------------------------------------')
                                        if deduction_status == -1:
                                            deduction_cal = self.monthly_deduction_calculation(employee_id, paycomponent_id, month,year, is_esi, pf_type)
                                        else:
                                            deduction_cal = amount
                                        deduction = Employeemonthlypay_deductions.objects.using( self._current_app_schema()).create(employee_id=employee_id,
                                                                               paycomponent_id=paycomponent_id,
                                                                               type=type,
                                                                               from_date=from_date,
                                                                               to_date=to_date,
                                                                               amount=deduction_cal,
                                                                               created_by=1,
                                                                               deduct_date=date_time.date(),
                                                                               deduction_status=deduction_status)
                                        logger.info("------Employeemonthlypay_deductions Create success--------" + str(deduction.id))

                            process_data = Payrollprocesschange.objects.using(self._current_app_schema()).filter(status=Activestatus.active,employee_id=i.employee_id, from_date__month__lte=currentMonth, to_date__month__gte=currentMonth, from_date__year__lte=currentYear,to_date__year__gte=currentYear)
                            if process_data.count() > 0:
                                for m in process_data:
                                    employee_id = m.employee_id
                                    pay_change = m.pay_change
                                    Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=employee_id).update(pay_status=pay_change)
                                    logger.info("------EMPLOYEEMONTHLY_PAYINFO UPDATED PAY_STATUS--------" +str(pay_change))

                            allowance_date=Employeeadditional_allowance.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id, active_date__month__lte=currentMonth, end_date__month__gte=currentMonth, active_date__year__lte=currentYear, end_date__year__gte=currentYear)
                            if allowance_date.count() > 0:
                                for a in allowance_date:
                                    employee=a.employee_id
                                    type=a.type
                                    # payroll_mastermap = Payrollcommon_Apicall(self._scope()).get_segment_based_paycom(a.type)
                                    payroll_mastermap = PayrollmastermappingService(self._scope()).get_segment_based_paycom(a.type)
                                    if payroll_mastermap == []:
                                        payroll_mastermap = None
                                    active_date=a.active_date
                                    end_date=a.end_date
                                    amount=a.amount
                                    month_details = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=employee, payroll_date__month=currentMonth, payroll_date__year=currentYear)
                                    if month_details.count() > 0:
                                        if a.custom_deduct == 0:
                                            details = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(empmonthly_pay_id=month_details[0].id,paycomponent=type,from_date=active_date,to_date=end_date,amount=amount)
                                            if details.count() > 0:
                                                continue
                                            else:
                                                emp_details = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                empmonthly_pay_id=month_details[0].id,
                                                paycomponent=type,
                                                from_date=active_date,
                                                to_date=end_date,
                                                created_by=1,
                                                # created_date=date_time,
                                                segment = payroll_mastermap,
                                                # entity_id=self._entity_id(),
                                                amount=amount)
                                                logger.info("------Employeemonthlypay_details Create success--------" + str(emp_details.id))
                                        else:
                                            deduct_data = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                                                                employee_id=employee,
                                                                                                paycomponent_id=type,
                                                                                                from_date=active_date,
                                                                                                to_date=end_date,
                                                                                                amount=amount,
                                                                                                deduction_status=1,
                                                                                                created_by=1,
                                                                                                deduct_date=date_time.date())
                                                                                                # created_date=date_time)
                                        continue
                                        # advance
                            advance_pay = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(status=Activestatus.active, advance__employee_id=i.employee_id,
                                            advance__from_date__month__lte=month, advance__to_date__month__gte=month,
                                            advance__from_date__year__lte=year, advance__to_date__year__gte=year)
                            if advance_pay.count() > 0:
                                advance_id = [i.advance_id for i in advance_pay]
                                unique_advance_id = list(set(advance_id))
                                for ids in unique_advance_id:
                                    advance1 = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(status=Activestatus.active,advance__id=ids).values('id',
                                                                                                   'advance_id',  'balance_amount',  'advance__emi_amount',
                                                                                                   'advance__employee_id', 'advance__from_date', 'advance__to_date').last()
                                    if advance1 is not None:
                                        # if advance1.count() > 0:
                                        if advance1['balance_amount'] == 0.00 or None:
                                            update = Employeeadvancedetails.objects.using( self._current_app_schema()).filter(id=advance1['advance_id']).update(
                                                advance_status=Advancestatus.closed, updated_by=1,
                                                updated_date=date_time)
                                            logger.info("-----Employeeadvancedetails update status closed emi bal=0---------" + str( advance1['advance_id']))
                                            continue
                                        else:
                                            advance_id = advance1['advance_id']
                                            paid_amount = advance1['advance__emi_amount']
                                            balance_amount = advance1['balance_amount']
                                            employee_payment = advance1['advance__employee_id']
                                            from_date_payment = advance1['advance__from_date']
                                            to_date_payment = advance1['advance__to_date']
                                            amount = abs(float(paid_amount - balance_amount))
                                            # advance_type = Advancetype.advance
                                            advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=advance_id,
                                                                                   paid_date=date_time,
                                                                                   balance_amount=amount,
                                                                                   paid_amount=paid_amount,
                                                                                   created_by=1,
                                                                                   created_date=date_time)

                                            logger.info( "------Employeeadvancepayment Create success--------" + str( advancepayment.id))

                                            advance_deduct = Employeemonthlypay_deductions.objects.using(
                                                self._current_app_schema()).create(
                                                employee_id=employee_payment,
                                                from_date=from_date_payment,
                                                to_date=to_date_payment,
                                                amount=paid_amount,
                                                created_by=1,
                                                deduction_status=1,
                                                deduct_date=date_time.date(),
                                                created_date=date_time,
                                                is_advance=1)
                                            logger.info( "------Employeemonthlypay_deductions Create success--------" + str( advance_deduct.id))

                                        # second advance create
                                        condition = ~Q(id__in=unique_advance_id)
                                        advancedetails1 = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(condition,
                                                                               status=Activestatus.active,
                                                                               employee_id=i.employee_id,
                                                                               advance_status=Advancestatus.paid,
                                                                               from_date__month__lte=month,
                                                                               to_date__month__gte=month,
                                                                               from_date__year__lte=year,
                                                                               to_date__year__gte=year)
                                        if advancedetails1.count() > 0:
                                            for s1 in advancedetails1:
                                                id = s1.id
                                                paid_amount = s1.emi_amount
                                                deduct_advance_employee = s1.employee_id
                                                balance_amount = abs(float(s1.payable_amount - paid_amount))
                                                from_date = s1.from_date
                                                to_date = s1.to_date
                                                advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                                                                                       paid_date=date_time,
                                                                                       balance_amount=balance_amount,
                                                                                       paid_amount=paid_amount,
                                                                                       created_by=1,
                                                                                       created_date=date_time)
                                                logger.info( "-----Employeeadvancepayment create success---------" + str(advancepayment.id))
                                                update = Employeeadvancedetails.objects.using(
                                                    self._current_app_schema()).filter(id=id).update(
                                                    advance_status=Advancestatus.open, updated_by=1,
                                                    updated_date=date_time)
                                                logger.info( "-----Employeeadvancedetails update status open emi bal>0---------" + str( update.id))

                                                advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                    employee_id=deduct_advance_employee,
                                                    from_date=from_date,
                                                    to_date=to_date,
                                                    amount=paid_amount,
                                                    created_by=1,
                                                    deduction_status=1,
                                                    deduct_date=date_time.date(),
                                                    created_date=date_time,
                                                    is_advance=1)

                                    continue
                            else:
                                advancedetails = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                       employee_id=i.employee_id,
                                                                       advance_status=Advancestatus.paid,
                                                                       from_date__month__lte=month,
                                                                       to_date__month__gte=month,
                                                                       from_date__year__lte=year,
                                                                       to_date__year__gte=year)
                                if advancedetails.count() > 0:
                                    for s in advancedetails:
                                        id = s.id
                                        paid_amount = s.emi_amount
                                        deduct_advance_employee = s.employee_id
                                        balance_amount = abs(float(s.payable_amount - paid_amount))
                                        from_date = s.from_date
                                        to_date = s.to_date
                                        advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                                                                               paid_date=date_time,
                                                                               balance_amount=balance_amount,
                                                                               paid_amount=paid_amount,
                                                                               created_by=1,
                                                                               created_date=date_time)
                                        logger.info( "-----Employeeadvancepayment create success---------" + str(advancepayment.id))
                                        update = Employeeadvancedetails.objects.using(
                                            self._current_app_schema()).filter(id=id).update(
                                            advance_status=Advancestatus.open, updated_by=1,
                                            updated_date=date_time)
                                        logger.info("-----Employeeadvancedetails update status open emi bal>0---------" + str( id))

                                        advance_deduct = Employeemonthlypay_deductions.objects.using(
                                            self._current_app_schema()).create(
                                            employee_id=deduct_advance_employee,
                                            from_date=from_date,
                                            to_date=to_date,
                                            amount=paid_amount,
                                            created_by=1,
                                            deduction_status=1,
                                            deduct_date=date_time.date(),
                                            created_date=date_time,
                                            is_advance=1)
                                        logger.info("-----Employeemonthlypay_deductions create success---------" + str(advance_deduct.id))
                            # advance_pay = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(status=Activestatus.active, advance__employee_id=i.employee_id,advance__from_date__month__lte=month, advance__to_date__month__gte=month, advance__from_date__year__lte=year, advance__to_date__year__gte=year).values('id', 'advance_id',  'balance_amount', 'advance__emi_amount', 'advance__employee_id',  'advance__from_date', 'advance__to_date').last()
                            # if advance_pay is not None:
                            #     # for advance in advance_pay:
                            #     if advance_pay['balance_amount'] == 0.00 or None:
                            #         continue
                            #     else:
                            #         advance_id = advance_pay['advance_id']
                            #         paid_amount = advance_pay['advance__emi_amount']
                            #         balance_amount = advance_pay['balance_amount']
                            #         employee_payment = advance_pay['advance__employee_id']
                            #         from_date_payment = advance_pay['advance__from_date']
                            #         to_date_payment = advance_pay['advance__to_date']
                            #         amount = abs(float(paid_amount - balance_amount))
                            #         # advance_type = 11
                            #         advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=advance_id,
                            #                                                                                                paid_date=date_time,
                            #                                                                                                balance_amount=amount,
                            #                                                                                                paid_amount=paid_amount,
                            #                                                                                                created_by=1)
                            #                                                                                                # created_date=date_time)
                            #
                            #         advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=employee_payment,
                            #                                                # paycomponent_id=advance_type,
                            #                                                from_date=from_date_payment,
                            #                                                to_date=to_date_payment,
                            #                                                amount=paid_amount,
                            #                                                created_by=1,
                            #                                                deduction_status=1,
                            #                                                deduct_date=date_time.date(),
                            #                                                # created_date=date_time,
                            #                                                is_advance=1)
                            # advancedetails = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id, advance_status=Advancestatus.paid, from_date__month__lte=month,  to_date__month__gte=month,  from_date__year__lte=year, to_date__year__gte=year)
                            # if advancedetails.count() > 0:
                            #     for s in advancedetails:
                            #         id = s.id
                            #         paid_amount = s.emi_amount
                            #         deduct_advance_employee = s.employee_id
                            #         balance_amount = float(s.payable_amount - paid_amount)
                            #         # advance_type = 11
                            #         from_date = s.from_date
                            #         to_date = s.to_date
                            #         advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                            #                                                                                    paid_date=date_time,
                            #                                                                                    balance_amount=balance_amount,
                            #                                                                                    paid_amount=paid_amount,
                            #                                                                                    created_by=1)
                            #                                                                                    # created_date=date_time)
                            #
                            #         advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=deduct_advance_employee,
                            #                                                                                        # paycomponent_id=advance_type,
                            #                                                                                        from_date=from_date,
                            #                                                                                        to_date=to_date,
                            #                                                                                        amount=paid_amount,
                            #                                                                                        created_by=1,
                            #                                                                                        deduction_status=1,
                            #                                                                                        deduct_date=date_time.date(),
                            #                                                                                        # created_date=date_time,
                            #                                                                                        is_advance=1)

            success_obj.set_status(SuccessStatus.SUCCESS)
            success_obj.set_message('DATA INSERTED SUCCESSFULLY')
            schedular2 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update(
                end=timezone.now(), message='DATA INSERTED SUCCESSFULLY')
            return success_obj
        except Exception as excep:
            obj = Error()
            obj.payrollmanual_run = {"error": str(excep)}
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(ErrorDescription.ALREADY_EXISTS)
            schedular3 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update(end=timezone.now(), message=str(excep))
            return obj

    # manual_run function
    def monthly_deduction_calculation(self, employee_id, paycomponent_id,month,year,is_esi, pf_type):
        # pf_data_calculation = Payrollcommon_Apicall(self._scope()).cal_employeepf_data(paycomponent_id)
        pf_data_calculation = EmployeePFService(self._scope()).cal_employeepf_data(paycomponent_id)
        if is_esi is (True or False) or get_pf_type(pf_type)['name'] == 'NORMAL_PF' or 'VIRTUAL_PF':
            # if is_esi is True:
                # flag_master = Payrollcommon_Apicall(self._scope()).cc_epf_based_paycom(pf_data_calculation['id'],FlagRef_Type.PF)
                flag_master = PaycomponentFlagmasterService(self._scope()).cc_epf_based_paycom(pf_data_calculation['id'],FlagRef_Type.PF)
                emp_details = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(paycomponent__in=flag_master, empmonthly_pay__employee_id=employee_id, company_contribution=False,status=Activestatus.active,empmonthly_pay__payroll_date__month=month, empmonthly_pay__payroll_date__year=year)
                amount = [i.amount for i in emp_details]
                sum_amount = sum(amount)
                pf_data_calculation_values = float(pf_data_calculation['percentage'])
                final_calculation = float(sum_amount) * pf_data_calculation_values / 100
                if get_pf_type(pf_type)['name'] == 'NORMAL_PF' or is_esi is (True or False):
                    if pf_data_calculation['sal_amount'] == 0.00 or None:
                        if pf_data_calculation['amount'] < final_calculation:
                            amount = round(pf_data_calculation['amount'])
                        else:
                            amount = round(final_calculation)
                    else:
                        if is_esi is False:
                            amount = 0.00
                        else:
                            if sum_amount <= pf_data_calculation['sal_amount']:
                                amount = round(final_calculation)
                            else:
                                amount = 0.00
                else:
                    amount = round(final_calculation)
            # else:
                # amount = 0.00
        else:
            amount = round(pf_data_calculation['amount'])
        return amount

    # manual_run function
    def bonus_month(self, type,month,year,date_time,from_date, to_date):
        # date_time = datetime.datetime.now()
        # month = int(date_time.month)
        # year = int(date_time.year)
        from_month,to_month,from_year,to_year = (None,)*4
        success_obj = NWisefinSuccess()
        if payrolldeduction_val(type)['name'] == 'QUARTERLY' or 'HALFYEARLY' or 'YEARLY':
            querterly_month = bonus_calculatetype().set_bonustype(type)
            for i in querterly_month['values']:
                if month == i:
                    if querterly_month['text']=='QUARTERLY':
                        from_month1 = date_time + relativedelta(months=-2)
                        from_month = from_month1.month
                        to_month = month
                        from_year = from_month1.year
                        to_year = year
                    elif querterly_month['text']=='HALFYEARLY':
                        from_month1 = date_time + relativedelta(months=-5)
                        from_month = from_month1.month
                        to_month = month
                        from_year = from_month1.year
                        to_year = year
                    elif querterly_month['text']=='YEARLY':
                        from_month1 = date_time + relativedelta(months=-11)
                        from_month = from_month1.month
                        to_month = month
                        from_year = from_month1.year
                        to_year = year
        elif payrolldeduction_val(type)['name'] == 'CUSTOM':
            from_month = from_date.month
            to_month = to_date.month
            from_year = from_date.year
            to_year = to_date.year #(from_month !=None and from_month !="")

        if from_month is None and to_month is None and from_year is None and to_year is None:
            return None
        else:
            if PAYROLL_TEST == 'TRUE':
                emp_url = APPLICATION_BE_URL + '/payrollserv/payroll_test_present_count'+ "?from_month="+ str(from_month) + "&to_month="+str(to_month) + "&from_year="+str(from_year) +"&to_year="+str(to_year)
            else:
                emp_url = APPLICATION_BE_URL + '/atdserv/payroll_present_count'+ "?from_month="+ str(from_month) + "&to_month="+str(to_month) + "&from_year="+str(from_year) +"&to_year="+str(to_year)
            ip_address = APPLICATION_BE_URL + '/usrserv/auth_token'
            username = 'apuser'
            password = '1234'
            datas = json.dumps({"username": username, "password": password, "entity_id": 1})
            resp = requests.post(ip_address, data=datas, verify=False)
            token_data = json.loads(resp.content.decode("utf-8"))
            headers = {"content-type": "application/json", "Authorization": "Token " + token_data["token"] + ""}
            logger.info("------EMPLOYEE ATTENDANCE API CALL BEFORE--------" + str(emp_url))
            resp_obj = requests.get(emp_url, headers=headers, verify=False)
            logger.info("------EMPLOYEE ATTENDANCE API CALL AFTER RESPONSE STATUS CODE--------" + str(resp_obj.status_code))
            emp_data_values = json.loads(resp_obj.content.decode("utf-8"))
            data_get = emp_data_values.get('data')
            logger.info("------EMPLOYEE ATTENDANCE API CALL AFTER RESPONSE--------" +str(data_get))
            print("EMPLOYEE ATTENDANCE API CALL AFTER RESPONSE" + str(data_get))
            return data_get


    def payroll_manual_run(self, request):
        success_obj = NWisefinSuccess()
        try:
            schedular = payrollschedular.objects.using(self._current_app_schema()).create(start=timezone.now(),created_date=timezone.now(),created_by=1)
            year1 = request.GET.get('year')
            month1 = request.GET.get('month')
            if (year1 != None and year1!='') and (month1 != None and month1 != ''):
                year = int(year1)
                month = int(month1)
                logger.info("-----PAYROLL_MANUAL_RUN_START------")
                # from datetime import datetime
                # date_time = datetime.now()
                from datetime import datetime, timedelta
                date_time = datetime(year, month + 1, 1) + timedelta(days=-1)
                if PAYROLL_TEST == 'TRUE':
                    emp_url = APPLICATION_BE_URL + '/payrollserv/payroll_test_attendance_summary'
                else:
                    emp_url = micro_userservice + '/atdserv/payroll_attendance_summary'
                data = {"month": month, "year": year}
                json_data = json.dumps(data)
                ip_address = micro_userservice + '/usrserv/auth_token'
                username = 'apuser'
                password = '1234'
                logger.info("------EMPLOYEE ATTENDANCE API CALL BEFORE--------" + str(emp_url))
                datas = json.dumps({"username": username, "password": password, "entity_id": 1})
                resp = requests.post(ip_address, data=datas, verify=False)
                token_data = json.loads(resp.content.decode("utf-8"))
                headers = {"content-type": "application/json", "Authorization": "Token " + token_data["token"] + ""}
                logger.info("TOKEN DATAS" +str(datas) and "TOKEN GENERATE" + str(headers))
                resp_obj = requests.post("" + emp_url, params='', data=json_data, headers=headers, verify=False)
                logger.info("------EMPLOYEE ATTENDANCE API CALL AFTER RESPONSE STATUS CODE--------" + str(resp_obj.status_code))
                emp_data_values = json.loads(resp_obj.content.decode("utf-8"))
                data_get = emp_data_values.get('data')
                df_data = pd.DataFrame(data_get)
                duplicates = df_data.drop_duplicates()
                data_val = duplicates.to_dict(orient='records')
                logger.info("------EMPLOYEE ATTENDANCE API CALL AFTER--------" + str(data_get))
                arr = []
                for j in data_val:
                    emp_id = j['employee_id']
                    arr.append(emp_id)
                val = set(arr)
                val = list(val)
                obj_val = EmployeePaystructure.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id__in=val)
                list_val = [i.id for i in obj_val]
                obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, emp_pay_id__in=list_val)

                for i in obj_val:
                    for j in data_val:
                        if i.employee_id == j['employee_id']:
                            month_pay = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, payroll_date__month=month, payroll_date__year=year, employee_id=i.employee_id)
                            if month_pay.count() > 0:
                                allowance_date = Employeeadditional_allowance.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id, active_date__month__lte=month, end_date__month__gte=month, active_date__year__lte=year, end_date__year__gte=year)
                                for a in allowance_date:
                                    employee = a.employee_id
                                    type = a.type
                                    # payroll_mastermap = Payrollcommon_Apicall(self._scope()).get_segment_based_paycom(a.type)
                                    payroll_mastermap = PayrollmastermappingService(self._scope()).get_segment_based_paycom(a.type)
                                    if payroll_mastermap == []:
                                        payroll_mastermap = None
                                    active_date = a.active_date
                                    end_date = a.end_date
                                    amount = a.amount
                                    details = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, empmonthly_pay__employee_id=i.employee_id, paycomponent=type, from_date=active_date, to_date=end_date, amount=amount,empmonthly_pay__payroll_date__month=month)
                                    if details.count() > 0:
                                        continue
                                    else:
                                        if a.custom_deduct == 0:
                                            paid_days = j['paid_days']
                                            payable_days = j['payable_days']
                                            employee_id = i.employee_id
                                            gross_pay = (float(i.gross_pay) * paid_days) / payable_days
                                            take_home = (float(i.take_home) * paid_days) / payable_days
                                            standard_ctc = (float(i.standard_ctc) * paid_days) / payable_days
                                            logger.info("------EMPLOYEE MONTHLY INFO GROSS_PAY AMOUNT--------" + str(gross_pay))
                                            obj_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                                                employee_id=employee_id,
                                                standard_ctc=standard_ctc,
                                                payable_days=payable_days,
                                                paid_days=paid_days,
                                                take_home=take_home,
                                                created_by=1,
                                                created_date=date_time,
                                                payroll_date=date_time.date(),
                                                gross_pay=gross_pay,
                                                pay_status=Advancestatus.draft)
                                            apifunction = Payrollcommon_Apicall(self._scope())
                                            code = apifunction.payslip_gen_code(CodeUtil.Employeemonthly_payinfo, 1, i.employee_id)
                                            logger.info("-----Employeemonthly_payinfo Code-----" +str(code))
                                            obj_data.code = code
                                            obj_data.save()
                                            logger.info("------Employeemonthly_payinfo Create success--------" + str(obj_data.code))

                                            emp_details = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                empmonthly_pay_id=obj_data.id,
                                                paycomponent=type,
                                                from_date=active_date,
                                                to_date=end_date,
                                                created_by=1,
                                                created_date=date_time,
                                                segment=payroll_mastermap,
                                                entity_id=self._entity_id(),
                                                amount=amount)
                                            logger.info("------Employeemonthlypay_details Create success--------" + str(emp_details.id))
                                        else:
                                            dedcut_data1 = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).filter(status=Activestatus.active, deduct_date__month=month, deduct_date__year=year, employee_id=i.employee_id,paycomponent_id=type)
                                            if dedcut_data1.count() > 0:
                                                continue
                                            else:
                                                deduct_data = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                        employee_id=employee,
                                                        paycomponent_id=type,
                                                        from_date=active_date,
                                                        to_date=end_date,
                                                        amount=amount,
                                                        created_by=1,
                                                        deduction_status=1,
                                                        deduct_date=date_time.date(),
                                                        created_date=date_time)
                                                logger.info("------Employeemonthlypay_details Create success--------" + str(deduct_data.id))
                                        continue
                            else:
                                paid_days = j['paid_days']
                                payable_days = j['payable_days']
                                employee_id = i.employee_id
                                is_esi = i.is_esi
                                pf_type = i.pf_type
                                gross_pay = (float(i.gross_pay) * paid_days) / payable_days
                                logger.info("------EMPLOYEE MONTHLY INFO GROSSPAY AMOUNT--------" + str(gross_pay))
                                #formula

                                take_home = (float(i.take_home) * paid_days) / payable_days
                                standard_ctc = (float(i.standard_ctc) * paid_days) / payable_days
                                obj_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                                    employee_id=employee_id,
                                    standard_ctc=standard_ctc,
                                    payable_days=payable_days,
                                    paid_days=paid_days,
                                    take_home=take_home,
                                    created_by=1,
                                    payroll_date=date_time.date(),
                                    created_date=date_time,
                                    gross_pay=gross_pay,
                                    pay_status=Advancestatus.draft,
                                    is_deduct=1)
                                apifunction = Payrollcommon_Apicall(self._scope())
                                code = apifunction.payslip_gen_code(CodeUtil.Employeemonthly_payinfo, 1, i.employee_id)
                                logger.info("-----Employeemonthly_payinfo Code-----" + str(code))
                                obj_data.code = code
                                obj_data.save()
                                logger.info("------Employeemonthly_payinfo Create success--------" + str(obj_data.code))
                                if obj_data.id > 0:
                                    monthly_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, emp_pay__employee_id=employee_id)
                                    if monthly_details.count() > 0:
                                        for k in monthly_details:
                                            paycomponent = k.paycomponent
                                            paycomponent_type = k.paycomponent_type
                                            paycomponent_percentage = k.paycomponent_percentage
                                            segment_percentage = k.segment_percentage
                                            data_amt = k.amount
                                            print(data_amt)
                                            company_contribution = k.company_contribution
                                            type = k.type
                                            segment = k.segment
                                            from_date = k.from_date
                                            to_date = k.to_date
                                            if is_esi is (True or False) or get_pf_type(pf_type)['name'] == ('NORMAL_PF' or 'STANDARD_PF' or 'VIRTUAL_PF'):
                                                if company_contribution is True:
                                                    from django.db.models import Sum
                                                    # pf = Payrollcommon_Apicall(self._scope()).company_contribution_data(paycomponent)[0]
                                                    pf = CompanyContributionService(self._scope()).company_contribution_data(paycomponent)[0]
                                                    if get_pf_type(pf_type)['name'] == 'NORMAL_PF' or is_esi is (True or False):
                                                        # pf = CompanyContribution.objects.using(self._current_app_schema()).filter(status=1,id=paycomponent).values('id', 'name', 'percentage', 'amount')[0]
                                                        # flag_master=list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(map_id=pf.id).value_list('id'))
                                                        # flag_master = Payrollcommon_Apicall(self._scope()).list_of_map_id_data(pf['id'])
                                                        # flag_master = Payrollcommon_Apicall(self._scope()).cc_epf_based_paycom(pf['id'],FlagRef_Type.COMPANYCONTRIBUTION)
                                                        flag_master = PaycomponentFlagmasterService(self._scope()).cc_epf_based_paycom(pf['id'],FlagRef_Type.COMPANYCONTRIBUTION)
                                                        # flag_master = list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(status=1, map_id=pf['id']).values_list('ref_id', flat=True))
                                                        print(flag_master)
                                                        sum_amt = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, paycomponent__in=flag_master,empmonthly_pay__employee_id=employee_id,empmonthly_pay__payroll_date__month=month, empmonthly_pay__payroll_date__year=year, company_contribution=False).aggregate(Sum('amount'))
                                                        logger.info("------COMPANY CONTRIBUTION SUM_AMT--------" + str(sum_amt))
                                                        sum_prec = float(sum_amt['amount__sum']) * float(pf['percentage']) / 100
                                                        if sum_amt['amount__sum'] != None:
                                                            print(sum_amt, 'iuh')
                                                            if pf['sal_amount'] == 0.00 or None:
                                                                if pf['amount'] < sum_prec:
                                                                    amount = round(pf['amount'])
                                                                else:
                                                                    amount = round(sum_prec)
                                                            else:
                                                                if is_esi is False:
                                                                    amount = 0.00
                                                                else:
                                                                    if sum_amt['amount__sum'] <= pf['sal_amount']:
                                                                        amount = round(sum_prec)
                                                                    else:
                                                                        amount = 0.00
                                                        else:
                                                            amount = 0.00
                                                    else:
                                                        amount = round(pf['amount'])
                                                elif type != None:
                                                    # created_dated = k.created_date.month
                                                    # if created_dated == month:
                                                        if payrolldeduction_val(type)['name'] == 'MONTHLY':
                                                            amount = round(float(data_amt) * paid_days / float(payable_days))
                                                            logger.info("------MONTHLY AMOUNT--------" + str(amount))
                                                        elif payrolldeduction_val(type)['name'] == 'QUARTERLY' or 'HALFYEARLY' or 'YEARLY' or 'CUSTOM':
                                                            month_data = self.bonus_month(type,month,year,date_time,from_date,to_date)
                                                            if month_data is None:
                                                                continue
                                                            else:
                                                                for y in month_data:
                                                                    emp_id = y['employee_id']
                                                                    if employee_id == emp_id:
                                                                        month_paid = y['paid_days']
                                                                        month_payable = y['payable_days']
                                                                        amount = round(float(data_amt) * month_paid / float(month_payable))
                                                                        logger.info("------'QUARTERLY' or 'HALFYEARLY' or 'YEARLY' CALCULATION--------" + str(amount))
                                                elif company_contribution is False or type is False:
                                                    cal_amount = float(gross_pay) * float(segment_percentage) / 100
                                                    amount = float(cal_amount) * float(paycomponent_percentage) / 100

                                            else:
                                                amount = 0.00

                                            data = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                empmonthly_pay_id=obj_data.id,
                                                paycomponent=paycomponent,
                                                paycomponent_type=paycomponent_type,
                                                paycomponent_percentage=paycomponent_percentage,
                                                company_contribution=company_contribution,
                                                amount=amount,
                                                type=type,
                                                segment=segment,
                                                created_by=1,
                                                created_date=date_time,
                                                segment_percentage=segment_percentage)
                                            logger.info( "------Employeemonthlypay_details Create success--------" + str(data.id))
                                            continue

                                deduction_data = EmployeePaystructure_deductions.objects.using(self._current_app_schema()).filter(status=Activestatus.active,employee_id=i.employee_id)
                                if deduction_data.count() > 0:
                                    for g in deduction_data:
                                        if g.is_customdeduct == 1:
                                            deduction_status = 1
                                        else:
                                            deduction_status = -1
                                        employee_id = g.employee_id
                                        paycomponent_id = g.paycomponent_id
                                        type = g.type
                                        if type == PayrollDeductionType.CUSTOM:
                                            from_date = g.from_date
                                            to_date = g.to_date
                                        else:
                                            from_date = date_time.date()
                                            to_date = date_time.date()
                                        amount = g.amount
                                        # if (deduction_status == 1 and type == PayrollDeductionType.CUSTOM) or deduction_status == -1:
                                        if from_date.month <= month and to_date.month >= month and from_date.year <= year and to_date.year >= year:
                                            logger.info(('--------------------------PAYSTRUCTURE DEDUCT TO MONTHLY DEDUCT DATA CUSTOM DEDUCTION-----------------------------------------------------------'))
                                            if deduction_status == -1:
                                                deduction_cal = self.monthly_deduction_calculation(employee_id,paycomponent_id,month,year,is_esi,pf_type)
                                            else:
                                                deduction_cal = amount
                                            deduction = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=employee_id,
                                                                                                                       paycomponent_id=paycomponent_id,
                                                                                                                       type=type,
                                                                                                                       from_date=from_date,
                                                                                                                       to_date=to_date,
                                                                                                                       amount=deduction_cal,
                                                                                                                       created_by=1,
                                                                                                                       deduct_date=date_time.date(),
                                                                                                                       created_date=date_time,
                                                                                                                       deduction_status=deduction_status)
                                            logger.info("------Employeemonthlypay_deductions Create success--------" + str(deduction.id))
                                process_data = Payrollprocesschange.objects.using(self._current_app_schema()).filter(status=Activestatus.active,employee_id=i.employee_id, from_date__month__lte=month, to_date__month__gte=month, from_date__year__lte=year,to_date__year__gte=year)
                                if process_data.count() > 0:
                                    for m in process_data:
                                        employee_id = m.employee_id
                                        pay_change = m.pay_change
                                        Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=employee_id).update(pay_status=pay_change)
                                        logger.info("------EMPLOYEEMONTHLY_PAYINFO UPDATED PAY_STATUS--------" +str(pay_change))

                                allowance_date=Employeeadditional_allowance.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id, active_date__month__lte=month, end_date__month__gte=month, active_date__year__lte=year, end_date__year__gte=year)
                                if allowance_date.count() > 0:
                                    for a in allowance_date:
                                        employee=a.employee_id
                                        type=a.type
                                        # payroll_mastermap = Payrollcommon_Apicall(self._scope()).get_segment_based_paycom(a.type)
                                        payroll_mastermap = PayrollmastermappingService(self._scope()).get_segment_based_paycom(a.type)
                                        if payroll_mastermap == []:
                                            payroll_mastermap=None
                                        active_date=a.active_date
                                        end_date=a.end_date
                                        amount=a.amount
                                        month_details = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=employee, payroll_date__month=month, payroll_date__year=year)
                                        if month_details.count() > 0:
                                            if a.custom_deduct == 0:
                                                details = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(empmonthly_pay_id=month_details[0].id,paycomponent=type,from_date=active_date,to_date=end_date,amount=amount)
                                                if details.count() > 0:
                                                    continue
                                                else:
                                                    emp_details = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                    empmonthly_pay_id=month_details[0].id,
                                                    paycomponent=type,
                                                    from_date=active_date,
                                                    to_date=end_date,
                                                    segment=payroll_mastermap,
                                                    created_by=1,
                                                    created_date=date_time,
                                                    amount=amount)
                                                    logger.info("------Employeemonthlypay_details Create success--------" +str(emp_details.id))
                                            else:
                                                deduct_data = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                                                                    employee_id=employee,
                                                                                                    paycomponent_id=type,
                                                                                                    from_date=active_date,
                                                                                                    to_date=end_date,
                                                                                                    amount=amount,
                                                                                                    deduction_status=1,
                                                                                                    created_by=1,
                                                                                                    deduct_date=date_time.date(),
                                                                                                    created_date=date_time)
                                                logger.info("------Employeemonthlypay_details Create success--------" + str(deduct_data.id))
                                            continue
                                # advance
                                advance_pay = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(
                                    status=Activestatus.active, advance__employee_id=i.employee_id,
                                    advance__from_date__month__lte=month, advance__to_date__month__gte=month,
                                    advance__from_date__year__lte=year, advance__to_date__year__gte=year)
                                if advance_pay.count() > 0:
                                    advance_id = [i.advance_id for i in advance_pay]
                                    unique_advance_id = list(set(advance_id))
                                    for ids in unique_advance_id:
                                        advance1 = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(status=Activestatus.active,advance__id=ids).values('id', 'advance_id','balance_amount','advance__emi_amount','advance__employee_id','advance__from_date','advance__to_date').last()
                                        if advance1 is not None:
                                        #if advance1.count() > 0:
                                            if 0.00 <= advance1['balance_amount'] <= 0.50 or None:
                                                update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=advance1['advance_id']).update(advance_status=Advancestatus.closed, updated_by=1,  updated_date=date_time)
                                                logger.info( "-----Employeeadvancedetails update status closed emi bal=0---------" + str(advance1['advance_id']))
                                                continue
                                            else:
                                                advance_id = advance1['advance_id']
                                                paid_amount = advance1['advance__emi_amount']
                                                balance_amount = advance1['balance_amount']
                                                employee_payment = advance1['advance__employee_id']
                                                from_date_payment = advance1['advance__from_date']
                                                to_date_payment = advance1['advance__to_date']
                                                amount = abs(float(paid_amount - balance_amount))
                                                # advance_type = Advancetype.advance
                                                advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=advance_id,
                                                                                                                                           paid_date=date_time,
                                                                                                                                           balance_amount=amount,
                                                                                                                                           paid_amount=paid_amount,
                                                                                                                                           created_by=1,
                                                                                                                                           created_date=date_time)

                                                logger.info( "------Employeeadvancepayment Create success--------" + str(advancepayment.id))
                                                if 0.00 <= advancepayment.balance_amount <= 0.50 or None:
                                                     update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=advancepayment.advance_id).update(advance_status=Advancestatus.closed, updated_by=1,updated_date=date_time)
                                                     logger.info( "-----Employeeadvancedetails update status closed emi bal=0---------" + str(advancepayment.advance_id))

                                                advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=employee_payment,
                                                                                                                                               from_date=from_date_payment,
                                                                                                                                               to_date=to_date_payment,
                                                                                                                                               amount=paid_amount,
                                                                                                                                               created_by=1,
                                                                                                                                               deduction_status=1,
                                                                                                                                               deduct_date=date_time.date(),
                                                                                                                                               created_date=date_time,
                                                                                                                                               is_advance=1)
                                                logger.info("------Employeemonthlypay_deductions Create success--------" + str(advance_deduct.id))

                                            # second advance create
                                            condition = ~Q(id__in=unique_advance_id)
                                            advancedetails1 = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(condition,status=Activestatus.active,
                                                                                                                               employee_id=i.employee_id,
                                                                                                                               advance_status=Advancestatus.paid,
                                                                                                                               from_date__month__lte=month,
                                                                                                                               to_date__month__gte=month,
                                                                                                                               from_date__year__lte=year,
                                                                                                                               to_date__year__gte=year)
                                            if advancedetails1.count() > 0:
                                                for s1 in advancedetails1:
                                                    id = s1.id
                                                    paid_amount = s1.emi_amount
                                                    deduct_advance_employee = s1.employee_id
                                                    balance_amount = abs(float(s1.payable_amount - paid_amount))
                                                    from_date = s1.from_date
                                                    to_date = s1.to_date
                                                    advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                                                                                                                                   paid_date=date_time,
                                                                                                                                   balance_amount=balance_amount,
                                                                                                                                   paid_amount=paid_amount,
                                                                                                                                   created_by=1,
                                                                                                                                   created_date=date_time)
                                                    logger.info("-----Employeeadvancepayment create success---------" + str(advancepayment.id))
                                                    update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=id).update(advance_status=Advancestatus.open, updated_by=1,updated_date=date_time)
                                                    logger.info( "-----Employeeadvancedetails update status open emi bal>0---------" + str(update.id))

                                                    advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                                                                                                            employee_id=deduct_advance_employee,
                                                                                                                                            from_date=from_date,
                                                                                                                                            to_date=to_date,
                                                                                                                                            amount=paid_amount,
                                                                                                                                            created_by=1,
                                                                                                                                            deduction_status=1,
                                                                                                                                            deduct_date=date_time.date(),
                                                                                                                                            created_date=date_time,
                                                                                                                                            is_advance=1)

                                        continue
                                else:
                                    advancedetails = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                           employee_id=i.employee_id,
                                                                           advance_status=Advancestatus.paid,
                                                                           from_date__month__lte=month,
                                                                           to_date__month__gte=month,
                                                                           from_date__year__lte=year,
                                                                           to_date__year__gte=year)
                                    if advancedetails.count() > 0:
                                        for s in advancedetails:
                                            id = s.id
                                            paid_amount = s.emi_amount
                                            deduct_advance_employee = s.employee_id
                                            balance_amount = abs(float(s.payable_amount - paid_amount))
                                            from_date = s.from_date
                                            to_date = s.to_date
                                            advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                                                                                   paid_date=date_time,
                                                                                   balance_amount=balance_amount,
                                                                                   paid_amount=paid_amount,
                                                                                   created_by=1,
                                                                                   created_date=date_time)
                                            logger.info("-----Employeeadvancepayment create success---------" + str(advancepayment.id))
                                            update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=id).update(advance_status=Advancestatus.open, updated_by=1, updated_date=date_time)
                                            logger.info("-----Employeeadvancedetails update status open emi bal>0---------" + str(id))

                                            advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=deduct_advance_employee,
                                                                                   from_date=from_date,
                                                                                   to_date=to_date,
                                                                                   amount=paid_amount,
                                                                                   created_by=1,
                                                                                   deduction_status=1,
                                                                                   deduct_date=date_time.date(),
                                                                                   created_date=date_time,
                                                                                   is_advance=1)
                                            logger.info("-----Employeemonthlypay_deductions create success---------" + str( advance_deduct.id))
                                # advance_pay = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(status=Activestatus.active, advance__employee_id=i.employee_id,advance__from_date__month__lte=month, advance__to_date__month__gte=month, advance__from_date__year__lte=year, advance__to_date__year__gte=year).values('id', 'advance_id','balance_amount','advance__emi_amount','advance__employee_id','advance__from_date','advance__to_date').last()
                                # if advance_pay is not None:
                                #     # for advance in advance_pay:
                                #     if advance_pay['balance_amount'] == 0.00 or None:
                                #         update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=advance_pay['advance_id']).update(advance_status=Advancestatus.closed,updated_by=1,updated_date=date_time)
                                #         logger.info("-----Employeeadvancedetails update status closed emi bal=0---------" + str(advance_pay['advance_id']))
                                #         continue
                                #     else:
                                #         advance_id = advance_pay['advance_id']
                                #         paid_amount = advance_pay['advance__emi_amount']
                                #         balance_amount = advance_pay['balance_amount']
                                #         employee_payment = advance_pay['advance__employee_id']
                                #         from_date_payment = advance_pay['advance__from_date']
                                #         to_date_payment = advance_pay['advance__to_date']
                                #         amount = abs(float(paid_amount - balance_amount))
                                #         # advance_type = Advancetype.advance
                                #         advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=advance_id,
                                #                                                                                                    paid_date=date_time,
                                #                                                                                                    balance_amount=amount,
                                #                                                                                                    paid_amount=paid_amount,
                                #                                                                                                    created_by=1,
                                #                                                                                                    created_date=date_time)
                                #
                                #         advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=employee_payment,
                                #                                                from_date=from_date_payment,
                                #                                                to_date=to_date_payment,
                                #                                                amount=paid_amount,
                                #                                                created_by=1,
                                #                                                deduction_status=1,
                                #                                                deduct_date=date_time.date(),
                                #                                                created_date=date_time,
                                #                                                is_advance=1)
                                # else:
                                #     advancedetails = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id, advance_status=Advancestatus.paid, from_date__month__lte=month, to_date__month__gte=month, from_date__year__lte=year, to_date__year__gte=year)
                                #     if advancedetails.count() > 0:
                                #         for s in advancedetails:
                                #             id=s.id
                                #             paid_amount=s.emi_amount
                                #             deduct_advance_employee = s.employee_id
                                #             balance_amount=float(s.payable_amount - paid_amount)
                                #             from_date=s.from_date
                                #             to_date=s.to_date
                                #             advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                                #                                                                                                      paid_date=date_time,
                                #                                                                                                      balance_amount=balance_amount,
                                #                                                                                                      paid_amount=paid_amount,
                                #                                                                                                      created_by=1,
                                #                                                                                                      created_date=date_time)
                                #             update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=id).update(advance_status=Advancestatus.open,updated_by=1,updated_date=date_time)
                                #             logger.info( "-----Employeeadvancedetails update status open emi bal>0---------" + str(id))
                                #
                                #             advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=deduct_advance_employee,
                                #                                                                         from_date=from_date,
                                #                                                                         to_date=to_date,
                                #                                                                         amount=paid_amount,
                                #                                                                         created_by=1,
                                #                                                                         deduction_status=1,
                                #                                                                         deduct_date=date_time.date(),
                                #                                                                         created_date=date_time,
                                #                                                                         is_advance=1)

                success_obj.set_status(SuccessStatus.SUCCESS)
                success_obj.set_message('DATA INSERTED SUCCESSFULLY')
                schedular1 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update(end=timezone.now(),message='DATA INSERTED SUCCESSFULLY')
                return success_obj
            else:
                obj = Error()
                obj.payrollmanual_run = {"message":"Please Select Month and Year "}
                obj.set_code(ErrorMessage.INVALID_DATA)
                obj.set_description(ErrorDescription.ALREADY_EXISTS)
                schedular2 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update(
                    end=timezone.now(), message='Please Select Month and Year')
                return obj
        except Exception as excep:
            exception_type, exception_object, exception_traceback = sys.exc_info()
            filename = exception_traceback.tb_frame.f_code.co_filename
            line_number = exception_traceback.tb_lineno
            traceback.print_exc()
            error_obj = NWisefinError()
            error_obj.set_code(ErrorMessage.INVALID_DATA)
            error_obj.set_description(str(excep))
            error_obj.payrollmanual_run = {"error":(str(excep) + " - " + str(filename) + ", line_no: " + str(line_number))}
            schedular3 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update(end=timezone.now(), message=str(excep))
            return error_obj
        # except:
            # success_obj.set_status('INVALID YEAR')
            # return success_obj



    def create_month_details_create(self, employee, month, user_id, data_json):
        monthinfo = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(employee_id=employee,
                                                                                             payroll_date__month=month)
        if monthinfo.count() > 0:
            month_create = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                empmonthly_pay_id=monthinfo[0].id,
                paycomponent=data_json.get_paycomponent(),
                paycomponent_type=data_json.get_paycomponent_type(),
                amount=data_json.get_amount(),
                created_by=user_id)
            # paycomponent_percentage=data_json.get_paycomponent_percentage(),
            # amount=float(monthinfo.gross_pay)*float(data_json.get_paycomponent_percentage())/100)
            success_obj = NWisefinSuccess()
            success_obj.set_status(SuccessStatus.SUCCESS)
            success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
            return success_obj
        else:
            error_obj = NWisefinError()
            error_obj.set_description(ErrorDescription.NO_DATA_FOUND)
            error_obj.set_code(ErrorMessage.INVALID_DATA)
            return error_obj


    def employeemonthpay_data(self, id_arr):
        emplmonth_info = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, id__in=id_arr)
        resp_arr = []
        for empmonth in emplmonth_info:
            get_resp = Employeemonthly_payinfoResponse()
            get_resp.set_id(empmonth.id)
            get_resp.set_employee_id(empmonth.employee_id)
            get_resp.set_standard_ctc(empmonth.standard_ctc)
            get_resp.set_payable_days(empmonth.payable_days)
            get_resp.set_paid_days(empmonth.paid_days)
            get_resp.set_pay_status(empmonth.pay_status)
            get_resp.set_gross_pay(empmonth.gross_pay)
            get_resp.set_pay_mode(empmonth.pay_mode)
            get_resp.set_payroll_date(empmonth.payroll_date)
            get_resp.set_take_home(empmonth.take_home)
            resp_arr.append(get_resp)
        return resp_arr

    def emp_manual_run(self):
        date_time = datetime.now()
        month = int(date_time.strftime("%m"))
        # month = 4
        year = int(date_time.strftime("%Y"))
        emp_url = APPLICATION_BE_URL + '/atdserv/payroll_attendance_summary'
        data = {"month": month, "year": year}
        json_data = json.dumps(data)
        ip_address = APPLICATION_BE_URL + '/usrserv/auth_token'
        username = 'apuser'
        password = '1234'
        datas = json.dumps({"username": username, "password": password, "entity_id": 1})
        resp = requests.post(ip_address, data=datas, verify=False)
        token_data = json.loads(resp.content.decode("utf-8"))
        headers = {"content-type": "application/json", "Authorization": "Token " + token_data["token"] + ""}
        resp_obj = requests.post("" + emp_url, params='', data=json_data, headers=headers, verify=False)
        emp_data_values = json.loads(resp_obj.content.decode("utf-8"))
        data_get = emp_data_values.get('data')
        arr = []
        for j in data_get:
            emp_id = j['employee_id']
            arr.append(emp_id)
        obj_val = EmployeePaystructure.objects.using(self._current_app_schema()).filter(employee_id__in=arr)
        list_val = [i.id for i in obj_val]
        obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(
            emp_pay_id__in=list_val)
        for i in obj_val:
            for j in data_get:
                if i.employee_id == j['employee_id']:
                    paid_days = j['paid_days']
                    payable_days = j['payable_days']
                    employee_id = i.employee_id
                    gross_pay = (float(i.gross_pay)*paid_days)/payable_days
                    take_home = i.take_home
                    standard_ctc =(float(i.standard_ctc)*paid_days)/payable_days
                    obj_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                        employee_id=employee_id,
                        standard_ctc=standard_ctc,
                        payable_days=payable_days,
                        paid_days=paid_days,
                        take_home=take_home,
                        created_by=1,
                        gross_pay=gross_pay)

                    for j in obj:
                        if j.emp_pay_id == obj_data.id:
                            paycomponent = j.paycomponent
                            paycomponent_type = j.paycomponent_type
                            paycomponent_percentage = j.paycomponent_percentage
                            data_amt = j.amount
                            print(data_amt)
                            company_contribution=j.company_contribution
                            type=j.type
                            if company_contribution is True or type is False:
                                from django.db.models import Sum
                                # pf = Payrollcommon_Apicall(self._scope()).company_contribution_data(paycomponent)[0]
                                pf = CompanyContributionService(self._scope()).company_contribution_data(paycomponent)[0]
                                # pf = CompanyContribution.objects.using(self._current_app_schema()).filter(id=paycomponent).values('id', 'name', 'percentage', 'amount')[0]
                                # flag_master=list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(map_id=pf.id).value_list('id'))
                                # flag_master = Payrollcommon_Apicall(self._scope()).list_of_map_id_data(pf['id'])
                                flag_master = PaycomponentFlagmasterService(self._scope()).list_of_map_id_val(pf['id'])
                                # flag_master = list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(map_id=pf['id']).values_list('ref_id', flat=True))
                                print(flag_master)
                                sum_amt = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(paycomponent__in=flag_master, empmonthly_pay__employee_id=employee_id).aggregate(Sum('amount'))
                                if sum_amt['amount__sum'] != None:
                                    sum_prec = float(sum_amt['amount__sum']) * float(pf['percentage']) / 100
                                    amount=sum_prec
                                else:
                                    amount=0.00
                            elif type != None:
                                amount=amount
                            elif company_contribution is False or type is False:
                                amount = float(gross_pay) * float(paycomponent_percentage) / 100

                            Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                empmonthly_pay_id=obj_data.id,
                                paycomponent=paycomponent,
                                paycomponent_type=paycomponent_type,
                                paycomponent_percentage=paycomponent_percentage,
                                company_contribution=company_contribution,
                                amount=amount,
                                type=type,
                                created_by=1)
                        continue
        deduction_data = EmployeePaystructure_deductions.objects.using(self._current_app_schema()).filter(employee_id__in=arr)


        # deduction_df = pd.DataFrame.from_records(deduction_data.values())
        # pf = EmployeePFStructure.objects.using(self._current_app_schema()).filter(
        #     id__in=deduction_df['paycomponent_id']).values('name', 'code', 'percentage', 'amount')
        # Employeemonthlypay_details.objects.using(self._current_app_schema())




        for i in deduction_data:
            employee_id = i.employee_id
            paycomponent_id = i.paycomponent_id
            type = i.type
            from_date = i.from_date
            to_date = i.to_date
            amount = i.amount
            from django.db.models import Sum
            # pf = Payrollcommon_Apicall(self._scope()).get_employee_pfstruc_data([paycomponent_id])[0]
            pf = PaycomponentFlagmasterService(self._scope()).get_employee_pf_data([paycomponent_id])[0]
            # pf = EmployeePFStructure.objects.using(self._current_app_schema()).filter(id=paycomponent_id).values('id','name', 'code', 'percentage', 'amount','sal_amount')[0]
            # flag_master=list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(map_id=pf.id).value_list('id'))
            # flag_master = Payrollcommon_Apicall(self._scope()).list_of_map_id_data(pf['id'])
            flag_master = PaycomponentFlagmasterService(self._scope()).list_of_map_id_val(pf['id'])
            # flag_master=list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(map_id=pf['id']).values_list('ref_id', flat=True))
            sum_amt=Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(paycomponent__in=flag_master,empmonthly_pay__employee_id=employee_id).aggregate(Sum('amount'))
            sum_prec=float(sum_amt['amount__sum'])*float(pf['percentage'])/100
            if float(pf['sal_amount'])>0:
                if float(sum_amt)> float(pf['sal_amount']):
                    amount=0.00
                else:
                    amount = sum_prec
            else:
                if sum_prec > float(pf['amount']):
                    amount = pf['amount']
                else:
                    amount = sum_prec

            Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=employee_id,
                                                                                           paycomponent_id=paycomponent_id,
                                                                                           type=type,
                                                                                           from_date=from_date,
                                                                                           to_date=to_date,
                                                                                           amount=amount,
                                                                                           created_by=1)
        success_obj = NWisefinSuccess()
        success_obj.set_status(SuccessStatus.SUCCESS)
        success_obj.set_message('DATA INSERTED SUCCESSFULLY')
        return success_obj


    def pay_status_update(self, user_id, data_json):
        current_date = date.today()
        year = current_date.strftime('%Y')
        month = current_date.strftime('%m')
        success_obj = NWisefinSuccess()
        data = advancestatus(data_json['pay_status'])
        if data['name'] == 'APPROVED':
            update_pay = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(id__in=data_json['id']).update(pay_status=data_json['pay_status'], updated_by=user_id, updated_date=timezone.now())
            insert_data = Payapprovedqueue.objects.using(self._current_app_schema()).create(date = date.today())
            id_data = insert_data.id
            insert_data.code = str(self._entity_id())+'VSH'+year+month+str(id_data)
            insert_data.save()
            bulk_update_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(id__in=data_json['id']).update(ref_id=insert_data.id)
            if update_pay > 0:
                success_obj.set_status(SuccessStatus.SUCCESS)
                success_obj.set_message(SuccessMessage.UPDATE_MESSAGE)
            else:
                success_obj = NWisefinError()
                success_obj.set_code(ErrorMessage.UNEXPECTED_ERROR)
                success_obj.set_description(ErrorDescription.INVALID_DATA)
        else:
            update_pay = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(
                id__in=data_json['id']).update(pay_status=data_json['pay_status'], updated_by=user_id,
                                               updated_date=timezone.now())
            success_obj.set_status(SuccessStatus.SUCCESS)
            success_obj.set_message(SuccessMessage.UPDATE_MESSAGE)

        return success_obj

    def get_monthlyinfo_id(self,month,year):
        monthpay_info = list(Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, payroll_date__month=month, payroll_date__year=year,pay_status=8).values_list('id', flat=True))
        data = {"data": monthpay_info}
        if len(monthpay_info) > 0:
            data_list = json.dumps(data)
            return data_list
        else:
            data=[]
            return data

    def payapproval_queue_get(self, ref_ids):
        obj = Payapprovedqueue.objects.using(self._current_app_schema()).filter(id__in=ref_ids)
        arr = []
        for i in obj:
            dict_data = {"id": i.id, "code": i.code, 'date': str(i.date)}
            arr.append(dict_data)
        return arr

    def approving_level_get(self, ref_id):
        emplmonth_info = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(pay_status=Advancestatus.approved, ref_id=ref_id)
        ref_id = [i.ref_id for i in emplmonth_info]
        appr_data = self.payapproval_queue_get(ref_id)
        resp_arr = NWisefinList()
        for empmonth in emplmonth_info:
            get_resp = Employeemonthly_payinfoResponse()
            get_resp.set_id(empmonth.id)
            get_resp.set_employee_id(empmonth.employee_id)
            get_resp.set_standard_ctc(empmonth.standard_ctc)
            get_resp.set_payable_days(empmonth.payable_days)
            get_resp.set_paid_days(empmonth.paid_days)
            get_resp.set_pay_status(empmonth.pay_status)
            get_resp.set_gross_pay(empmonth.gross_pay)
            get_resp.set_pay_mode(empmonth.pay_mode)
            get_resp.set_payroll_date(empmonth.payroll_date)
            get_resp.set_take_home(empmonth.take_home)
            get_resp.set_ref_id(empmonth.ref_id, appr_data)
            resp_arr.append(get_resp)
        return resp_arr



    def payapproved_ccbs_payrollget(self,month,year):
        pay_approve = Payapprovedqueue.objects.using(self._current_app_schema()).filter(date__month=month,date__year=year).values('id','code','date')
        if pay_approve.count() > 0:
            ref_id_arr = [k['id'] for k in pay_approve]
            approve_data = self.cc_bs_based_payrollget(ref_id_arr)
            pay_approve_df = pd.DataFrame.from_records(pay_approve)
            payapprove_df = approve_data.merge(pay_approve_df, left_on='ref_id', right_on='id', how='inner')
            payapprove_df1 = payapprove_df.drop(['employee_id','ref_id','date'],  axis=1)
            payapprove_df2 = payapprove_df.drop(['employee_id', 'ref_id', 'costcentre', 'businesssegment', 'date', 'code'], axis=1)
            arr = []
            list_data = NWisefinList()
            if payapprove_df.empty:
                return list_data
            for index,row in payapprove_df1.iterrows():
                ccbs_data = row['ccbs']
                approval_dta = row['id']
                condition1 = payapprove_df1.loc[((ccbs_data == payapprove_df2['ccbs']) & (approval_dta == payapprove_df2['id']))]
                condition2 =sum(condition1['gross_pay'])
                dict = { "id" : approval_dta,
                         "Total_Amount": condition2,
                         "cc_bs":ccbs_data,
                         "code":row['code'],
                         "costcentre":row['costcentre'],
                         "businesssegment":row['businesssegment']}
                arr.append(dict)
                print(arr)
            final_df = pd.DataFrame.from_records(arr)
            final_df1 = final_df.drop(['id', 'cc_bs'], axis=1)
            final_df2 = final_df1.drop_duplicates()
            final_datadf = final_df2.to_json(orient="records")
            final_data = json.loads(final_datadf)
            list_data.data = final_data
        else:
            list_data = NWisefinList()
        return list_data

    def cc_bs_based_payrollget(self,ref_id):
        payinfo_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, pay_status=Advancestatus.approved,ref_id__in=ref_id).values('employee_id','gross_pay','ref_id')
        employee_arr = [i['employee_id'] for i in payinfo_data]
        if payinfo_data.count() > 0:
            employee_cc_bs = Payrollcommon_Apicall(self._scope()).emp_data_cc_bs(employee_arr)
            employee_cc_bs_df = pd.DataFrame([vars(s) for s in employee_cc_bs], columns=['id', 'costcentre', 'businesssegment'])
            month_payinfo = pd.DataFrame.from_records(payinfo_data)
            pay_data_df1 = month_payinfo.merge(employee_cc_bs_df, left_on='employee_id', right_on='id', how='left')
            pay_data_df = pay_data_df1.drop(['id'], axis=1)
            pay_data_df['ccbs'] = pay_data_df['costcentre'].map(str) + pay_data_df['businesssegment'].map(str)
        else:
            pay_data_df = pd.DataFrame(columns=['employee_id','gross_pay','ref_id','id', 'costcentre', 'businesssegment'])
        return pay_data_df

    def common_pdf_function(self, employeemonthpay):
        context = employeemonthpay
        context['logopath'] = Employeemonthlypay_detailsService(self._scope()).logopath
        response = HttpResponse(content_type='application/pdf')
        template = loader.get_template('employeemonthpay_fetch.html')
        html = template.render(context)
        pisa.CreatePDF(html, dest=response)
        data = emppaystructurecontroller.read_pdf(response.content)
        return data


    def approvel_bank_template_download(self,month,year,vys_page):
        payinfo_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, pay_status=Advancestatus.approved,payroll_date__month=month,payroll_date__year=year)[vys_page.get_offset():vys_page.get_query_limit()]
        arr = NWisefinList()
        if payinfo_data.count() >0:
            employee_arr = [i.employee_id for i in payinfo_data]
            apifunction = Payrollcommon_Apicall(self._scope())
            employee_data = apifunction.employee_data(employee_arr)
            for i in payinfo_data:
                data_resp = Employeemonthly_payinfoResponse()
                data_resp.set_employee_val1(i.employee_id, employee_data)
                data_resp.set_payroll_date1(i.payroll_date)
                data_resp.set_ref_id1(i.ref_id)
                payapprove = Payapprovedqueue.objects.using(self._current_app_schema()).get(id=i.ref_id)
                date = str(payapprove.date)
                data_resp.Approval_date = datetime.strptime(date, "%Y-%m-%d").strftime("%d %b %Y")
                data_resp.Payable_TK_home_Bonus = 0.0
                data_resp.Sum_of_Paid = 0.0
                data_resp.Balance_payable = 0.0
                arr.append(data_resp)
            vpage = NWisefinPaginator(payinfo_data, vys_page.get_index(), 10)
            arr.set_pagination(vpage)
        else:
            vpage = NWisefinPaginator([], vys_page.get_index(), 10)
            arr.set_pagination(vpage)
        return arr

    def payroll_test_upload(self, file,user_id):
        success_obj = NWisefinSuccess()
        # file_df = pd.DataFrame(file)
        test_upload_obj = file.fillna(np.nan).replace([np.nan], [None]).to_dict(orient='records')
        arr=[]
        for i in test_upload_obj:
            try:
                employee_id = Payrollcommon_Apicall(self._scope()).emp_code(i['Employee Code'])
            except  Exception as e:
                arr.append({"error" : str(e),"code" : i['Employee Code']})
                continue
            payroll_test_obj = PayrollTest.objects.using(self._current_app_schema()).create(employee_id=employee_id.get('id'),
                                                                                            month=i['Month'],
                                                                                            year=i['Year'],
                                                                                            present_count=i['Present Count'],
                                                                                            leave_count=i['Leave Count'],
                                                                                            duration=i['Duration'],
                                                                                            paid_days=i['Paid Days'],
                                                                                            created_by=user_id)
        success_obj.set_status(SuccessStatus.SUCCESS)
        success_obj.set_message((arr))
        return success_obj

    def test_upload_summary(self, employee, month, year, vys_page ):
        apifunction = Payrollcommon_Apicall(self._scope())
        condition = Q(status=Activestatus.active)
        if employee != None and employee != "":
            emp_list = apifunction.emp_arr_function(employee)
            condition &= Q(employee_id__in=emp_list)
        if month != None and month != "":
            condition &= Q(month=month)
        if year != None and year != "":
            condition &= Q(year=year)
        payroll_test_info = PayrollTest.objects.using(self._current_app_schema()).filter(condition)[
                   vys_page.get_offset():vys_page.get_query_limit()]
        list_data = NWisefinList()
        if payroll_test_info.count() > 0:
            employee_arr = [i.employee_id for i in payroll_test_info]
            employee_info = apifunction.employee_get_value(employee_arr)
            for i in payroll_test_info:
                data_resp = Employeemonthly_payinfoResponse()
                data_resp.set_employee_val(i.employee_id, employee_info)
                data_resp.set_month(i.month)
                data_resp.set_paid_days(i.paid_days)
                data_resp.set_year(i.year)
                data_resp.set_leave_count(i.leave_count)
                data_resp.set_present_count(i.present_count)
                list_data.append(data_resp)
            vpage = NWisefinPaginator(payroll_test_info, vys_page.get_index(), 10)
            list_data.set_pagination(vpage)
        else:
            vpage = NWisefinPaginator([], vys_page.get_index(), 10)
            list_data.set_pagination(vpage)
        return list_data

    def payroll_test_present_count(self,request):
        from_month=request.GET.get('from_month')
        to_month=request.GET.get('to_month')
        from_year=request.GET.get('from_year')
        to_year=request.GET.get('to_year')
        condition=Q(status=Activestatus.active)
        if (from_month !=None and from_month !="") and (  to_month!=None and to_month!=""):
            condition &=Q(month__range=[from_month,to_month])
        if (from_year !=None and from_year !="") and (to_year !=None and to_year!=""):
            condition &=Q(year__range=[from_year,to_year])
        obj=PayrollTest.objects.using(self._current_app_schema()).filter(condition).values('paid_days','employee_id')
        f_month = int(from_month)
        t_month = int(to_month)
        f_year = int(from_year)
        t_year = int(to_year)
        days_count = 0
        for year in range(f_year, t_year + 1):
            for month in range(f_month, t_month + 1):
                num_days = monthrange(year, month)[1]
                days_count = days_count + num_days
        df1 = pd.DataFrame(obj)
        if len(df1) == 0:
            df1 = pd.DataFrame(columns=['paid_days','employee_id'])
        df1['paid_days']= df1['paid_days'].replace(np.nan, 0)
        df2=df1.to_dict('records')

        arr = NWisefinList()
        for i in df2:
                d = {"employee_id": i['employee_id'], "paid_days": i['paid_days'], "payable_days": days_count}
                arr.append(d)
        return arr

    def payroll_test_attendance_summary(self, body_data):
        employee_id = body_data.get('employee_id', None)
        smonth = body_data.get('month', None)
        syear = body_data.get('year', None)

        month = int(smonth)
        year = int(syear)
        days = monthrange(year, month)
        total_days = days[1]

        condition = Q(status=Activestatus.active)
        if (month !=None and month!="" )and (year!=None and year!=""):
            condition &= Q(month=month) & Q(year=year)
        if (employee_id is not None) and (employee_id != ''):
            condition &= Q(employee_id__in=employee_id)
        att_report = PayrollTest.objects.using(self._current_app_schema()).filter(condition).values('employee_id','paid_days')
        df1=pd.DataFrame(att_report)
        df1['paid_days']=df1['paid_days'].replace(np.nan, 0)
        df2 = df1.to_dict('records')

        arr=NWisefinList()

        for i in df2:
            attendancedict = {"payable_days": total_days, "employee_id": i['employee_id'], "paid_days": i['paid_days']}
            arr.append(attendancedict)
        return arr

    def update_payroll_paidstatus(self,approve_status,user_id):
        payroll_info = approve_status.drop_duplicates(subset=['Payshlip_code'])
        payroll_obj = payroll_info.to_dict(orient='records')
        code = [i['Payshlip_code'] for i in payroll_obj]
        payinfo = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active,code__in=code)
        if payinfo.count() > 0:
            update_paid = payinfo.update(pay_status=Advancestatus.paid, updated_by=user_id,updated_date=timezone.now())
            if update_paid > 0:
                success_obj = NWisefinSuccess()
                success_obj.set_status(SuccessStatus.SUCCESS)
                success_obj.set_message(SuccessMessage.UPDATE_MESSAGE)
            else:
                success_obj = NWisefinError()
                success_obj.set_code(ErrorMessage.UNEXPECTED_ERROR)
                success_obj.set_description(ErrorDescription.INVALID_DATA)
            return success_obj

    def get_columnnames_payinfo(self):
        payinfo = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active)
        if payinfo.count() >0:
            # employee_df = pd.DataFrame(payinfo.columns.values)
            payinfo_data = list(payinfo.values())
            payinfo_df1 = pd.DataFrame(payinfo_data)
            df_columns = payinfo_df1[['code','take_home','pay_status']]
            df_columns.rename(columns={'code': 'Payslip_code','take_home':'Net_salary'},inplace=True)
            payinfo_df = df_columns.columns
            return payinfo_df
        else:
            df = pd.DataFrame()
            return df


    # payrollschedualar manual_run
    def payrollshedular_manualrun(self, id):
        if id > 0:
            shedular_data = PayrollManualRunSchedular.objects.using(self._current_app_schema()).filter(id=id).delete()
            return shedular_data
        else:
            shedular_data = PayrollManualRunSchedular.objects.using(self._current_app_schema()).create(date=timezone.now())
            return shedular_data.id

    def payrollshedular_permonth(self, id):
        if id > 0:
            shedular_data = PayrollManualRunSchedular.objects.using(self._current_app_schema()).filter(id=id).update(is_completed=True)
            return shedular_data
        else:
            shedular_data = PayrollManualRunSchedular.objects.using(self._current_app_schema()).create(is_manual=False, date=timezone.now())
            return shedular_data.id

    def payrollshedular_check(self):
        shedular_data = PayrollManualRunSchedular.objects.using(self._current_app_schema()).filter(is_manual=True)
        return shedular_data.count()


    def schedular_payrollmanualrun(self,request):
        success_obj = NWisefinSuccess()
        try:
            schedular = payrollschedular.objects.using(self._current_app_schema()).create(start=timezone.now(),
                                                                                          created_date=timezone.now(),
                                                                                          created_by=1)
            year1 = request.GET.get('year')
            month1 = request.GET.get('month')
            if (year1 != None and year1 != '') and (month1 != None and month1 != ''):
                year = int(year1)
                month = int(month1)
                logger.info("-----PAYROLL_MANUAL_RUN_START------")
                # from datetime import datetime
                # date_time = datetime.now()
                from datetime import datetime, timedelta
                date_time = datetime(year, month + 1, 1) + timedelta(days=-1)
                if PAYROLL_TEST == 'TRUE':
                    emp_url = APPLICATION_BE_URL + '/payrollserv/payroll_test_attendance_summary'
                else:
                    emp_url = APPLICATION_BE_URL + '/atdserv/payroll_attendance_summary'
                data = {"month": month, "year": year}
                json_data = json.dumps(data)
                ip_address = APPLICATION_BE_URL + '/usrserv/auth_token'
                username = 'apuser'
                password = '1234'
                logger.info("------EMPLOYEE ATTENDANCE API CALL BEFORE--------" + str(emp_url))
                datas = json.dumps({"username": username, "password": password, "entity_id": 1})
                resp = requests.post(ip_address, data=datas, verify=False)
                token_data = json.loads(resp.content.decode("utf-8"))
                headers = {"content-type": "application/json", "Authorization": "Token " + token_data["token"] + ""}
                logger.info("TOKEN DATAS" + str(datas) and "TOKEN GENERATE" + str(headers))
                resp_obj = requests.post("" + emp_url, params='', data=json_data, headers=headers, verify=False)
                logger.info(
                    "------EMPLOYEE ATTENDANCE API CALL AFTER RESPONSE STATUS CODE--------" + str(resp_obj.status_code))
                emp_data_values = json.loads(resp_obj.content.decode("utf-8"))
                data_get = emp_data_values.get('data')
                df_data = pd.DataFrame(data_get)
                duplicates = df_data.drop_duplicates()
                data_val = duplicates.to_dict(orient='records')
                logger.info("------EMPLOYEE ATTENDANCE API CALL AFTER--------" + str(data_get))
                arr = []
                for j in data_val:
                    emp_id = j['employee_id']
                    arr.append(emp_id)
                val = set(arr)
                val = list(val)
                obj_val = EmployeePaystructure.objects.using(self._current_app_schema()).filter(
                    status=Activestatus.active, employee_id__in=val)
                list_val = [i.id for i in obj_val]
                obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(
                    status=Activestatus.active, emp_pay_id__in=list_val)

                for i in obj_val:
                    for j in data_val:
                        if i.employee_id == j['employee_id']:
                            month_pay = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter( status=Activestatus.active, payroll_date__month=month, payroll_date__year=year, employee_id=i.employee_id)
                            if month_pay.count() > 0:
                                allowance_date = Employeeadditional_allowance.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                       employee_id=i.employee_id,
                                                                       active_date__month__lte=month,
                                                                       end_date__month__gte=month,
                                                                       active_date__year__lte=year,
                                                                       end_date__year__gte=year)
                                for a in allowance_date:
                                    employee = a.employee_id
                                    type = a.type
                                    # payroll_mastermap = Payrollcommon_Apicall(self._scope()).get_segment_based_paycom(a.type)
                                    payroll_mastermap = PayrollmastermappingService( self._scope()).get_segment_based_paycom(a.type)
                                    if payroll_mastermap == []:
                                        payroll_mastermap = None
                                    active_date = a.active_date
                                    end_date = a.end_date
                                    amount = a.amount
                                    details = Employeemonthlypay_details.objects.using( self._current_app_schema()).filter(status=Activestatus.active,
                                                                           empmonthly_pay__employee_id=i.employee_id,
                                                                           paycomponent=type, from_date=active_date,
                                                                           to_date=end_date, amount=amount)
                                    if details.count() > 0:
                                        continue
                                    else:
                                        if a.custom_deduct == 0:
                                            paid_days = j['paid_days']
                                            payable_days = j['payable_days']
                                            employee_id = i.employee_id
                                            gross_pay = (float(i.gross_pay) * paid_days) / payable_days
                                            take_home = (float(i.take_home) * paid_days) / payable_days
                                            standard_ctc = (float(i.standard_ctc) * paid_days) / payable_days
                                            logger.info("------EMPLOYEE MONTHLY INFO GROSS_PAY AMOUNT--------" + str(gross_pay))
                                            obj_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                                                employee_id=employee_id,
                                                standard_ctc=standard_ctc,
                                                payable_days=payable_days,
                                                paid_days=paid_days,
                                                take_home=take_home,
                                                created_by=1,
                                                created_date=date_time,
                                                payroll_date=date_time.date(),
                                                gross_pay=gross_pay,
                                                pay_status=Advancestatus.draft)
                                            apifunction = Payrollcommon_Apicall(self._scope())
                                            code = apifunction.payslip_gen_code(CodeUtil.Employeemonthly_payinfo, 1, i.employee_id)
                                            logger.info("-----Employeemonthly_payinfo Code-----" + str(code))
                                            obj_data.code = code
                                            obj_data.save()
                                            logger.info("------Employeemonthly_payinfo Create success--------" + str(obj_data.code))

                                            emp_details = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                empmonthly_pay_id=obj_data.id,
                                                paycomponent=type,
                                                from_date=active_date,
                                                to_date=end_date,
                                                created_by=1,
                                                created_date=date_time,
                                                segment=payroll_mastermap,
                                                entity_id=self._entity_id(),
                                                amount=amount)
                                            logger.info("------Employeemonthlypay_details Create success--------" + str(emp_details.id))
                                        else:
                                            dedcut_data1 = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                                   deduct_date__month=month,
                                                                                   deduct_date__year=year,
                                                                                   employee_id=i.employee_id,
                                                                                   paycomponent_id=type)
                                            if dedcut_data1.count() > 0:
                                                continue
                                            else:
                                                deduct_data = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                    employee_id=employee,
                                                    paycomponent_id=type,
                                                    from_date=active_date,
                                                    to_date=end_date,
                                                    amount=amount,
                                                    created_by=1,
                                                    deduction_status=1,
                                                    deduct_date=date_time.date(),
                                                    created_date=date_time)
                                                logger.info("------Employeemonthlypay_details Create success--------" + str(deduct_data.id))
                                        continue
                            else:
                                paid_days = j['paid_days']
                                payable_days = j['payable_days']
                                employee_id = i.employee_id
                                is_esi = i.is_esi
                                pf_type = i.pf_type
                                gross_pay = (float(i.gross_pay) * paid_days) / payable_days
                                logger.info("------EMPLOYEE MONTHLY INFO GROSSPAY AMOUNT--------" + str(gross_pay))
                                # formula

                                take_home = (float(i.take_home) * paid_days) / payable_days
                                standard_ctc = (float(i.standard_ctc) * paid_days) / payable_days
                                obj_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                                    employee_id=employee_id,
                                    standard_ctc=standard_ctc,
                                    payable_days=payable_days,
                                    paid_days=paid_days,
                                    take_home=take_home,
                                    created_by=1,
                                    payroll_date=date_time.date(),
                                    created_date=date_time,
                                    gross_pay=gross_pay,
                                    pay_status=Advancestatus.draft,
                                    is_deduct=1)
                                apifunction = Payrollcommon_Apicall(self._scope())
                                code = apifunction.payslip_gen_code(CodeUtil.Employeemonthly_payinfo, 1, i.employee_id)
                                logger.info("-----Employeemonthly_payinfo Code-----" + str(code))
                                obj_data.code = code
                                obj_data.save()
                                logger.info("------Employeemonthly_payinfo Create success--------" + str(obj_data.code))
                                if obj_data.id > 0:
                                    monthly_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active,emp_pay__employee_id=employee_id)
                                    if monthly_details.count() > 0:
                                        for k in monthly_details:
                                            paycomponent = k.paycomponent
                                            paycomponent_type = k.paycomponent_type
                                            paycomponent_percentage = k.paycomponent_percentage
                                            segment_percentage = k.segment_percentage
                                            data_amt = k.amount
                                            print(data_amt)
                                            company_contribution = k.company_contribution
                                            type = k.type
                                            segment = k.segment
                                            from_date = k.from_date
                                            to_date = k.to_date
                                            if is_esi is (True or False) or get_pf_type(pf_type)['name'] == ('NORMAL_PF' or 'STANDARD_PF' or 'VIRTUAL_PF'):
                                                if company_contribution is True:
                                                    from django.db.models import Sum
                                                    # pf = Payrollcommon_Apicall(self._scope()).company_contribution_data(paycomponent)[0]
                                                    pf = CompanyContributionService(self._scope()).company_contribution_data(paycomponent)[0]
                                                    if get_pf_type(pf_type)['name'] == 'NORMAL_PF' or is_esi is (True or False):
                                                        # pf = CompanyContribution.objects.using(self._current_app_schema()).filter(status=1,id=paycomponent).values('id', 'name', 'percentage', 'amount')[0]
                                                        # flag_master=list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(map_id=pf.id).value_list('id'))
                                                        # flag_master = Payrollcommon_Apicall(self._scope()).list_of_map_id_data(pf['id'])
                                                        # flag_master = Payrollcommon_Apicall(self._scope()).cc_epf_based_paycom(pf['id'],FlagRef_Type.COMPANYCONTRIBUTION)
                                                        flag_master = PaycomponentFlagmasterService(self._scope()).cc_epf_based_paycom(pf['id'], FlagRef_Type.COMPANYCONTRIBUTION)
                                                        # flag_master = list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(status=1, map_id=pf['id']).values_list('ref_id', flat=True))
                                                        print(flag_master)
                                                        sum_amt = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(
                                                            status=Activestatus.active, paycomponent__in=flag_master,
                                                            empmonthly_pay__employee_id=employee_id,
                                                            empmonthly_pay__payroll_date__month=month,
                                                            empmonthly_pay__payroll_date__year=year,
                                                            company_contribution=False).aggregate(Sum('amount'))
                                                        logger.info("------COMPANY CONTRIBUTION SUM_AMT--------" + str(sum_amt))
                                                        sum_prec = float(sum_amt['amount__sum']) * float(pf['percentage']) / 100
                                                        if sum_amt['amount__sum'] != None:
                                                            print(sum_amt, 'iuh')
                                                            if pf['sal_amount'] == 0.00 or None:
                                                                if pf['amount'] < sum_prec:
                                                                    amount = round(pf['amount'])
                                                                else:
                                                                    amount = round(sum_prec)
                                                            else:
                                                                if is_esi is False:
                                                                    amount = 0.00
                                                                else:
                                                                    if sum_amt['amount__sum'] <= pf['sal_amount']:
                                                                        amount = round(sum_prec)
                                                                    else:
                                                                        amount = 0.00
                                                        else:
                                                            amount = 0.00
                                                    else:
                                                        amount = round(pf['amount'])
                                                elif type != None:
                                                    # created_dated = k.created_date.month
                                                    # if created_dated == month:
                                                    if payrolldeduction_val(type)['name'] == 'MONTHLY':
                                                        amount = round(float(data_amt) * paid_days / float(payable_days))
                                                        logger.info("------MONTHLY AMOUNT--------" + str(amount))
                                                    elif payrolldeduction_val(type)['name'] == 'QUARTERLY' or 'HALFYEARLY' or 'YEARLY' or 'CUSTOM':
                                                        month_data = self.bonus_month(type, month, year, date_time,from_date, to_date)
                                                        if month_data is None:
                                                            continue
                                                        else:
                                                            for y in month_data:
                                                                emp_id = y['employee_id']
                                                                if employee_id == emp_id:
                                                                    month_paid = y['paid_days']
                                                                    month_payable = y['payable_days']
                                                                    amount = round(float(data_amt) * month_paid / float(month_payable))
                                                                    logger.info("------'QUARTERLY' or 'HALFYEARLY' or 'YEARLY' CALCULATION--------" + str(amount))
                                                elif company_contribution is False or type is False:
                                                    cal_amount = float(gross_pay) * float(segment_percentage) / 100
                                                    amount = float(cal_amount) * float(paycomponent_percentage) / 100

                                            else:
                                                amount = 0.00

                                            data = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                empmonthly_pay_id=obj_data.id,
                                                paycomponent=paycomponent,
                                                paycomponent_type=paycomponent_type,
                                                paycomponent_percentage=paycomponent_percentage,
                                                company_contribution=company_contribution,
                                                amount=amount,
                                                type=type,
                                                segment=segment,
                                                created_by=1,
                                                created_date=date_time,
                                                segment_percentage=segment_percentage)
                                            logger.info("------Employeemonthlypay_details Create success--------" + str(data.id))
                                            continue

                                deduction_data = EmployeePaystructure_deductions.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id)
                                if deduction_data.count() > 0:
                                    for g in deduction_data:
                                        if g.is_customdeduct == 1:
                                            deduction_status = 1
                                        else:
                                            deduction_status = -1
                                        employee_id = g.employee_id
                                        paycomponent_id = g.paycomponent_id
                                        type = g.type
                                        if type == PayrollDeductionType.CUSTOM:
                                            from_date = g.from_date
                                            to_date = g.to_date
                                        else:
                                            from_date = date_time.date()
                                            to_date = date_time.date()
                                        amount = g.amount
                                        # if (deduction_status == 1 and type == PayrollDeductionType.CUSTOM) or deduction_status == -1:
                                        if from_date.month <= month and to_date.month >= month and from_date.year <= year and to_date.year >= year:
                                            logger.info(('--------------------------PAYSTRUCTURE DEDUCT TO MONTHLY DEDUCT DATA CUSTOM DEDUCTION-----------------------------------------------------------'))
                                            if deduction_status == -1:
                                                deduction_cal = self.monthly_deduction_calculation(employee_id,  paycomponent_id, month, year, is_esi, pf_type)
                                            else:
                                                deduction_cal = amount
                                            deduction = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=employee_id,
                                                                                   paycomponent_id=paycomponent_id,
                                                                                   type=type,
                                                                                   from_date=from_date,
                                                                                   to_date=to_date,
                                                                                   amount=deduction_cal,
                                                                                   created_by=1,
                                                                                   deduct_date=date_time.date(),
                                                                                   created_date=date_time,
                                                                                   deduction_status=deduction_status)
                                            logger.info("-----Employeemonthlypay_deductions Create success--------" + str(deduction.id))
                                process_data = Payrollprocesschange.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id, from_date__month__lte=month, to_date__month__gte=month, from_date__year__lte=year, to_date__year__gte=year)
                                if process_data.count() > 0:
                                    for m in process_data:
                                        employee_id = m.employee_id
                                        pay_change = m.pay_change
                                        Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=employee_id).update(pay_status=pay_change)
                                        logger.info("------EMPLOYEEMONTHLY_PAYINFO UPDATED PAY_STATUS--------" + str(pay_change))

                                allowance_date = Employeeadditional_allowance.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                       employee_id=i.employee_id,
                                                                       active_date__month__lte=month,
                                                                       end_date__month__gte=month,
                                                                       active_date__year__lte=year,
                                                                       end_date__year__gte=year)
                                if allowance_date.count() > 0:
                                    for a in allowance_date:
                                        employee = a.employee_id
                                        type = a.type
                                        # payroll_mastermap = Payrollcommon_Apicall(self._scope()).get_segment_based_paycom(a.type)
                                        payroll_mastermap = PayrollmastermappingService(self._scope()).get_segment_based_paycom(a.type)
                                        if payroll_mastermap == []:
                                            payroll_mastermap = None
                                        active_date = a.active_date
                                        end_date = a.end_date
                                        amount = a.amount
                                        month_details = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                               employee_id=employee,
                                                                               payroll_date__month=month,
                                                                               payroll_date__year=year)
                                        if month_details.count() > 0:
                                            if a.custom_deduct == 0:
                                                details = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(empmonthly_pay_id=month_details[0].id, paycomponent=type,from_date=active_date, to_date=end_date, amount=amount)
                                                if details.count() > 0:
                                                    continue
                                                else:
                                                    emp_details = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                        empmonthly_pay_id=month_details[0].id,
                                                        paycomponent=type,
                                                        from_date=active_date,
                                                        to_date=end_date,
                                                        segment=payroll_mastermap,
                                                        created_by=1,
                                                        created_date=date_time,
                                                        amount=amount)
                                                    logger.info("------Employeemonthlypay_details Create success--------" + str(emp_details.id))
                                            else:
                                                deduct_data = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                    employee_id=employee,
                                                    paycomponent_id=type,
                                                    from_date=active_date,
                                                    to_date=end_date,
                                                    amount=amount,
                                                    deduction_status=1,
                                                    created_by=1,
                                                    deduct_date=date_time.date(),
                                                    created_date=date_time)
                                                logger.info(
                                                    "------Employeemonthlypay_details Create success--------" + str(
                                                        deduct_data.id))
                                            continue
                                # advance
                                advance_pay = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(
                                    status=Activestatus.active, advance__employee_id=i.employee_id,
                                    advance__from_date__month__lte=month, advance__to_date__month__gte=month,
                                    advance__from_date__year__lte=year, advance__to_date__year__gte=year)
                                if advance_pay.count() > 0:
                                    advance_id = [i.advance_id for i in advance_pay]
                                    unique_advance_id = list(set(advance_id))
                                    for ids in unique_advance_id:
                                        advance1 = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                               advance__id=ids).values('id',
                                                                                                       'advance_id',
                                                                                                       'balance_amount',
                                                                                                       'advance__emi_amount',
                                                                                                       'advance__employee_id',
                                                                                                       'advance__from_date',
                                                                                                       'advance__to_date').last()
                                        if advance1 is not None:
                                            # if advance1.count() > 0:
                                            if 0.00 <= advance1['balance_amount'] <= 0.50 or None:
                                                update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=advance1['advance_id']).update(
                                                    advance_status=Advancestatus.closed, updated_by=1,
                                                    updated_date=date_time)
                                                logger.info("-----Employeeadvancedetails update status closed emi bal=0---------" + str( advance1['advance_id']))
                                                continue
                                            else:
                                                advance_id = advance1['advance_id']
                                                paid_amount = advance1['advance__emi_amount']
                                                balance_amount = advance1['balance_amount']
                                                employee_payment = advance1['advance__employee_id']
                                                from_date_payment = advance1['advance__from_date']
                                                to_date_payment = advance1['advance__to_date']
                                                amount = abs(float(paid_amount - balance_amount))
                                                # advance_type = Advancetype.advance
                                                advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=advance_id,
                                                                                       paid_date=date_time,
                                                                                       balance_amount=amount,
                                                                                       paid_amount=paid_amount,
                                                                                       created_by=1,
                                                                                       created_date=date_time)

                                                logger.info("------Employeeadvancepayment Create success--------" + str(
                                                    advancepayment.id))
                                                if 0.00 <= advancepayment.balance_amount <= 0.50 or None:
                                                    update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(
                                                        id=advancepayment.advance_id).update(
                                                        advance_status=Advancestatus.closed, updated_by=1,
                                                        updated_date=date_time)
                                                    logger.info(
                                                        "-----Employeeadvancedetails update status closed emi bal=0---------" + str(
                                                            advancepayment.advance_id))

                                                advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=employee_payment,
                                                                                       from_date=from_date_payment,
                                                                                       to_date=to_date_payment,
                                                                                       amount=paid_amount,
                                                                                       created_by=1,
                                                                                       deduction_status=1,
                                                                                       deduct_date=date_time.date(),
                                                                                       created_date=date_time,
                                                                                       is_advance=1)
                                                logger.info("------Employeemonthlypay_deductions Create success--------" + str(advance_deduct.id))

                                            # second advance create
                                            condition = ~Q(id__in=unique_advance_id)
                                            advancedetails1 = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(condition,
                                                                                   status=Activestatus.active,
                                                                                   employee_id=i.employee_id,
                                                                                   advance_status=Advancestatus.paid,
                                                                                   from_date__month__lte=month,
                                                                                   to_date__month__gte=month,
                                                                                   from_date__year__lte=year,
                                                                                   to_date__year__gte=year)
                                            if advancedetails1.count() > 0:
                                                for s1 in advancedetails1:
                                                    id = s1.id
                                                    paid_amount = s1.emi_amount
                                                    deduct_advance_employee = s1.employee_id
                                                    balance_amount = abs(float(s1.payable_amount - paid_amount))
                                                    from_date = s1.from_date
                                                    to_date = s1.to_date
                                                    advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                                                                                           paid_date=date_time,
                                                                                           balance_amount=balance_amount,
                                                                                           paid_amount=paid_amount,
                                                                                           created_by=1,
                                                                                           created_date=date_time)
                                                    logger.info("-----Employeeadvancepayment create success---------" + str(advancepayment.id))
                                                    update = Employeeadvancedetails.objects.using( self._current_app_schema()).filter(id=id).update(
                                                        advance_status=Advancestatus.open, updated_by=1,
                                                        updated_date=date_time)
                                                    logger.info("-----Employeeadvancedetails update status open emi bal>0---------" + str(update.id))

                                                    advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                        employee_id=deduct_advance_employee,
                                                        from_date=from_date,
                                                        to_date=to_date,
                                                        amount=paid_amount,
                                                        created_by=1,
                                                        deduction_status=1,
                                                        deduct_date=date_time.date(),
                                                        created_date=date_time,
                                                        is_advance=1)

                                        continue
                                else:
                                    advancedetails = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                           employee_id=i.employee_id,
                                                                           advance_status=Advancestatus.paid,
                                                                           from_date__month__lte=month,
                                                                           to_date__month__gte=month,
                                                                           from_date__year__lte=year,
                                                                           to_date__year__gte=year)
                                    if advancedetails.count() > 0:
                                        for s in advancedetails:
                                            id = s.id
                                            paid_amount = s.emi_amount
                                            deduct_advance_employee = s.employee_id
                                            balance_amount = abs(float(s.payable_amount - paid_amount))
                                            from_date = s.from_date
                                            to_date = s.to_date
                                            advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                                                                                   paid_date=date_time,
                                                                                   balance_amount=balance_amount,
                                                                                   paid_amount=paid_amount,
                                                                                   created_by=1,
                                                                                   created_date=date_time)
                                            logger.info("-----Employeeadvancepayment create success---------" + str(advancepayment.id))
                                            update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=id).update(advance_status=Advancestatus.open, updated_by=1, updated_date=date_time)
                                            logger.info( "-----Employeeadvancedetails update status open emi bal>0---------" + str( id))

                                            advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=deduct_advance_employee,
                                                                                   from_date=from_date,
                                                                                   to_date=to_date,
                                                                                   amount=paid_amount,
                                                                                   created_by=1,
                                                                                   deduction_status=1,
                                                                                   deduct_date=date_time.date(),
                                                                                   created_date=date_time,
                                                                                   is_advance=1)
                                            logger.info("-----Employeemonthlypay_deductions create success---------" + str( advance_deduct.id))

                success_obj.set_status(SuccessStatus.SUCCESS)
                success_obj.set_message('DATA INSERTED SUCCESSFULLY')
                schedular1 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update(
                    end=timezone.now(), message='DATA INSERTED SUCCESSFULLY')
                return success_obj
            else:
                obj = Error()
                obj.payrollmanual_run = {"message": "Please Select Month and Year "}
                obj.set_code(ErrorMessage.INVALID_DATA)
                obj.set_description(ErrorDescription.ALREADY_EXISTS)
                schedular2 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update( end=timezone.now(), message='Please Select Month and Year')
                return obj
        except Exception as excep:
            obj = Error()
            obj.payrollmanual_run = {"error": str(excep)}
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(ErrorDescription.ALREADY_EXISTS)
            schedular3 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update( end=timezone.now(), message=str(excep))
            return obj

    def schedular_payrollmanualrun1(self):
        success_obj = NWisefinSuccess()
        try:
            schedular = payrollschedular.objects.using(self._current_app_schema()).create(start=timezone.now(),
                                                                                          created_date=timezone.now(),
                                                                                          created_by=1)
            from datetime import datetime
            date_time = datetime.now()
            month = int(date_time.strftime("%m"))
            year = int(date_time.strftime("%Y"))
            month1 = datetime.now().month
            year1 = datetime.now().year
            if (year1 != None and year1 != '') and (month1 != None and month1 != ''):
                # year = int(year1)
                # month = int(month1)
                logger.info("-----PAYROLL_MANUAL_RUN_START------")
                # from datetime import datetime
                # date_time = datetime.now()
                from datetime import datetime, timedelta
                date_time = datetime(year, month + 1, 1) + timedelta(days=-1)
                if PAYROLL_TEST == 'TRUE':
                    emp_url = APPLICATION_BE_URL + '/payrollserv/payroll_test_attendance_summary'
                else:
                    emp_url = APPLICATION_BE_URL + '/atdserv/payroll_attendance_summary'
                data = {"month": month, "year": year}
                json_data = json.dumps(data)
                ip_address = APPLICATION_BE_URL + '/usrserv/auth_token'
                username = 'apuser'
                password = '1234'
                logger.info("------EMPLOYEE ATTENDANCE API CALL BEFORE--------" + str(emp_url))
                datas = json.dumps({"username": username, "password": password, "entity_id": 1})
                resp = requests.post(ip_address, data=datas, verify=False)
                token_data = json.loads(resp.content.decode("utf-8"))
                headers = {"content-type": "application/json", "Authorization": "Token " + token_data["token"] + ""}
                logger.info("TOKEN DATAS" + str(datas) and "TOKEN GENERATE" + str(headers))
                resp_obj = requests.post("" + emp_url, params='', data=json_data, headers=headers, verify=False)
                logger.info(
                    "------EMPLOYEE ATTENDANCE API CALL AFTER RESPONSE STATUS CODE--------" + str(resp_obj.status_code))
                emp_data_values = json.loads(resp_obj.content.decode("utf-8"))
                data_get = emp_data_values.get('data')
                df_data = pd.DataFrame(data_get)
                duplicates = df_data.drop_duplicates()
                data_val = duplicates.to_dict(orient='records')
                logger.info("------EMPLOYEE ATTENDANCE API CALL AFTER--------" + str(data_get))
                arr = []
                for j in data_val:
                    emp_id = j['employee_id']
                    arr.append(emp_id)
                val = set(arr)
                val = list(val)
                obj_val = EmployeePaystructure.objects.using(self._current_app_schema()).filter(
                    status=Activestatus.active, employee_id__in=val)
                list_val = [i.id for i in obj_val]
                obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(
                    status=Activestatus.active, emp_pay_id__in=list_val)

                for i in obj_val:
                    for j in data_val:
                        if i.employee_id == j['employee_id']:
                            month_pay = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter( status=Activestatus.active, payroll_date__month=month, payroll_date__year=year, employee_id=i.employee_id)
                            if month_pay.count() > 0:
                                allowance_date = Employeeadditional_allowance.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                       employee_id=i.employee_id,
                                                                       active_date__month__lte=month,
                                                                       end_date__month__gte=month,
                                                                       active_date__year__lte=year,
                                                                       end_date__year__gte=year)
                                for a in allowance_date:
                                    employee = a.employee_id
                                    type = a.type
                                    # payroll_mastermap = Payrollcommon_Apicall(self._scope()).get_segment_based_paycom(a.type)
                                    payroll_mastermap = PayrollmastermappingService( self._scope()).get_segment_based_paycom(a.type)
                                    if payroll_mastermap == []:
                                        payroll_mastermap = None
                                    active_date = a.active_date
                                    end_date = a.end_date
                                    amount = a.amount
                                    details = Employeemonthlypay_details.objects.using( self._current_app_schema()).filter(status=Activestatus.active,
                                                                           empmonthly_pay__employee_id=i.employee_id,
                                                                           paycomponent=type, from_date=active_date,
                                                                           to_date=end_date, amount=amount)
                                    if details.count() > 0:
                                        continue
                                    else:
                                        if a.custom_deduct == 0:
                                            paid_days = j['paid_days']
                                            payable_days = j['payable_days']
                                            employee_id = i.employee_id
                                            gross_pay = (float(i.gross_pay) * paid_days) / payable_days
                                            take_home = (float(i.take_home) * paid_days) / payable_days
                                            standard_ctc = (float(i.standard_ctc) * paid_days) / payable_days
                                            logger.info("------EMPLOYEE MONTHLY INFO GROSS_PAY AMOUNT--------" + str(gross_pay))
                                            obj_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                                                employee_id=employee_id,
                                                standard_ctc=standard_ctc,
                                                payable_days=payable_days,
                                                paid_days=paid_days,
                                                take_home=take_home,
                                                created_by=1,
                                                created_date=date_time,
                                                payroll_date=date_time.date(),
                                                gross_pay=gross_pay,
                                                pay_status=Advancestatus.draft)
                                            apifunction = Payrollcommon_Apicall(self._scope())
                                            code = apifunction.payslip_gen_code(CodeUtil.Employeemonthly_payinfo, 1, i.employee_id)
                                            logger.info("-----Employeemonthly_payinfo Code-----" + str(code))
                                            obj_data.code = code
                                            obj_data.save()
                                            logger.info("------Employeemonthly_payinfo Create success--------" + str(obj_data.code))

                                            emp_details = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                empmonthly_pay_id=obj_data.id,
                                                paycomponent=type,
                                                from_date=active_date,
                                                to_date=end_date,
                                                created_by=1,
                                                created_date=date_time,
                                                segment=payroll_mastermap,
                                                entity_id=self._entity_id(),
                                                amount=amount)
                                            logger.info("------Employeemonthlypay_details Create success--------" + str(emp_details.id))
                                        else:
                                            dedcut_data1 = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                                   deduct_date__month=month,
                                                                                   deduct_date__year=year,
                                                                                   employee_id=i.employee_id,
                                                                                   paycomponent_id=type)
                                            if dedcut_data1.count() > 0:
                                                continue
                                            else:
                                                deduct_data = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                    employee_id=employee,
                                                    paycomponent_id=type,
                                                    from_date=active_date,
                                                    to_date=end_date,
                                                    amount=amount,
                                                    created_by=1,
                                                    deduction_status=1,
                                                    deduct_date=date_time.date(),
                                                    created_date=date_time)
                                                logger.info("------Employeemonthlypay_details Create success--------" + str(deduct_data.id))
                                        continue
                            else:
                                paid_days = j['paid_days']
                                payable_days = j['payable_days']
                                employee_id = i.employee_id
                                is_esi = i.is_esi
                                pf_type = i.pf_type
                                gross_pay = (float(i.gross_pay) * paid_days) / payable_days
                                logger.info("------EMPLOYEE MONTHLY INFO GROSSPAY AMOUNT--------" + str(gross_pay))
                                # formula

                                take_home = (float(i.take_home) * paid_days) / payable_days
                                standard_ctc = (float(i.standard_ctc) * paid_days) / payable_days
                                obj_data = Employeemonthly_payinfo.objects.using(self._current_app_schema()).create(
                                    employee_id=employee_id,
                                    standard_ctc=standard_ctc,
                                    payable_days=payable_days,
                                    paid_days=paid_days,
                                    take_home=take_home,
                                    created_by=1,
                                    payroll_date=date_time.date(),
                                    created_date=date_time,
                                    gross_pay=gross_pay,
                                    pay_status=Advancestatus.draft,
                                    is_deduct=1)
                                apifunction = Payrollcommon_Apicall(self._scope())
                                code = apifunction.payslip_gen_code(CodeUtil.Employeemonthly_payinfo, 1, i.employee_id)
                                logger.info("-----Employeemonthly_payinfo Code-----" + str(code))
                                obj_data.code = code
                                obj_data.save()
                                logger.info("------Employeemonthly_payinfo Create success--------" + str(obj_data.code))
                                if obj_data.id > 0:
                                    monthly_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active,emp_pay__employee_id=employee_id)
                                    if monthly_details.count() > 0:
                                        for k in monthly_details:
                                            paycomponent = k.paycomponent
                                            paycomponent_type = k.paycomponent_type
                                            paycomponent_percentage = k.paycomponent_percentage
                                            segment_percentage = k.segment_percentage
                                            data_amt = k.amount
                                            print(data_amt)
                                            company_contribution = k.company_contribution
                                            type = k.type
                                            segment = k.segment
                                            from_date = k.from_date
                                            to_date = k.to_date
                                            if is_esi is (True or False) or get_pf_type(pf_type)['name'] == ('NORMAL_PF' or 'STANDARD_PF' or 'VIRTUAL_PF'):
                                                if company_contribution is True:
                                                    from django.db.models import Sum
                                                    # pf = Payrollcommon_Apicall(self._scope()).company_contribution_data(paycomponent)[0]
                                                    pf = CompanyContributionService(self._scope()).company_contribution_data(paycomponent)[0]
                                                    if get_pf_type(pf_type)['name'] == 'NORMAL_PF' or is_esi is (True or False):
                                                        # pf = CompanyContribution.objects.using(self._current_app_schema()).filter(status=1,id=paycomponent).values('id', 'name', 'percentage', 'amount')[0]
                                                        # flag_master=list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(map_id=pf.id).value_list('id'))
                                                        # flag_master = Payrollcommon_Apicall(self._scope()).list_of_map_id_data(pf['id'])
                                                        # flag_master = Payrollcommon_Apicall(self._scope()).cc_epf_based_paycom(pf['id'],FlagRef_Type.COMPANYCONTRIBUTION)
                                                        flag_master = PaycomponentFlagmasterService(self._scope()).cc_epf_based_paycom(pf['id'], FlagRef_Type.COMPANYCONTRIBUTION)
                                                        # flag_master = list(PaycomponentFlagmaster.objects.using(self._current_app_schema()).filter(status=1, map_id=pf['id']).values_list('ref_id', flat=True))
                                                        print(flag_master)
                                                        sum_amt = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(
                                                            status=Activestatus.active, paycomponent__in=flag_master,
                                                            empmonthly_pay__employee_id=employee_id,
                                                            empmonthly_pay__payroll_date__month=month,
                                                            empmonthly_pay__payroll_date__year=year,
                                                            company_contribution=False).aggregate(Sum('amount'))
                                                        logger.info("------COMPANY CONTRIBUTION SUM_AMT--------" + str(sum_amt))
                                                        sum_prec = float(sum_amt['amount__sum']) * float(pf['percentage']) / 100
                                                        if sum_amt['amount__sum'] != None:
                                                            print(sum_amt, 'iuh')
                                                            if pf['sal_amount'] == 0.00 or None:
                                                                if pf['amount'] < sum_prec:
                                                                    amount = round(pf['amount'])
                                                                else:
                                                                    amount = round(sum_prec)
                                                            else:
                                                                if is_esi is False:
                                                                    amount = 0.00
                                                                else:
                                                                    if sum_amt['amount__sum'] <= pf['sal_amount']:
                                                                        amount = round(sum_prec)
                                                                    else:
                                                                        amount = 0.00
                                                        else:
                                                            amount = 0.00
                                                    else:
                                                        amount = round(pf['amount'])
                                                elif type != None:
                                                    # created_dated = k.created_date.month
                                                    # if created_dated == month:
                                                    if payrolldeduction_val(type)['name'] == 'MONTHLY':
                                                        amount = round(float(data_amt) * paid_days / float(payable_days))
                                                        logger.info("------MONTHLY AMOUNT--------" + str(amount))
                                                    elif payrolldeduction_val(type)['name'] == 'QUARTERLY' or 'HALFYEARLY' or 'YEARLY' or 'CUSTOM':
                                                        month_data = self.bonus_month(type, month, year, date_time,from_date, to_date)
                                                        if month_data is None:
                                                            continue
                                                        else:
                                                            for y in month_data:
                                                                emp_id = y['employee_id']
                                                                if employee_id == emp_id:
                                                                    month_paid = y['paid_days']
                                                                    month_payable = y['payable_days']
                                                                    amount = round(float(data_amt) * month_paid / float(month_payable))
                                                                    logger.info("------'QUARTERLY' or 'HALFYEARLY' or 'YEARLY' CALCULATION--------" + str(amount))
                                                elif company_contribution is False or type is False:
                                                    cal_amount = float(gross_pay) * float(segment_percentage) / 100
                                                    amount = float(cal_amount) * float(paycomponent_percentage) / 100

                                            else:
                                                amount = 0.00

                                            data = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                empmonthly_pay_id=obj_data.id,
                                                paycomponent=paycomponent,
                                                paycomponent_type=paycomponent_type,
                                                paycomponent_percentage=paycomponent_percentage,
                                                company_contribution=company_contribution,
                                                amount=amount,
                                                type=type,
                                                segment=segment,
                                                created_by=1,
                                                created_date=date_time,
                                                segment_percentage=segment_percentage)
                                            logger.info("------Employeemonthlypay_details Create success--------" + str(data.id))
                                            continue

                                deduction_data = EmployeePaystructure_deductions.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id)
                                if deduction_data.count() > 0:
                                    for g in deduction_data:
                                        if g.is_customdeduct == 1:
                                            deduction_status = 1
                                        else:
                                            deduction_status = -1
                                        employee_id = g.employee_id
                                        paycomponent_id = g.paycomponent_id
                                        type = g.type
                                        if type == PayrollDeductionType.CUSTOM:
                                            from_date = g.from_date
                                            to_date = g.to_date
                                        else:
                                            from_date = date_time.date()
                                            to_date = date_time.date()
                                        amount = g.amount
                                        # if (deduction_status == 1 and type == PayrollDeductionType.CUSTOM) or deduction_status == -1:
                                        if from_date.month <= month and to_date.month >= month and from_date.year <= year and to_date.year >= year:
                                            logger.info(('--------------------------PAYSTRUCTURE DEDUCT TO MONTHLY DEDUCT DATA CUSTOM DEDUCTION-----------------------------------------------------------'))
                                            if deduction_status == -1:
                                                deduction_cal = self.monthly_deduction_calculation(employee_id,  paycomponent_id, month, year, is_esi, pf_type)
                                            else:
                                                deduction_cal = amount
                                            deduction = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=employee_id,
                                                                                   paycomponent_id=paycomponent_id,
                                                                                   type=type,
                                                                                   from_date=from_date,
                                                                                   to_date=to_date,
                                                                                   amount=deduction_cal,
                                                                                   created_by=1,
                                                                                   deduct_date=date_time.date(),
                                                                                   created_date=date_time,
                                                                                   deduction_status=deduction_status)
                                            logger.info("-----Employeemonthlypay_deductions Create success--------" + str(deduction.id))
                                process_data = Payrollprocesschange.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=i.employee_id, from_date__month__lte=month, to_date__month__gte=month, from_date__year__lte=year, to_date__year__gte=year)
                                if process_data.count() > 0:
                                    for m in process_data:
                                        employee_id = m.employee_id
                                        pay_change = m.pay_change
                                        Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active, employee_id=employee_id).update(pay_status=pay_change)
                                        logger.info("------EMPLOYEEMONTHLY_PAYINFO UPDATED PAY_STATUS--------" + str(pay_change))

                                allowance_date = Employeeadditional_allowance.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                       employee_id=i.employee_id,
                                                                       active_date__month__lte=month,
                                                                       end_date__month__gte=month,
                                                                       active_date__year__lte=year,
                                                                       end_date__year__gte=year)
                                if allowance_date.count() > 0:
                                    for a in allowance_date:
                                        employee = a.employee_id
                                        type = a.type
                                        # payroll_mastermap = Payrollcommon_Apicall(self._scope()).get_segment_based_paycom(a.type)
                                        payroll_mastermap = PayrollmastermappingService(self._scope()).get_segment_based_paycom(a.type)
                                        if payroll_mastermap == []:
                                            payroll_mastermap = None
                                        active_date = a.active_date
                                        end_date = a.end_date
                                        amount = a.amount
                                        month_details = Employeemonthly_payinfo.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                               employee_id=employee,
                                                                               payroll_date__month=month,
                                                                               payroll_date__year=year)
                                        if month_details.count() > 0:
                                            if a.custom_deduct == 0:
                                                details = Employeemonthlypay_details.objects.using(self._current_app_schema()).filter(empmonthly_pay_id=month_details[0].id, paycomponent=type,from_date=active_date, to_date=end_date, amount=amount)
                                                if details.count() > 0:
                                                    continue
                                                else:
                                                    emp_details = Employeemonthlypay_details.objects.using(self._current_app_schema()).create(
                                                        empmonthly_pay_id=month_details[0].id,
                                                        paycomponent=type,
                                                        from_date=active_date,
                                                        to_date=end_date,
                                                        segment=payroll_mastermap,
                                                        created_by=1,
                                                        created_date=date_time,
                                                        amount=amount)
                                                    logger.info("------Employeemonthlypay_details Create success--------" + str(emp_details.id))
                                            else:
                                                deduct_data = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                    employee_id=employee,
                                                    paycomponent_id=type,
                                                    from_date=active_date,
                                                    to_date=end_date,
                                                    amount=amount,
                                                    deduction_status=1,
                                                    created_by=1,
                                                    deduct_date=date_time.date(),
                                                    created_date=date_time)
                                                logger.info(
                                                    "------Employeemonthlypay_details Create success--------" + str(
                                                        deduct_data.id))
                                            continue
                                # advance
                                advance_pay = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(
                                    status=Activestatus.active, advance__employee_id=i.employee_id,
                                    advance__from_date__month__lte=month, advance__to_date__month__gte=month,
                                    advance__from_date__year__lte=year, advance__to_date__year__gte=year)
                                if advance_pay.count() > 0:
                                    advance_id = [i.advance_id for i in advance_pay]
                                    unique_advance_id = list(set(advance_id))
                                    for ids in unique_advance_id:
                                        advance1 = Employeeadvancepayment.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                               advance__id=ids).values('id',
                                                                                                       'advance_id',
                                                                                                       'balance_amount',
                                                                                                       'advance__emi_amount',
                                                                                                       'advance__employee_id',
                                                                                                       'advance__from_date',
                                                                                                       'advance__to_date').last()
                                        if advance1 is not None:
                                            # if advance1.count() > 0:
                                            if 0.00 <= advance1['balance_amount'] <= 0.50 or None:
                                                update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=advance1['advance_id']).update(
                                                    advance_status=Advancestatus.closed, updated_by=1,
                                                    updated_date=date_time)
                                                logger.info("-----Employeeadvancedetails update status closed emi bal=0---------" + str( advance1['advance_id']))
                                                continue
                                            else:
                                                advance_id = advance1['advance_id']
                                                paid_amount = advance1['advance__emi_amount']
                                                balance_amount = advance1['balance_amount']
                                                employee_payment = advance1['advance__employee_id']
                                                from_date_payment = advance1['advance__from_date']
                                                to_date_payment = advance1['advance__to_date']
                                                amount = abs(float(paid_amount - balance_amount))
                                                # advance_type = Advancetype.advance
                                                advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=advance_id,
                                                                                       paid_date=date_time,
                                                                                       balance_amount=amount,
                                                                                       paid_amount=paid_amount,
                                                                                       created_by=1,
                                                                                       created_date=date_time)

                                                logger.info("------Employeeadvancepayment Create success--------" + str(
                                                    advancepayment.id))
                                                if 0.00 <= advancepayment.balance_amount <= 0.50 or None:
                                                    update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(
                                                        id=advancepayment.advance_id).update(
                                                        advance_status=Advancestatus.closed, updated_by=1,
                                                        updated_date=date_time)
                                                    logger.info(
                                                        "-----Employeeadvancedetails update status closed emi bal=0---------" + str(
                                                            advancepayment.advance_id))

                                                advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=employee_payment,
                                                                                       from_date=from_date_payment,
                                                                                       to_date=to_date_payment,
                                                                                       amount=paid_amount,
                                                                                       created_by=1,
                                                                                       deduction_status=1,
                                                                                       deduct_date=date_time.date(),
                                                                                       created_date=date_time,
                                                                                       is_advance=1)
                                                logger.info("------Employeemonthlypay_deductions Create success--------" + str(advance_deduct.id))

                                            # second advance create
                                            condition = ~Q(id__in=unique_advance_id)
                                            advancedetails1 = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(condition,
                                                                                   status=Activestatus.active,
                                                                                   employee_id=i.employee_id,
                                                                                   advance_status=Advancestatus.paid,
                                                                                   from_date__month__lte=month,
                                                                                   to_date__month__gte=month,
                                                                                   from_date__year__lte=year,
                                                                                   to_date__year__gte=year)
                                            if advancedetails1.count() > 0:
                                                for s1 in advancedetails1:
                                                    id = s1.id
                                                    paid_amount = s1.emi_amount
                                                    deduct_advance_employee = s1.employee_id
                                                    balance_amount = abs(float(s1.payable_amount - paid_amount))
                                                    from_date = s1.from_date
                                                    to_date = s1.to_date
                                                    advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                                                                                           paid_date=date_time,
                                                                                           balance_amount=balance_amount,
                                                                                           paid_amount=paid_amount,
                                                                                           created_by=1,
                                                                                           created_date=date_time)
                                                    logger.info("-----Employeeadvancepayment create success---------" + str(advancepayment.id))
                                                    update = Employeeadvancedetails.objects.using( self._current_app_schema()).filter(id=id).update(
                                                        advance_status=Advancestatus.open, updated_by=1,
                                                        updated_date=date_time)
                                                    logger.info("-----Employeeadvancedetails update status open emi bal>0---------" + str(update.id))

                                                    advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(
                                                        employee_id=deduct_advance_employee,
                                                        from_date=from_date,
                                                        to_date=to_date,
                                                        amount=paid_amount,
                                                        created_by=1,
                                                        deduction_status=1,
                                                        deduct_date=date_time.date(),
                                                        created_date=date_time,
                                                        is_advance=1)

                                        continue
                                else:
                                    advancedetails = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(status=Activestatus.active,
                                                                           employee_id=i.employee_id,
                                                                           advance_status=Advancestatus.paid,
                                                                           from_date__month__lte=month,
                                                                           to_date__month__gte=month,
                                                                           from_date__year__lte=year,
                                                                           to_date__year__gte=year)
                                    if advancedetails.count() > 0:
                                        for s in advancedetails:
                                            id = s.id
                                            paid_amount = s.emi_amount
                                            deduct_advance_employee = s.employee_id
                                            balance_amount = abs(float(s.payable_amount - paid_amount))
                                            from_date = s.from_date
                                            to_date = s.to_date
                                            advancepayment = Employeeadvancepayment.objects.using(self._current_app_schema()).create(advance_id=id,
                                                                                   paid_date=date_time,
                                                                                   balance_amount=balance_amount,
                                                                                   paid_amount=paid_amount,
                                                                                   created_by=1,
                                                                                   created_date=date_time)
                                            logger.info("-----Employeeadvancepayment create success---------" + str(advancepayment.id))
                                            update = Employeeadvancedetails.objects.using(self._current_app_schema()).filter(id=id).update(advance_status=Advancestatus.open, updated_by=1, updated_date=date_time)
                                            logger.info( "-----Employeeadvancedetails update status open emi bal>0---------" + str( id))

                                            advance_deduct = Employeemonthlypay_deductions.objects.using(self._current_app_schema()).create(employee_id=deduct_advance_employee,
                                                                                   from_date=from_date,
                                                                                   to_date=to_date,
                                                                                   amount=paid_amount,
                                                                                   created_by=1,
                                                                                   deduction_status=1,
                                                                                   deduct_date=date_time.date(),
                                                                                   created_date=date_time,
                                                                                   is_advance=1)
                                            logger.info("-----Employeemonthlypay_deductions create success---------" + str( advance_deduct.id))

                success_obj.set_status(SuccessStatus.SUCCESS)
                success_obj.set_message('DATA INSERTED SUCCESSFULLY')
                schedular1 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update(
                    end=timezone.now(), message='DATA INSERTED SUCCESSFULLY')
                return success_obj
            else:
                obj = Error()
                obj.payrollmanual_run = {"message": "Please Select Month and Year "}
                obj.set_code(ErrorMessage.INVALID_DATA)
                obj.set_description(ErrorDescription.ALREADY_EXISTS)
                schedular2 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update( end=timezone.now(), message='Please Select Month and Year')
                return obj
        except Exception as excep:
            obj = Error()
            obj.payrollmanual_run = {"error": str(excep)}
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(ErrorDescription.ALREADY_EXISTS)
            schedular3 = payrollschedular.objects.using(self._current_app_schema()).filter(id=schedular.id).update( end=timezone.now(), message=str(excep))
            return obj

    def payroll_serv_schedular(self,request,scheduler):
        logger.info("payroll_schedular_for_manual_run")
        print('payroll_schedular')
        try:
            id = 0
            sched_create = self.payrollshedular_manualrun(id)
            self.schedular_payrollmanualrun(request)
            logger.info('payrollmanual_run finish')
            scheduler.remove_job('payroll_manual_run')
            self.payrollshedular_manualrun(int(sched_create))
            return True
        except Exception as e:
            logger.info('except error connection' + str(e))
            scheduler.remove_job('payroll_manual_run')
            self.payrollshedular_manualrun(int(sched_create))
            return True

    def payroll_ser_schedular(self):
        logger.info("payroll_schedular start")
        print('payroll_schedular start')
        id=0
        sched_create = self.payrollshedular_permonth(id)
        self.schedular_payrollmanualrun1()
        self.payrollshedular_permonth(int(sched_create))
        logger.info("payroll_schedular end")
        print('payroll_schedular end')
        return True


    def payroll_schedularmanual(self,request):
        scheduler = BackgroundScheduler()
        scheduler.add_job(self.payroll_serv_schedular, 'interval', minutes=1,id='payroll_manual_run',args=[request,scheduler])
        scheduler.start()