import random
from django.forms import IntegerField
from django.http import JsonResponse
from django.shortcuts import render, redirect
from django.views import View
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models.functions import Coalesce, Cast
from program_department.models import Program_Types
from hr_department.models import Team, Vendors
from .models import Alloted_Targets, Expenditure, Incomes, HRExpenditure, EquipmentExpenditure, TravelExpenditure, IECExpenditure, AccommodationExpenditure, MiscellaneousExpenditure, OfficeExpenditure
from country.models import States
from django.db.models import Sum, F, Value
from program_department.models import Projects
from django.db.models import FloatField, ExpressionWrapper
from django.db.models.functions import Round

# Create your views here.

class AddIncomeView(LoginRequiredMixin, View):

    def get(self, request):
        states = States.objects.all()
        program_types = Program_Types.objects.all()
        return render(request, "add-income.html", {'states' : states, 'program_types' : program_types})
    

    def post(self, request):
        try:
            income = Incomes()
            income.income_type = request.POST.get('income_type')
            income.donation_type = request.POST.get('donation_type')
            income.donor = request.POST.get('donor')
            income.email = request.POST.get('email')
            income.mobile = request.POST.get('mobile')
            income.aadhar_no = request.POST.get('aadhar_no')
            income.pan_no =  request.POST.get('pan_no')
            income.sanction_amount = request.POST.get('sanction_amount')
            income.received_amount = request.POST.get('received_amount')
            income.human_resource = request.POST.get('human_resource')
            income.camp_expenses = request.POST.get('camp_expenses')
            income.training_expenses = request.POST.get('training_expenses')
            income.equipment_expenses = request.POST.get('equipment_expenses')
            income.travel_expenses = request.POST.get('travel_expenses')
            income.material_expences = request.POST.get('material_expences')
            income.administrative_expenses = request.POST.get('administrative_expenses')
            income.accommodation_expenses = request.POST.get('accommodation_expenses')
            income.monitoring_expenses = request.POST.get('monitoring_expenses')
            income.miscellaneous_expenses = request.POST.get('miscellaneous_expenses')
            income.no_of_installments = request.POST.get('no_of_installments')
            income.mode_of_payment = request.POST.get('mode_of_payment')
            if 'proof_of_evidence' in request.FILES:
                income.proof_of_evidence = request.FILES.get('proof_of_evidence')
            income.payment_date = request.POST.get('payment_date')
            income.program_type_id = request.POST.get('program_type')
            income.project_id = request.POST.get('project')
            income.start_date = request.POST.get('start_date')
            income.end_date = request.POST.get('end_date')
            income.state_id = request.POST.get('state')
            income.district_id = request.POST.get('district')
            income.address = request.POST.get('address')
            income.message = request.POST.get('message')
            income.save()
            if income.id:
                targets = []
                target_names = request.POST.getlist('target_names')
                target_numbers = request.POST.getlist('target_numbers')
                for index, name in enumerate(target_names):
                    targets.append(
                        Alloted_Targets(income_id = income.id, target_name = name, target_number = target_numbers[index])
                    )
                if len(targets):
                    Alloted_Targets.objects.bulk_create(targets)       
                messages.success(request, "Team member registered successfully.")
                return redirect("IncomesView")
            else:
                messages.error(request, "Something went wrong. Please try again later.")
                return redirect("IncomesView")
        except Exception as e:
            print(e)
    

