import datetime

import pandas as pd
from django.utils import timezone
from django.db.models import Q, Sum
from npayroll.settings import logger
from payrollservice.data.response.emppaystructdetailsresponse import EmployeePaystructure_detailsResponse
from payrollservice.data.response.emppaystructureresponse import EmployeePaystructureResponse
from payrollservice.models import EmployeePaystructure_details
from payrollservice.service.auditservice import AudtiService
from payrollservice.service.payrollmastersservice import PayrollComponentService, PaycomponentFlagmasterService, \
    CompanyContributionService, SegmentMasterService, EmployeePFService, ComponentTypeService
from payrollservice.util.payrollutil import Activestatus, Advancetype, ModifyStatus, get_pf_type, payrolldeduction_val, \
    AllowanceType, FlagRef_Type
from utilityservice.data.response.nwisefinerrorconstants import ErrorDescription, ErrorMessage
from utilityservice.data.response.nwisefinsuccess import NWisefinSuccess, SuccessStatus, SuccessMessage
from utilityservice.data.response.nwisefinerror import NWisefinError
from utilityservice.data.response.nwisefinlist import NWisefinList
from utilityservice.data.response.nwisefinpaginator import NWisefinPaginator
from utilityservice.service.applicationconstants import ApplicationNamespace
from utilityservice.service.threadlocal import NWisefinThread