class EditIncomeView(LoginRequiredMixin, View):

    def get(self, request, id):
        try:
            states = States.objects.all()
            program_types = Program_Types.objects.all()
            income = Incomes.objects.get(id = id)
            return render(request, "edit-income.html", {'states' : states, 'program_types' : program_types, 'income' : income})
        except Incomes.DoesNotExist:
            messages.error(request, "Income error Something went wrong. Please try again later.")
            return redirect("IncomesView")
        

    def post(self, request, id):
        try:
            income = Incomes.objects.get(id = id)
            income.income_type = request.POST.get('income_type')
            income.donation_type = request.POST.get('donation_type')
            income.donor = request.POST.get('donor')
            income.email = request.POST.get('email')
            income.mobile = request.POST.get('mobile')
            income.aadhar_no = request.POST.get('aadhar_no')
            income.pan_no =  request.POST.get('pan_no')
            income.sanction_amount = request.POST.get('sanction_amount')
            income.received_amount = request.POST.get('received_amount')
            income.human_resource = request.POST.get('human_resource')
            income.camp_expenses = request.POST.get('camp_expenses')
            income.training_expenses = request.POST.get('training_expenses')
            income.equipment_expenses = request.POST.get('equipment_expenses')
            income.travel_expenses = request.POST.get('travel_expenses')
            income.material_expences = request.POST.get('material_expences')
            income.administrative_expenses = request.POST.get('administrative_expenses')
            income.accommodation_expenses = request.POST.get('accommodation_expenses')
            income.monitoring_expenses = request.POST.get('monitoring_expenses')
            income.miscellaneous_expenses = request.POST.get('miscellaneous_expenses')
            income.no_of_installments = request.POST.get('no_of_installments')
            income.mode_of_payment = request.POST.get('mode_of_payment')
            if 'proof_of_evidence' in request.FILES:
                income.proof_of_evidence = request.FILES.get('proof_of_evidence')
            income.payment_date = request.POST.get('payment_date')
            income.program_type_id = request.POST.get('program_type')
            income.project_id = request.POST.get('project')
            income.start_date = request.POST.get('start_date')
            income.end_date = request.POST.get('end_date')
            income.state_id = request.POST.get('state')
            income.district_id = request.POST.get('district')
            income.address = request.POST.get('address')
            income.message = request.POST.get('message')
            income.save()
            Alloted_Targets.objects.filter(income_id = id).delete()
            targets = []
            target_names = request.POST.getlist('target_names')
            target_numbers = request.POST.getlist('target_numbers')
            for index, name in enumerate(target_names):
                targets.append(
                    Alloted_Targets(income_id = income.id, target_name = name, target_number = target_numbers[index])
                )
            if len(targets):
                Alloted_Targets.objects.bulk_create(targets)       
            messages.success(request, "Team member registered successfully.")
            return redirect("IncomesView")
        except Incomes.DoesNotExist:
            messages.error(request, "Income error Something went wrong. Please try again later.")
            return redirect("IncomesView")


class IncomesView(LoginRequiredMixin, View):

    def get(self, request):
        program_types = Program_Types.objects.all()
        incomes = Incomes.objects.all()
    
        if 'income_type' in request.GET and request.GET['income_type'] != "All":
            income_type = request.GET['income_type']
            incomes = incomes.filter(income_type = request.GET['income_type'])
        else:
            income_type = 'All'


        if 'donation_type' in request.GET and request.GET['donation_type'] != "All":
            donation_type = request.GET['donation_type']
            incomes = incomes.filter(donation_type = request.GET['donation_type'])
        else:
            donation_type = 'All'


        if 'program_type' in request.GET and request.GET['program_type'] != "All":
            program_type = request.GET['program_type']
            incomes = incomes.filter(program_type_id = request.GET['program_type'])
        else:
            program_type = 'All'

        return render(request, "incomes.html", {'incomes' : incomes, 'program_types' : program_types, 'income_type' : income_type, 'program_type' : program_type, 'donation_type' : donation_type})

    
class IncomeChartView(LoginRequiredMixin, View):

    def get(self, request):
        # Get counts grouped by state as array
        income_counts = (
            Incomes.objects
            .values('income_type')
            .annotate(total_income=Sum('received_amount'))
            .order_by('income_type')
        )

        income_result = [
            {'name': item['income_type'] or 'Unknown', 'y': item['total_income']}
            for item in income_counts
        ]

        return JsonResponse({
            'income_result': income_result
        }, safe=False)
        

class IncomeView(LoginRequiredMixin, View):
    def get(self, request, id):
        try:
            income = Incomes.objects.get(id = id)
            return render(request, "income.html", {'income' : income})
        except Incomes.DoesNotExist:
            return redirect("IncomeView")
        

class AddExpenditureView(LoginRequiredMixin, View):

    def get(self, request):
        projects = Projects.objects.all()
        team_members = Team.objects.all()
        vendors = Vendors.objects.all()
        return render(request, "add-expenditure.html", {'projects' : projects, 'team_members' : team_members, 'vendors' : vendors})
    

    def post(self, request):
        expenditure = Expenditure()
        expence_date = request.POST.get('expence_date')
        expenditure.expence_date = expence_date
        expenditure.sector_of_expence = request.POST.get('sector_of_expence')
        expenditure.project_id = request.POST.get('project')
        expenditure.administrative_expense = request.POST.get('administrative_expense')
        expenditure.payment_type = request.POST.get('payment_type')
        expenditure.payment_status = request.POST.get('payment_status')
        expenditure.assets = request.POST.get('assets')
        if request.FILES.get('other_invoice'):
            expenditure.other_invoice = request.FILES.get('other_invoice')
        if request.FILES.get('other_payment_proof'):
            expenditure.other_payment_proof = request.FILES.get('other_payment_proof')
        expenditure.advance = request.POST.get('advance')
        expenditure.description = request.POST.get('description')
        expenditure.other_payment_mode = request.POST.get('other_payment_mode')
        expenditure.member_or_vendor = request.POST.get('member_or_vendor')
        expenditure.member_id = request.POST.get('team')
        expenditure.vendor_id = request.POST.get('vendor')
        expenditure.pan_no = request.POST.get('pan_no')
        expenditure.save()    

        if expenditure.id:
            hr = HRExpenditure()
            hr.expenditure_id = expenditure.id
            hr.human_resource = request.POST.get('human_resource')
            hr.hr_expence_date = request.POST.get('hr_expence_date')
            hr.hr_amount = request.POST.get('hr_amount')
            hr.hr_section = request.POST.get('hr_section')
            hr.hr_tds_deduction = request.POST.get('hr_tds_deduction') if request.POST.get('hr_tds_deduction') else 0
            hr.hr_tds_deduction_date = request.POST.get('hr_tds_deduction_date')
            hr.save()
            
            equipment = EquipmentExpenditure()
            equipment.expenditure_id = expenditure.id
            equipment.equipment_expence_date = request.POST.get('equipment_expence_date')
            equipment.equipment_amount = request.POST.get('equipment_amount')
            equipment.equipment_section = request.POST.get('equipment_section')
            equipment.equipment_supplier_name = request.POST.get('equipment_supplier_name')
            equipment.equipment_tds_deduction = request.POST.get('equipment_tds_deduction')
            equipment.equipment_tds_deduction_date = request.POST.get('equipment_tds_deduction_date')
            equipment.save()

            office = OfficeExpenditure()
            office.expenditure_id = expenditure.id
            office.office_expence_date = request.POST.get('office_expence_date')
            office.office_amount = request.POST.get('office_expence_amount')
            office.office_section = request.POST.get('office_expence_section')
            office.office_supplier_name = request.POST.get('office_expence_supplier_name')
            office.office_tds_deduction = request.POST.get('office_expence_tds_deduction')
            office.office_tds_deduction_date = request.POST.get('office_expence_tds_deduction_date')
            office.save()

            travel_expences = []
            expence_dates = request.POST.getlist('travel_expence_date')
            departures = request.POST.getlist('departure')
            arrivals = request.POST.getlist('arrival')
            mode_of_travels = request.POST.getlist('mode_of_travel')
            travel_amounts = request.POST.getlist('travel_amount')
            travel_sections = request.POST.getlist('travel_section')
            tds_deductions = request.POST.getlist('travel_tds_deduction')
            tds_deduction_dates = request.POST.getlist('travel_tds_deduction_date')

            for index, travel_date in enumerate(expence_dates):
                travel_expences.append(
                    TravelExpenditure(
                        expenditure_id = expenditure.id,
                        travel_expence_date = travel_date,
                        departure = departures[index],
                        arrival = arrivals[index],
                        mode_of_travel = mode_of_travels[index],
                        travel_amount = travel_amounts[index],
                        travel_section = travel_sections[index],
                        travel_tds_deduction = tds_deductions[index],
                        travel_tds_deduction_date = tds_deduction_dates[index]
                    )
                )
            if len(travel_expences):
                TravelExpenditure.objects.bulk_create(travel_expences)    


            iec = IECExpenditure()
            iec.expenditure_id = expenditure.id
            iec.iec_expence_date = request.POST.get('iec_expence_date')
            iec.item = request.POST.get('item')
            iec.quantity = request.POST.get('quantity')
            iec.rate = request.POST.get('rate')
            iec.iec_amount = request.POST.get('iec_amount')
            iec.iec_section = request.POST.get('iec_section')
            iec.iec_remarks = request.POST.get('iec_remarks')
            iec.iec_tds_deduction = request.POST.get('iec_tds_deduction')
            iec.iec_tds_deduction_date = request.POST.get('iec_tds_deduction_date')
            iec.save()

            accomodation = AccommodationExpenditure()
            accomodation.expenditure_id = expenditure.id
            accomodation.accommodation_expence_date = request.POST.get('accommodation_expence_date')
            accomodation.accommodation_check_in = request.POST.get('accommodation_check_in')
            accomodation.accommodation_check_out = request.POST.get('accommodation_check_out')
            accomodation.no_of_days = request.POST.get('no_of_days')
            accomodation.accommodation_amount = request.POST.get('accommodation_amount')
            accomodation.accommodation_section = request.POST.get('accommodation_section')
            accomodation.accommodation_tds_deduction = request.POST.get('accommodation_tds_deduction')
            accomodation.accommodation_tds_deduction_date = request.POST.get('accommodation_tds_deduction_date')
            accomodation.save()

            miscellaneous = MiscellaneousExpenditure()
            miscellaneous.expenditure_id = expenditure.id
            miscellaneous.miscellaneous_expence_date = request.POST.get('miscellaneous_expence_date')
            miscellaneous.miscellaneous_other = request.POST.get('miscellaneous_other')
            miscellaneous.miscellaneous_remarks = request.POST.get('miscellaneous_remarks')
            miscellaneous.miscellaneous_amount = request.POST.get('miscellaneous_amount')
            miscellaneous.miscellaneous_section = request.POST.get('miscellaneous_section')
            miscellaneous.miscellaneous_tds_deduction = request.POST.get('miscellaneous_tds_deduction')
            miscellaneous.miscellaneous_tds_deduction_date = request.POST.get('miscellaneous_tds_deduction_date')
            miscellaneous.miscellaneous_description = request.POST.get('miscellaneous_description')
            miscellaneous.save()

        messages.success(request, "Expenditure added successfully.")
        return redirect("ExpendituresView")
    