class EmployeePaystructure_detailsService(NWisefinThread):
    def __init__(self, scope):
        super().__init__(scope)
        self._set_namespace(
            ApplicationNamespace.PAYROLL_SERVICE)



    def create_employeepay_structdetails(self, request, allowance_obj, user_id, data,standard_ctc, gross_pay, action):
        success_obj = NWisefinSuccess()
        success_obj.set_status(SuccessStatus.SUCCESS)
        if allowance_obj.get_company_contribution() is True or action == '1' or allowance_obj.get_type() != None:
            amount = allowance_obj.get_amount()
        else:
            amount = float(gross_pay) * float(allowance_obj.get_paycomponent_percentage()) / 100
        if allowance_obj.get_id() is not None:
            emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(id=allowance_obj.get_id()).update(
                                                                                    emp_pay_id=data,
                                                                                    paycomponent=allowance_obj.get_paycomponent(),
                                                                                    paycomponent_type=allowance_obj.get_paycomponent_type(),
                                                                                    paycomponent_percentage=allowance_obj.get_paycomponent_percentage(),
                                                                                    company_contribution=allowance_obj.get_company_contribution(),
                                                                                    type=allowance_obj.get_type(),
                                                                                    from_date=allowance_obj.get_from_date(),
                                                                                    to_date=allowance_obj.get_to_date(),
                                                                                    updated_by=user_id,
                                                                                    updated_date=timezone.now(),
                                                                                    entity_id=self._entity_id(),amount=amount,
                                                                                    segment=allowance_obj.get_segment())
            emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).get(id=allowance_obj.get_id())
            audit_insert_data = AudtiService(self._scope()).audit_function(emp_details, emp_details.id, user_id,
                                                                           Advancetype.paystructure_details,
                                                                           ModifyStatus.UPDATE)
            success_obj.set_message(SuccessMessage.UPDATE_MESSAGE)
        else:
            emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).create(emp_pay_id=data,
                                                                                    paycomponent=allowance_obj.get_paycomponent(),
                                                                                    paycomponent_type=allowance_obj.get_paycomponent_type(),
                                                                                    paycomponent_percentage=allowance_obj.get_paycomponent_percentage(),
                                                                                    company_contribution=allowance_obj.get_company_contribution(),
                                                                                    type=allowance_obj.get_type(),
                                                                                    from_date=allowance_obj.get_from_date(),
                                                                                    to_date=allowance_obj.get_to_date(),
                                                                                    created_by=user_id,
                                                                                    entity_id=self._entity_id(),amount=amount,
                                                                                    segment=allowance_obj.get_segment())
            audit_insert_data = AudtiService(self._scope()).audit_function(emp_details, emp_details.id, user_id,
                                                                           Advancetype.paystructure_details,
                                                                           ModifyStatus.CREATE)
            success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
        success_obj.id = emp_details.id
        return success_obj


    def employeepaystrct_summary(self, vys_page):
        condition=Q(entity_id=self._entity_id(),status=Activestatus.active)
        empallowance_details= EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(condition)[vys_page.get_offset():vys_page.get_query_limit()]
        empallowance_data=NWisefinList()
        paycomponent = [i.paycomponent for i in empallowance_details]
        segment_id = [i.segment for i in empallowance_details]
        # segment_dta = Payrollcommon_Apicall(self._scope()).get_segment_dta(segment_id)
        segment_dta = SegmentMasterService(self._scope()).get_multiple_segment_data(segment_id)
        # pay_com_obj = Payrollcommon_Apicall(self._scope()).get_payroll_component(paycomponent)
        pay_com_obj =  PayrollComponentService(self._scope()).get_multiple_payroll_component_val(paycomponent)
        # pay_com_obj = PayrollComponentService(self._scope()).get_multiple_payroll_component(paycomponent)
        for empallowance in empallowance_details:
            resp= EmployeePaystructure_detailsResponse()
            resp.set_id(empallowance.id)
            resp.set_paycomponent_val(empallowance.paycomponent, pay_com_obj)
            if empallowance.company_contribution == 1:
                # company_con_obj = Payrollcommon_Apicall(self._scope()).get_companycontribution_multi_data(paycomponent)
                company_con_obj = CompanyContributionService(self._scope()).get_multiple_contribution(paycomponent)
                # company_con_obj = CompanyContributionService(self._scope()).get_multiple_contribution(paycomponent)
                resp.set_company_contribution_val(empallowance.paycomponent, company_con_obj)
            resp.set_paycomponent_type(empallowance.paycomponent_type)
            resp.set_paycomponent_percentage(empallowance.paycomponent_percentage)
            resp.set_amount(empallowance.amount)
            resp.set_type(empallowance.type)
            resp.set_from_date(empallowance.from_date)
            resp.set_to_date(empallowance.to_date)
            resp.set_segment_data(empallowance.segment, segment_dta)
            empallowance_data.append(resp)
            vpage = NWisefinPaginator(empallowance_details, vys_page.get_index(), 10)
            empallowance_data.set_pagination(vpage)
        return empallowance_data


    def employee_level_detail(self, emppay_id):
        emp_obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(emp_pay_id=emppay_id,status=Activestatus.active)
        paycomponent = [i.paycomponent for i in emp_obj]
        segment_id = [i.segment for i in emp_obj]
        bonus_total = sum(i.amount for i in emp_obj if i.type != None)
        # pay_com_obj = Payrollcommon_Apicall(self._scope()).get_payroll_component(paycomponent)
        pay_com_obj = PayrollComponentService(self._scope()).get_multiple_payroll_component_val(paycomponent)
        # segment_dta = Payrollcommon_Apicall(self._scope()).get_segment_dta(segment_id)
        segment_dta = SegmentMasterService(self._scope()).get_multiple_segment_data(segment_id)
        # pay_com_obj = PayrollComponentService(self._scope()).get_multiple_payroll_component_val(paycomponent)
        company_contribution = sum([i.amount for i in emp_obj if i.company_contribution == 1])
        without_company_contribution = sum([i.amount for i in emp_obj if i.company_contribution == 0 and i.type == None])
        print(without_company_contribution)
        print(company_contribution)
        arr = []
        for i in emp_obj:
            data_resp = EmployeePaystructure_detailsResponse()
            data_resp.set_id(i.id)
            data_resp.set_amount(i.amount)
            data_resp.set_yearly_amount(i.amount)
            data_resp.set_paycomponent_val(i.paycomponent, pay_com_obj)
            if i.company_contribution == 1:
                # company_con_obj = Payrollcommon_Apicall(self._scope()).get_companycontribution_multi_data(paycomponent)
                company_con_obj = CompanyContributionService(self._scope()).get_multiple_contribution(paycomponent)
                # company_con_obj = CompanyContributionService(self._scope()).get_multiple_contribution(paycomponent)
                data_resp.set_company_contribution_val(i.paycomponent, company_con_obj)
                data_resp.set_cc_total(company_contribution)
                data_resp.set_yearly_cc_total(company_contribution)
            data_resp.set_paycomponent_type(i.paycomponent_type)
            data_resp.set_paycomponent_percentage(i.paycomponent_percentage)
            data_resp.companycontribution = (i.company_contribution)
            data_resp.set_type(i.type)
            data_resp.set_Annual_bonus_total(bonus_total)
            data_resp.set_Yearly_Annual_bonus_total(bonus_total)
            data_resp.set_total_component_amount(without_company_contribution)
            data_resp.set_yearly_total(without_company_contribution)
            data_resp.set_cc_total1(company_contribution)
            data_resp.set_yearly_cc_total1(company_contribution)
            data_resp.set_from_date(i.from_date)
            data_resp.set_to_date(i.to_date)
            data_resp.set_segment_data(i.segment, segment_dta)
            arr.append(data_resp)
        return arr

    def paystrct_detail_inactive(self, id, user_id):
        detail_data = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(id=id).update(status=Activestatus.inactive, updated_by=user_id,updated_date=timezone.now())
        if detail_data > 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

    def get_paystruct_value(self, struct_id):
        emp_obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).get(id=struct_id)
        # pay_com_obj = Payrollcommon_Apicall(self._scope()).get_payroll_component([emp_obj.paycomponent])
        pay_com_obj = PayrollComponentService(self._scope()).get_multiple_payroll_component_val([emp_obj.paycomponent])
        # pay_com_obj = PayrollComponentService(self._scope()).get_multiple_payroll_component([emp_obj.paycomponent])
        data_resp = EmployeePaystructure_detailsResponse()
        data_resp.set_id(emp_obj.id)
        data_resp.set_amount(emp_obj.amount)
        data_resp.set_emp_pay(emp_obj.emp_pay_id)
        data_resp.set_paycomponent_val(emp_obj.paycomponent, pay_com_obj)
        data_resp.set_paycomponent_type(emp_obj.paycomponent_type)
        data_resp.set_paycomponent_percentage(emp_obj.paycomponent_percentage)
        data_resp.set_type(emp_obj.type)
        data_resp.set_from_date(emp_obj.from_date)
        data_resp.set_to_date(emp_obj.to_date)
        # segment_dta = Payrollcommon_Apicall(self._scope()).single_segment_dta(emp_obj.segment)
        segment_dta = SegmentMasterService(self._scope()).get_segmentmaster(emp_obj.segment)
        data_resp.set_segment(segment_dta)
        return data_resp

    def create_emp_default_allowance(self, emp_pay_id, ctc_amt, emp_id):
        alw_type = AllowanceType()
        alw_arr = alw_type.var_arr
        create_arr = []
        # default_data = Payrollcommon_Apicall(self._scope()).get_default_components()
        default_data = PayrollComponentService(self._scope()).get_default_components()
        # mst_serv = PayrollComponentService(self._scope())
        # default_data = mst_serv.get_default_components()
        for i in alw_arr:
            amount = ctc_amt * (i['percentage'] / 100)
            emp_alw = EmployeePaystructure_details(emp_pay_id=emp_pay_id,
                                        # allowance_type=i['id'],
                                        # is_total=True,
                                        paycomponent_type=i['id'],
                                        is_deduction=False,
                                        amount=amount,
                                        created_by=emp_id,entity_id=self._entity_id())
            for data in default_data:
                if data.allowance_type == i['id']:
                    alw = EmployeePaystructure_details(emp_pay_id=emp_pay_id,
                                            # allowance=data.id,
                                            # allowance_type=i['id'],
                                            # is_total=False,
                                            paycomponent=data.id,
                                            paycomponent_type=i['id'],
                                            is_deduction=False,
                                            amount=amount,
                                            created_by=emp_id,entity_id=self._entity_id())
                    create_arr.append(alw)
            create_arr.append(emp_alw)


        EmployeePaystructure_details.objects.using(self._current_app_schema()).bulk_create(create_arr)
        resp = NWisefinSuccess()
        resp.set_status(SuccessStatus.SUCCESS)
        resp.set_message(SuccessMessage.UPDATE_MESSAGE)
        return resp

    def employee_sancturaies_pf_calculation(self, employee_id):
        obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(
            emp_pay__employee_id=employee_id)
        amount = [i.amount for i in obj]
        sum_amount = sum(amount)
        paycomponent_data = [i.paycomponent for i in obj]
        # pf_data_calculation = Payrollcommon_Apicall(self._scope()).component_data(paycomponent_data)
        pf_data_calculation = PaycomponentFlagmasterService(self._scope()).get_component_values(paycomponent_data)
        # pf_data_calculation = PaycomponentFlagmasterService(self._scope()).get_component_values(paycomponent_data)
        list_data = NWisefinList()
        for i in pf_data_calculation:
            percentage = i.paycomponent_data.percentage
            amount = float(i.paycomponent_data.amount)
            pay_struct_det_per = float(percentage)
            data_resp = EmployeePaystructureResponse()
            if i.paycomponent_data.name == 'Employee PF':
                data = data_resp.amount = int(sum_amount) * pay_struct_det_per / 100
                data_resp.pfstructure = i.paycomponent_data.name
                # data_resp.paycomponent = i.ref_id.name
                if amount <= data:
                    data_resp.amount = amount
                else:
                    data_resp.amount = data
            elif i.paycomponent_data.name == 'ESI std':
                data = data_resp.amount = int(sum_amount) * pay_struct_det_per / 100
                data_resp.pfstructure = i.paycomponent_data.name
                # data_resp.paycomponent = i.ref_id.name
                if amount <= data:
                    data_resp.amount = amount
                else:
                    data_resp.amount = data
            list_data.append(data_resp)
        return list_data


    def employee_deduction_calculation(self, employee_id, paycomponent_id):
        list_data = NWisefinList()
        # pf_data_calculation = Payrollcommon_Apicall(self._scope()).paycomponent_data(paycomponent_id)
        pf_data_calculation = PaycomponentFlagmasterService(self._scope()).get_paycomponent_data(paycomponent_id)
        # pf_data_calculation = PaycomponentFlagmasterService(self._scope()).get_paycomponent_data(paycomponent_id)
        emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(
            paycomponent__in=pf_data_calculation['paycomponent'], emp_pay__employee_id=employee_id, company_contribution=False, status=Activestatus.active)
        amount = [i.amount for i in emp_details]
        sum_amount = sum(amount)
        esi_cal_amt = pf_data_calculation['sal_amount']
        pf_data_calculation_values = float(pf_data_calculation['pfstructure_percentage'])
        final_calculation = float(sum_amount) * pf_data_calculation_values / 100
        if esi_cal_amt < sum_amount and pf_data_calculation['structure_name'] == 'ESI':
            amount = '0.0'
        elif esi_cal_amt > sum_amount:
            amount = round(final_calculation)
        elif final_calculation == '0.0':
            amount = round(final_calculation)
        elif final_calculation >= pf_data_calculation['amount']:
            amount = round(pf_data_calculation['amount'])
        else:
            amount = round(final_calculation)
        list_data.append(amount)
        return list_data


    def company_contribution_calculation(self, paycomponent_id, employee_id):
       list_data = NWisefinList()
       # pf_data_calculation = Payrollcommon_Apicall(self._scope()).get_company_contribution_data(paycomponent_id)
       pf_data_calculation = PaycomponentFlagmasterService(self._scope()).get_companycontri_data(paycomponent_id)
       # pf_data_calculation = PaycomponentFlagmasterService(self._scope()).get_companycontri_data(paycomponent_id)
       emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(paycomponent__in=pf_data_calculation['paycomponent'], emp_pay__employee_id=employee_id, status=Activestatus.active,company_contribution=False)
       company_contribution_amount = pf_data_calculation['company_contribution_amount']
       amount = [i.amount for i in emp_details]
       sum_amount = sum(amount)
       sal_amount = pf_data_calculation['sal_amount']
       company_contribution_per=float(pf_data_calculation['company_contribution_percentage'])
       total_calculation=float(sum_amount) * company_contribution_per / 100
       if sal_amount < sum_amount and pf_data_calculation['contribution_structure_name'] == 'ESI':
           round_of_amount = '0.0'
       elif company_contribution_amount > total_calculation:
           round_of_amount = round(total_calculation)
       else:
           round_of_amount = round(company_contribution_amount)
       list_data.append(round_of_amount)
       return list_data


    def employee_paystucture_details(self,employee_id,arr):
        obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, emp_pay__employee_id__in=employee_id,company_contribution=False).values('emp_pay__employee_id','paycomponent','amount','type','from_date','to_date')
        return obj

    def employee_paystucture_details1(self,employee_id,arr):
        obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, emp_pay__employee_id__in=employee_id,company_contribution=False).values('emp_pay__employee_id','emp_pay__take_home','paycomponent','amount','type','from_date','to_date')
        return obj

    def emp_structure_info_withcb(self,emp_list):
        struct_query = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active,emp_pay__employee_id__in=emp_list).values('paycomponent', 'company_contribution', 'amount', 'type','emp_pay__employee_id','emp_pay__gross_pay')
        return struct_query

    def struct_detail_excel_upload(self, details_data, user_id,data,gross_pay):
        success_obj = NWisefinSuccess()
        success_obj.set_status(SuccessStatus.SUCCESS)
        if details_data['COMPANY_CONTRIBUTION'] == 1 or details_data['TYPE'] != None:
            values = details_data['AMOUNT']
        else:
            amount = float(gross_pay) * float(details_data['PAYCOMPONENT_PERCENTAGE']) / 100
            values = (round(amount,2))
        if details_data['COMPANY_CONTRIBUTION'] == 1:
            # paycomponent = Payrollcommon_Apicall(self._scope()).company_contribution_values(details_data['PAYCOMPONENT'])
            paycomponent = CompanyContributionService(self._scope()).company_contribution_val(details_data['PAYCOMPONENT'])
        else:
            # paycomponent = Payrollcommon_Apicall(self._scope()).get_payrollcomponent_val(details_data['PAYCOMPONENT'])
            paycomponent = PayrollComponentService(self._scope()).get_payrollcomponent_val(details_data['PAYCOMPONENT'])
        # paycomponent_type = Payrollcommon_Apicall(self._scope()).get_componenttype_name(details_data['PAYCOMPONENT_TYPE'])
        paycomponent_type = ComponentTypeService(self._scope()).get_componenttype_name(details_data['PAYCOMPONENT_TYPE'])
        emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).create(emp_pay_id=data,
                                                                                                    paycomponent=paycomponent,
                                                                                                    paycomponent_type=paycomponent_type,
                                                                                                    paycomponent_percentage=details_data['PAYCOMPONENT_PERCENTAGE'],
                                                                                                    company_contribution=details_data['COMPANY_CONTRIBUTION'],
                                                                                                    type=details_data['TYPE'],
                                                                                                    created_by=user_id,
                                                                                                    entity_id=self._entity_id(),
                                                                                                    amount=values)
                                                                                                    # from_date=details_data['FROM_DATE'],
                                                                                                    # to_date=details_data['TO_DATE'])

        success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
        success_obj.id = emp_details.id
        return success_obj

    def create_employeepay_structdetails1(self, request, allowance_obj, user_id,struct_id,take_home,employee_id):
        success_obj = NWisefinSuccess()
        success_obj.set_status(SuccessStatus.SUCCESS)
        # if allowance_obj.get_company_contribution() is True or allowance_obj.get_type() != None:
        #     amount = allowance_obj.get_amount()
        # else:
        #     amount = float(take_home) * float(allowance_obj.get_paycomponent_percentage()) / 100
        if allowance_obj.get_details_id() is not None:
            emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(id=allowance_obj.get_details_id()).update(
                                                                                    emp_pay_id=struct_id,
                                                                                    paycomponent=allowance_obj.get_paycomponent(),
                                                                                    paycomponent_type=allowance_obj.get_paycomponent_type(),
                                                                                    paycomponent_percentage=allowance_obj.get_paycomponent_percentage(),
                                                                                    company_contribution=allowance_obj.get_company_contribution(),
                                                                                    type=allowance_obj.get_type(),
                                                                                    from_date=allowance_obj.get_from_date(),
                                                                                    to_date=allowance_obj.get_to_date(),
                                                                                    updated_by=user_id,
                                                                                    updated_date=timezone.now(),
                                                                                    entity_id=self._entity_id(),amount=allowance_obj.get_amount(),
                                                                                    segment=allowance_obj.get_segment(),
                                                                                    segment_percentage=allowance_obj.get_segment_percentage())
            emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).get(id=allowance_obj.get_details_id())
            audit_insert_data = AudtiService(self._scope()).audit_function(emp_details, emp_details.id, user_id,
                                                                           Advancetype.paystructure_details,
                                                                           ModifyStatus.UPDATE)
            success_obj.set_message(SuccessMessage.UPDATE_MESSAGE)
        else:
            emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).create(emp_pay_id=struct_id,
                                                                                    paycomponent=allowance_obj.get_paycomponent(),
                                                                                    paycomponent_type=allowance_obj.get_paycomponent_type(),
                                                                                    paycomponent_percentage=allowance_obj.get_paycomponent_percentage(),
                                                                                    company_contribution=allowance_obj.get_company_contribution(),
                                                                                    type=allowance_obj.get_type(),
                                                                                    from_date=allowance_obj.get_from_date(),
                                                                                    to_date=allowance_obj.get_to_date(),
                                                                                    created_by=user_id,
                                                                                    entity_id=self._entity_id(),amount=allowance_obj.get_amount(),
                                                                                    segment=allowance_obj.get_segment(),
                                                                                    segment_percentage=allowance_obj.get_segment_percentage())
            audit_insert_data = AudtiService(self._scope()).audit_function(emp_details, emp_details.id, user_id,
                                                                           Advancetype.paystructure_details,
                                                                           ModifyStatus.CREATE)
            success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
        success_obj.id = emp_details.id
        return success_obj


    def struct_detail_excel_upload1(self, details_data, user_id,data,gross_pay,employee_id,pf_type,is_esi):
        try:
            success_obj = NWisefinSuccess()
            success_obj.set_status(SuccessStatus.SUCCESS)
            # if details_data['TYPE'] != None:
                # values = details_data['AMOUNT']
            # else:
                # amount = float(gross_pay) * float(details_data['PAYCOMPONENT_PERCENTAGE']) / 100
            # values = (round(amount,2))
            # segment_id = Payrollcommon_Apicall(self._scope()).get_segment_name(details_data['SEGMENT'])
            logger.info("upload EmployeePaystructure_details data" + str(details_data))
            segment_id = SegmentMasterService(self._scope()).get_segment_name(details_data['SEGMENT'])
            # paycomponent = Payrollcommon_Apicall(self._scope()).get_payrollcomponent_val(details_data['PAYCOMPONENT'])
            paycomponent = PayrollComponentService(self._scope()).get_payrollcomponent_val(details_data['PAYCOMPONENT'])
            # paycomponent_type = Payrollcommon_Apicall(self._scope()).get_componenttype_name(details_data['PAYCOMPONENT_TYPE'])
            paycomponent_type = ComponentTypeService(self._scope()).get_componenttype_name(details_data['PAYCOMPONENT_TYPE'])
            emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).create(emp_pay_id=data,
                                                                                                        paycomponent=paycomponent,
                                                                                                        paycomponent_type=paycomponent_type,
                                                                                                        paycomponent_percentage=details_data['PAYCOMPONENT_PERCENTAGE'],
                                                                                                        company_contribution=details_data['COMPANY_CONTRIBUTION'],
                                                                                                        type=details_data['TYPE'],
                                                                                                        created_by=user_id,
                                                                                                        entity_id=self._entity_id(),
                                                                                                        amount=details_data['AMOUNT'],
                                                                                                        from_date=details_data['FROM_DATE'],
                                                                                                        to_date=details_data['TO_DATE'],
                                                                                                        segment=segment_id,
                                                                                                        segment_percentage=details_data['SEGMENT_PERCENTAGE'])
            logger.info("upload EmployeePaystructure_details id" + str(emp_details.id))
            success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
            success_obj.id = emp_details.id
            return success_obj
        except Exception as excep:
            obj = NWisefinError()
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(str(excep))
            return obj

    def cc_struct_detail_excel_upload(self,user_id, data, employee_id, pf_type,is_esi):
        try:
            logger.info("upload EmployeePaystructure_details company contribution calcultion start (employee_id)" + str(employee_id))
            from django.db.models import Sum
            success_obj = NWisefinSuccess()
            success_obj.set_status(SuccessStatus.SUCCESS)
            data1 = ['PF', 'ESI']
            for i in data1:
                logger.info("condition for loop finish if condition start is_esi == (1 or 0) or get_pf_type(pf_type)['name'] == ('NORMAL_PF' or 'STANDARD_PF' or 'VIRTUAL_PF') (employee_id)" + str(employee_id))
                if is_esi == (1 or 0) or get_pf_type(pf_type)['name'] == ('NORMAL_PF' or 'STANDARD_PF' or 'VIRTUAL_PF'):
                    from django.db.models import Sum
                    # paycomponent = Payrollcommon_Apicall(self._scope()).company_contribution_values(i)
                    paycomponent = CompanyContributionService(self._scope()).company_contribution_val(i)
                    # 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 == (1 or 0):
                        # 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)
                        print(flag_master)
                        sum_amt = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, paycomponent__in=flag_master, emp_pay__employee_id=employee_id, 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 == 0:
                                    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'])
                else:
                    amount = 0.00

                emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).create(emp_pay_id=data,
                                                                                                            paycomponent=paycomponent,
                                                                                                            paycomponent_type=1,
                                                                                                            paycomponent_percentage=pf['percentage'],
                                                                                                            company_contribution=1,
                                                                                                            created_by=user_id,
                                                                                                            entity_id=self._entity_id(),
                                                                                                            amount=amount)

            success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
            success_obj.id = emp_details.id
            logger.info("upload EmployeePaystructure_details company contribution calcultion end (employee_id)" + str(employee_id))
            logger.info("upload EmployeePaystructure_details company contribution calcultion end (strcuture_id--emp_pay_id)" + str(data))
            return success_obj
        except Exception as excep:
            obj = NWisefinError()
            obj.set_code(ErrorMessage.INVALID_DATA)
            obj.set_description(str(excep))
            return obj


        # data1 = ['PF','ESI']
        # for i in data1:
        #     if pf1 == 1 and i == 'PF' or esi1 == 1 and i == 'ESI':
        #         paycomponent = Payrollcommon_Apicall(self._scope()).company_contribution_values(i)
        #         pf = Payrollcommon_Apicall(self._scope()).company_contribution_data(paycomponent)[0]
        #         flag_master = Payrollcommon_Apicall(self._scope()).cc_epf_based_paycom(pf['id'],FlagRef_Type.COMPANYCONTRIBUTION)
        #         print(flag_master)
        #         sum_amt = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(status=Activestatus.active, paycomponent__in=flag_master, emp_pay__employee_id=employee_id,company_contribution=False).aggregate(Sum('amount'))
        #         logger.info("------COMPANY CONTRIBUTION SUM_AMT--------" + str(sum_amt))
        #         if sum_amt['amount__sum'] != None:
        #             if pf['name'] == 'ESI':
        #                 if float(sum_amt['amount__sum']) <= 21000:
        #                     sum_prec = float(sum_amt['amount__sum']) * float(pf['percentage']) / 100
        #                     values = sum_prec
        #                 else:
        #                     values = 0.00
        #             else:
        #                 sum_prec = float(sum_amt['amount__sum']) * float(pf['percentage']) / 100
        #                 values = sum_prec
        #         else:
        #             values = 0.00
        #     else:
        #         paycomponent = Payrollcommon_Apicall(self._scope()).company_contribution_values(i)
        #         pf = Payrollcommon_Apicall(self._scope()).company_contribution_data(paycomponent)[0]
        #         values = 0.00

            # emp_details = EmployeePaystructure_details.objects.using(self._current_app_schema()).create(emp_pay_id=data,
            #                                                                                             paycomponent=paycomponent,
            #                                                                                             paycomponent_type=1,
            #                                                                                             paycomponent_percentage=pf['percentage'],
            #                                                                                             company_contribution=1,
            #                                                                                             created_by=user_id,
            #                                                                                             entity_id=self._entity_id(),
            #                                                                                             amount=values)


        # success_obj.set_message(SuccessMessage.CREATE_MESSAGE)
        # success_obj.id = emp_details.id
        # return success_obj


    #
    # # segment based
    # def employee_structure_get(self, emppay_id):
    #     emp_obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(emp_pay_id=emppay_id,status=Activestatus.active)
    #     paycomponent = [i.paycomponent for i in emp_obj]
    #     segment_id = [i.segment for i in emp_obj]
    #     pay_com_obj = Payrollcommon_Apicall(self._scope()).get_payroll_component(paycomponent)
    #     segment_data = Payrollcommon_Apicall(self._scope()).get_segment_dta(segment_id)
    #     arr, arr1, arr2 = [], [],[]
    #     for seg_data in segment_data:
    #         data_resp1 = EmployeePaystructure_detailsResponse()
    #         data_resp1.set_segment_data(seg_data.id, segment_data)
    #         for i in emp_obj:
    #             if seg_data.id == i.segment:
    #                 if i.company_contribution == 0:
    #                     data_resp = EmployeePaystructure_detailsResponse()
    #                     data_resp.set_id(i.id)
    #                     data_resp.set_amount(i.amount)
    #                     data_resp.set_paycomponent_val(i.paycomponent, pay_com_obj)
    #                     data_resp.set_paycomponent_type(i.paycomponent_type)
    #                     data_resp.set_paycomponent_percentage(i.paycomponent_percentage)
    #                     data_resp.set_type(i.type)
    #                     data_resp.set_from_date(i.from_date)
    #                     data_resp.set_to_date(i.to_date)
    #             # data_resp.set_segment_data(i.segment, segment_data)
    #                     arr.append(data_resp)
    #                 arr2.append(data_resp1.segment)
    #             if i.company_contribution == 1:
    #                 company_con_obj = Payrollcommon_Apicall(self._scope()).get_companycontribution_multi_data(paycomponent)
    #                 # company_con_obj = CompanyContributionService(self._scope()).get_multiple_contribution(paycomponent)
    #                 data_resp1.set_company_contribution_val(i.paycomponent, company_con_obj)
    #                 arr1.append(data_resp1)
    #             final_data = {"company_contribution":arr1, "segment_details":arr2, "paycomponent": arr}
    #     return final_data

    def company_contribution_data(self, id_data):
        obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(emp_pay=id_data,
                                                                                            company_contribution=True)
        paycomponent_id = [i.paycomponent for i in obj]
        # paycomponent_dta = Payrollcommon_Apicall(self._scope()).company_contribution_data_get(paycomponent_id)
        paycomponent_dta = CompanyContributionService(self._scope()).company_contribution_data_get(paycomponent_id)
        data = self.set_company_contribution_values(paycomponent_id, paycomponent_dta, obj)
        return data

    def set_company_contribution_values(self, company_contribution, arr, obj):
        arr_dta = []
        for i in arr:
            for j in company_contribution:
                if i.id == j:
                    data = {"id": j, "company_contribution": True, "name": i.name,
                            "max_amount": i.amount, "percentage": i.percentage,"sal_amount": i.sal_amount}
                    arr_dta.append(data)
                    for k in obj:
                        for j in arr_dta:
                            if k.paycomponent == j['id']:
                                j.__setitem__("details_id", k.id)
                                j.__setitem__("details_amount", str(k.amount))
                        continue
        return arr_dta

    def without_cmpny_contribution(self, id_data):
        obj = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(emp_pay_id=id_data,
                                                                                            status=Activestatus.active,
                                                                                            company_contribution=False)
        segment_id = [i.segment for i in obj]
        if obj:
            pay_df = pd.DataFrame(obj.values('segment', 'segment_percentage'))
            pay_df['segment_percentage'] = pay_df['segment_percentage'].astype(str)
            pay_df = pay_df.drop_duplicates(subset=['segment', 'segment_percentage'], keep='first')
            # pay_obj = pay_df.set_index(pay_df['segment'])['segment_percentage'].to_dict()
            unique_segment_info = dict(zip(pay_df["segment"], pay_df["segment_percentage"]))
        else:
            unique_segment_info = {}

        segment_id = list(set(segment_id))
        # segment_data = SegmentMasterService(self._scope()).get_segment_info(segment_id)
        # mapped_segment_info = {segment_data[k]: str(v) for k, v in unique_segment_info.items()}
        segment_id.sort()
        arr = []
        for i in segment_id:
            pf_arr = []
            obj_data = EmployeePaystructure_details.objects.using(self._current_app_schema()).filter(emp_pay_id=id_data,
                                                                                                     segment=i,
                                                                                                     status=Activestatus.active,
                                                                                                     company_contribution=False)
            emp_pf_data = EmployeePFService(self._scope()).get_employeepfstruct_details()
            for k in obj_data:
                # emp_pf_data = Payrollcommon_Apicall(self._scope()).get_employee_pf_data()
                # values = Payrollcommon_Apicall(self._scope()).paycomponent_details_dta(k.paycomponent)
                values = PayrollComponentService(self._scope()).paycomponent_details_data(k.paycomponent)
                arr_dta = []
                for emp_pf in emp_pf_data:
                    pf_component = emp_pf.paycomponent
                    for pf_component_dta in pf_component:
                        if pf_component_dta == k.paycomponent:
                            emp_pf_name = emp_pf.name
                            arr_dta.append(emp_pf_name)
                pay_com_data = {'paycomponent': values['paycomponent'], "details_id": k.id,
                                "amount": str(k.amount), "paycomponent_percentage": str(k.paycomponent_percentage),
                                'paycomponent_name': values['paycomponent_name'], 'type':payrolldeduction_val(k.type)['id'],
                                 'paycom': arr_dta}
                pf_arr.append(pay_com_data)
            # segment_data = Payrollcommon_Apicall(self._scope()).segment_data_for_get(i, pf_arr)
            segment_data = SegmentMasterService(self._scope()).segment_for_structure_get(i, pf_arr,unique_segment_info)
            # segment_data['per_emp_segments'] = mapped_segment_info
            arr.append(segment_data)
            # for j in arr:
            #     fin_arr = []
            #     for n in j['paycomponent_data']:
            #         for m in obj_data:
            #             if n['paycomponent'] == m.paycomponent:
            #                 n.__setitem__("details_id", m.id)
            #                 n.__setitem__("amount", str(m.amount))
            #                 n.__setitem__("company_contribution", False)
            #                 n.__setitem__("paycomponent_percentage", str(m.paycomponent_percentage))
            #                 fin_arr.append(n)
        return arr

        #     paycomponent_id = [i.paycomponent for i in obj_data]
        #     emp_pf_data = Payrollcommon_Apicall(self._scope()).get_employee_pf_data()
        #     paycomponent_data = Payrollcommon_Apicall(self._scope()).paystruct_details_data_val(paycomponent_id)
        #     for pf_data in emp_pf_data:
        #         for j in pf_data.paycomponent:
        #             for k in paycomponent_data:
        #                 if j == k.paycomponent:
        #                     emp_pf_name = pf_data.name
        #                     pay_com_data = {'paycomponent': k.paycomponent, 'paycomponent_name': k.paycomponent_name,
        #                                     'paycomponent_percentage': k.paycomponent_percentage,
        #                                     'paycom': [emp_pf_name]}
        #                     pf_arr.append(pay_com_data)
        #     segment_data = Payrollcommon_Apicall(self._scope()).segment_data_for_get(i, pf_arr)
        #     arr.append(segment_data)
        #     for j in arr:
        #         fin_arr = []
        #         for n in j['paycomponent_data']:
        #             for m in obj_data:
        #                 if n['paycomponent'] == m.paycomponent:
        #                     n.__setitem__("details_id", m.id)
        #                     n.__setitem__("amount", str(m.amount))
        #                     n.__setitem__("company_contribution", False)
        #                     n.__setitem__("paycomponent_percentage", str(m.paycomponent_percentage))
        #                     fin_arr.append(n)
        # return arr