class ExpendituresView(LoginRequiredMixin, View):

    def get(self, request):
        projects = Projects.objects.all()
        expenditures = Expenditure.objects.annotate(
            travel_total_amount=Coalesce(Sum(Cast('travel__travel_amount', FloatField())), Value(0.0), output_field=FloatField()),
            travel_total_tds=Coalesce(Sum(
                Cast('travel__travel_amount', FloatField()) *
                Cast('travel__travel_tds_deduction', FloatField()) / 100.0
            ), Value(0.0), output_field=FloatField())
        ).annotate(
            total_amount=ExpressionWrapper(
                Coalesce(Cast(F('hr__hr_amount'), FloatField()), Value(0.0), output_field=FloatField()) +
                Coalesce(Cast(F('equipment__equipment_amount'), FloatField()), Value(0.0), output_field=FloatField()) +
                Coalesce(Sum(Cast('travel__travel_amount', FloatField())), Value(0.0), output_field=FloatField()) +
                Coalesce(Cast(F('iec__iec_amount'), FloatField()), Value(0.0), output_field=FloatField()) +
                Coalesce(Cast(F('accommodation__accommodation_amount'), FloatField()), Value(0.0), output_field=FloatField()) +
                Coalesce(Cast(F('miscellaneous__miscellaneous_amount'), FloatField()), Value(0.0), output_field=FloatField()) +
                Coalesce(Cast(F('office__office_amount'), FloatField()), Value(0.0), output_field=FloatField()),
                output_field=FloatField()
            ),
            total_tds=ExpressionWrapper(
                (Coalesce(Cast(F('hr__hr_amount'), FloatField()), Value(0.0), output_field=FloatField()) *
                Coalesce(Cast(F('hr__hr_tds_deduction'), FloatField()), Value(0.0), output_field=FloatField()) / 100.0) +

                (Coalesce(Cast(F('equipment__equipment_amount'), FloatField()), Value(0.0), output_field=FloatField()) *
                Coalesce(Cast(F('equipment__equipment_tds_deduction'), FloatField()), Value(0.0), output_field=FloatField()) / 100.0) +

                F('travel_total_tds') +

                (Coalesce(Cast(F('iec__iec_amount'), FloatField()), Value(0.0), output_field=FloatField()) *
                Coalesce(Cast(F('iec__iec_tds_deduction'), FloatField()), Value(0.0), output_field=FloatField()) / 100.0) +

                (Coalesce(Cast(F('accommodation__accommodation_amount'), FloatField()), Value(0.0), output_field=FloatField()) *
                Coalesce(Cast(F('accommodation__accommodation_tds_deduction'), FloatField()), Value(0.0), output_field=FloatField()) / 100.0) +

                (Coalesce(Cast(F('miscellaneous__miscellaneous_amount'), FloatField()), Value(0.0), output_field=FloatField()) *
                Coalesce(Cast(F('miscellaneous__miscellaneous_tds_deduction'), FloatField()), Value(0.0), output_field=FloatField()) / 100.0) +

                (Coalesce(Cast(F('office__office_amount'), FloatField()), Value(0.0), output_field=FloatField()) *
                Coalesce(Cast(F('office__office_tds_deduction'), FloatField()), Value(0.0), output_field=FloatField()) / 100.0),
                output_field=FloatField()
            )
        ).annotate(
            net_amount=ExpressionWrapper(
                F('total_amount') - F('advance') - F('total_tds'),
                output_field=FloatField()
            )
        )

        if 'sector_of_expence' in request.GET and request.GET['sector_of_expence'] != "All":
            sector_of_expence = request.GET['sector_of_expence']
            expenditures = expenditures.filter(sector_of_expence = request.GET['sector_of_expence'])
        else:
            sector_of_expence = 'All'

        if 'administrative_expense' in request.GET and request.GET['administrative_expense'] != "All":
            administrative_expense = request.GET['administrative_expense']
            expenditures = expenditures.filter(administrative_expense = request.GET['administrative_expense'])
        else:
            administrative_expense = 'All'

        if 'project' in request.GET and request.GET['project'] != "All":
            project = request.GET['project']
            expenditures = expenditures.filter(project_id = request.GET['project'])
        else:
            project = 'All'

        return render(request, "expenditures.html", {'expenditures' : expenditures, 'sector_of_expence' : sector_of_expence, 'administrative_expense' : administrative_expense, 'project' : project, 'projects' : projects})


class ExpenditureChartView(LoginRequiredMixin, View):

    def get(self, request):
        # Get counts grouped by state as array
        
        hr_amount = HRExpenditure.objects.all()
        equipment_amount = EquipmentExpenditure.objects.all()
        travel_amount = TravelExpenditure.objects.all()
        iec_amount = IECExpenditure.objects.all()
        accommodation_amount = AccommodationExpenditure.objects.all()
        miscellaneous_amount = MiscellaneousExpenditure.objects.all()
        office_amount = OfficeExpenditure.objects.all()

        if 'sector_of_expence' in request.GET and request.GET['sector_of_expence'] != "All":
            hr_amount = hr_amount.filter(expenditure__sector_of_expence = request.GET['sector_of_expence'])
            equipment_amount = equipment_amount.filter(expenditure__sector_of_expence = request.GET['sector_of_expence'])
            travel_amount =  travel_amount.filter(expenditure__sector_of_expence = request.GET['sector_of_expence'])
            iec_amount = iec_amount.filter(expenditure__sector_of_expence = request.GET['sector_of_expence'])
            accommodation_amount = accommodation_amount.filter(expenditure__sector_of_expence = request.GET['sector_of_expence'])
            miscellaneous_amount = miscellaneous_amount.filter(expenditure__sector_of_expence = request.GET['sector_of_expence'])
            office_amount = office_amount.filter(expenditure__sector_of_expence = request.GET['sector_of_expence'])

        if 'administrative_expense' in request.GET and request.GET['administrative_expense'] != "All":
            hr_amount = hr_amount.filter(expenditure__administrative_expense = request.GET['administrative_expense'])
            equipment_amount = equipment_amount.filter(expenditure__administrative_expense = request.GET['administrative_expense'])
            travel_amount =  travel_amount.filter(expenditure__administrative_expense = request.GET['administrative_expense'])
            iec_amount = iec_amount.filter(expenditure__administrative_expense = request.GET['administrative_expense'])
            accommodation_amount = accommodation_amount.filter(expenditure__administrative_expense = request.GET['administrative_expense'])
            miscellaneous_amount = miscellaneous_amount.filter(expenditure__administrative_expense = request.GET['administrative_expense'])
            office_amount = office_amount.filter(expenditure__administrative_expense = request.GET['administrative_expense'])

        if 'project' in request.GET and request.GET['project'] != "All":
            hr_amount = hr_amount.filter(expenditure__project_id = request.GET['project'])
            equipment_amount = equipment_amount.filter(expenditure__project_id = request.GET['project'])
            travel_amount =  travel_amount.filter(expenditure__project_id = request.GET['project'])
            iec_amount = iec_amount.filter(expenditure__project_id = request.GET['project'])
            accommodation_amount = accommodation_amount.filter(expenditure__project_id = request.GET['project'])
            miscellaneous_amount = miscellaneous_amount.filter(expenditure__project_id = request.GET['project'])
            office_amount = office_amount.filter(expenditure__project_id = request.GET['project'])
        
        hr_amount = hr_amount.aggregate(hr_amount = Sum('hr_amount'))['hr_amount'] or 0
        equipment_amount = equipment_amount.aggregate(equipment_amount = Sum('equipment_amount'))['equipment_amount'] or 0
        travel_amount = travel_amount.aggregate(travel_amount = Sum('travel_amount'))['travel_amount'] or 0
        iec_amount = iec_amount.aggregate(iec_amount = Sum('iec_amount'))['iec_amount'] or 0
        accommodation_amount = accommodation_amount.aggregate(accommodation_amount = Sum('accommodation_amount'))['accommodation_amount'] or 0
        miscellaneous_amount = miscellaneous_amount.aggregate(miscellaneous_amount = Sum('miscellaneous_amount'))['miscellaneous_amount'] or 0
        office_amount = office_amount.aggregate(office_amount = Sum('office_amount'))['office_amount'] or 0
        
        amounts = [
            {'name' : 'HR Amount', 'y': hr_amount},
            {'name' : 'Equipment Amount', 'y' : equipment_amount},
            {'name' : 'Travel Amount', 'y' : travel_amount},
            {'name' : 'IEC Amount', 'y' : iec_amount},
            {'name' : 'Accomodation Amount', 'y' : accommodation_amount},
            {'name' : 'Miscellaneous Amount', 'y' : miscellaneous_amount},
            {'name' : 'Office Amount', 'y' : office_amount},
        ]

        return JsonResponse({'amounts': amounts}, safe=False)
        

class EditExpenditureView(LoginRequiredMixin, View):

    def get(self, request, id):
        projects = Projects.objects.all()
        expenditure = Expenditure.objects.get(id = id)
        team_members = Team.objects.all()
        vendors = Vendors.objects.all()
        return render(request, "edit-expenditure.html", {'projects' : projects, 'expenditure' : expenditure, 'team_members' : team_members, 'vendors' : vendors})
    

    def post(self, request, id):
        try:
            expenditure = Expenditure.objects.get(id = id)
            expence_date = request.POST.get('expence_date')
            expenditure.expence_date = expence_date
            expenditure.sector_of_expence = request.POST.get('sector_of_expence')
            expenditure.project_id = request.POST.get('project')
            expenditure.administrative_expense = request.POST.get('administrative_expense')
            expenditure.payment_type = request.POST.get('payment_type')
            expenditure.payment_status = request.POST.get('payment_status')
            expenditure.assets = request.POST.get('assets')
            expenditure.other_payment_mode = request.POST.get('other_payment_mode')
            if request.FILES.get('other_invoice'):
                expenditure.other_invoice = request.FILES.get('other_invoice')
            if request.FILES.get('other_payment_proof'):
                expenditure.other_payment_proof = request.FILES.get('other_payment_proof')
            expenditure.advance = request.POST.get('advance')
            expenditure.description = request.POST.get('description')
            expenditure.member_or_vendor = request.POST.get('member_or_vendor')
            expenditure.member_id = request.POST.get('team')
            expenditure.vendor_id = request.POST.get('vendor')
            expenditure.pan_no = request.POST.get('pan_no')
            expenditure.save()    
            
            hr = HRExpenditure.objects.get(expenditure_id = id)
            hr.expenditure_id = expenditure.id
            hr.human_resource = request.POST.get('human_resource')
            hr.hr_expence_date = request.POST.get('hr_expence_date')
            hr.hr_amount = request.POST.get('hr_amount')
            hr.hr_section = request.POST.get('hr_section')
            hr.hr_tds_deduction = request.POST.get('hr_tds_deduction') if request.POST.get('hr_tds_deduction') else 0
            hr.hr_tds_deduction_date = request.POST.get('hr_tds_deduction_date')
            hr.save()
            
            equipment = EquipmentExpenditure.objects.get(expenditure_id = id)
            equipment.expenditure_id = expenditure.id
            equipment.equipment_expence_date = request.POST.get('equipment_expence_date')
            equipment.equipment_amount = request.POST.get('equipment_amount')
            equipment.equipment_section = request.POST.get('equipment_section')
            equipment.equipment_supplier_name = request.POST.get('equipment_supplier_name')
            equipment.equipment_tds_deduction = request.POST.get('equipment_tds_deduction')
            equipment.equipment_tds_deduction_date = request.POST.get('equipment_tds_deduction_date')
            equipment.save()

            office = OfficeExpenditure.objects.get(expenditure_id = id)
            office.expenditure_id = expenditure.id
            office.office_expence_date = request.POST.get('office_expence_date')
            office.office_amount = request.POST.get('office_expence_amount')
            office.office_section = request.POST.get('office_expence_section')
            office.office_supplier_name = request.POST.get('office_expence_supplier_name')
            office.office_tds_deduction = request.POST.get('office_expence_tds_deduction')
            office.office_tds_deduction_date = request.POST.get('office_expence_tds_deduction_date')
            office.save()

            
            TravelExpenditure.objects.filter(expenditure_id = id).delete()
            
            travel_expences = []
            expence_dates = request.POST.getlist('travel_expence_date')
            departures = request.POST.getlist('departure')
            arrivals = request.POST.getlist('arrival')
            mode_of_travels = request.POST.getlist('mode_of_travel')
            travel_amounts = request.POST.getlist('travel_amount')
            travel_sections = request.POST.getlist('travel_section')
            tds_deductions = request.POST.getlist('travel_tds_deduction')
            tds_deduction_dates = request.POST.getlist('travel_tds_deduction_date')

            for index, travel_date in enumerate(expence_dates):
                travel_expences.append(
                    TravelExpenditure(
                        expenditure_id = expenditure.id,
                        travel_expence_date = travel_date,
                        departure = departures[index],
                        arrival = arrivals[index],
                        mode_of_travel = mode_of_travels[index],
                        travel_amount = travel_amounts[index],
                        travel_section = travel_sections[index],
                        travel_tds_deduction = tds_deductions[index],
                        travel_tds_deduction_date = tds_deduction_dates[index]
                    )
                )
            if len(travel_expences):
                TravelExpenditure.objects.bulk_create(travel_expences) 

            iec = IECExpenditure.objects.get(expenditure_id = id)
            iec.expenditure_id = expenditure.id
            iec.iec_expence_date = request.POST.get('iec_expence_date')
            iec.item = request.POST.get('item')
            iec.quantity = request.POST.get('quantity')
            iec.rate = request.POST.get('rate')
            iec.iec_amount = request.POST.get('iec_amount')
            iec.iec_section = request.POST.get('iec_section')
            iec.iec_remarks = request.POST.get('iec_remarks')
            iec.iec_tds_deduction = request.POST.get('iec_tds_deduction')
            iec.iec_tds_deduction_date = request.POST.get('iec_tds_deduction_date')
            iec.save()

            accomodation = AccommodationExpenditure.objects.get(expenditure_id = id)
            accomodation.expenditure_id = expenditure.id
            accomodation.accommodation_expence_date = request.POST.get('accommodation_expence_date')
            accomodation.accommodation_check_in = request.POST.get('accommodation_check_in')
            accomodation.accommodation_check_out = request.POST.get('accommodation_check_out')
            accomodation.no_of_days = request.POST.get('no_of_days')
            accomodation.accommodation_amount = request.POST.get('accommodation_amount')
            accomodation.accommodation_section = request.POST.get('accommodation_section')
            accomodation.accommodation_tds_deduction = request.POST.get('accommodation_tds_deduction')
            accomodation.accommodation_tds_deduction_date = request.POST.get('accommodation_tds_deduction_date')
            accomodation.save()

            miscellaneous = MiscellaneousExpenditure.objects.get(expenditure_id = id)
            miscellaneous.expenditure_id = expenditure.id
            miscellaneous.miscellaneous_expence_date = request.POST.get('miscellaneous_expence_date')
            miscellaneous.miscellaneous_other = request.POST.get('miscellaneous_other')
            miscellaneous.miscellaneous_remarks = request.POST.get('miscellaneous_remarks')
            miscellaneous.miscellaneous_amount = request.POST.get('miscellaneous_amount')
            miscellaneous.miscellaneous_section = request.POST.get('miscellaneous_section')
            miscellaneous.miscellaneous_tds_deduction = request.POST.get('miscellaneous_tds_deduction')
            miscellaneous.miscellaneous_tds_deduction_date = request.POST.get('miscellaneous_tds_deduction_date')
            miscellaneous.miscellaneous_description = request.POST.get('miscellaneous_description')
            miscellaneous.save()
            messages.success(request, "Expenditure updated successfully.")
            return redirect("ExpendituresView")
        except Expenditure.DoesNotExist:
            messages.success(request, "Expenditure doesn't exists.")
            return redirect("ExpendituresView")
    

class DeleteExpenditureView(LoginRequiredMixin, View):

    def get(self, request, id):
        try:
            expenditure = Expenditure.objects.get(id = id)
            expenditure.delete()
            messages.success(request, "Expenditure deleted successfully.")
            return redirect('ExpendituresView')
        except Expenditure.DoesNotExist:
            messages.error(request, "Expenditure doesn't exists.")
            return redirect('ExpendituresView')


        
class ExpenditureView(LoginRequiredMixin, View):
    def get(self, request, id):
        try:
            expenditure = Expenditure.objects.get(id = id)
            return render(request, "expenditure.html", {'expenditure' : expenditure})
        except Expenditure.DoesNotExist:
            return redirect("ExpendituresView")
        

class DeleteIncomeView(LoginRequiredMixin, View):

    def get(self, request, id):
        try:
            income = Incomes.objects.get(id = id)
            income.delete()
            messages.success(request, "Income deleted successfully.")
            return redirect('IncomesView')
        except Incomes.DoesNotExist:
            messages.error(request, "Income doesn't exists.")
            return redirect('IncomesView')
