from appservices.common.util import *
from appservices.common.payment_gateways.wowpe_payment_gateways import *
# from appservices.common.payment_gateways.fstac_payment_gateways import *
# from appservices.common.payment_gateways.payaid_payment_gateways import *
from appservices.common.payment_gateways.accurepay_payment_gateways import *
from appservices.common.payment_gateways.payu_payment_gateways import *
from appservices.common.payment_gateways.lyra_payment_gateway import *
from appservices.common.payment_gateways.getepay_payment_gateway import *
from appservices.common.payment_gateways.axis_payment_gateways import *
from appservices.common.payment_gateways.worldline_payment_gateway import *
from appservices.v1.controllers.payout_apis import *
from flask import render_template_string
from xhtml2pdf import pisa
from appservices.common.form_schemas import *


admin_reports = Blueprint("admin_reports",__name__)





@admin_reports.route("/settlement_ledger_reports",methods=["POST","GET"])
@adminid_access_token_required
def settlement_ledger_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        reportsList = []

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")
        merchantMail = request.form.get("merchantMail","")
        paymentId = request.form.get("paymentId","")

        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/settlement_ledger_reports_list.html",
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            merchantMail=merchantMail,
            paymentId=paymentId,
            reportsList=reportsList
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched pending user data!!"
        return render_template("super_admin_templates/settlement_ledger_reports_list.html", 
            error=error,
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            merchantMail=merchantMail,
            paymentId=paymentId,
            reportsList=reportsList
            )


@admin_reports.route("/payout_ledger_reports",methods=["POST","GET"])
@adminid_access_token_required
def payout_ledger_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    permissionsList = check_permissions(session.get("adminId"),"payoutLedgerReportPermissions")
    if "view" in permissionsList:
        pagination=""
        payoutsList=[]
        transactionUniqueId=""
        merchantsList=[]
        merchantId=""
        orderId=""
        pgList=[]
        pgId=""
        searchId=""
        siteTitleList=[]
        siteTitle =""
        snoCount=0
        form=PayoutLedgerSearchForm(request.args)
        try:
            adminId = session.get("adminId")
            payoutsList = []
            merchantsList = []
            pgList = []

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            orderId = request.args.get("orderId","")
            searchId=request.args.get("searchId","")
            transactionUniqueId = request.args.get("transactionUniqueId","")
            merchantId = request.args.get("merchantId","")
            pgId = request.args.get("pgId","")
            siteTitle = request.args.get("siteTitle","")
            transactionType = request.args.get("transactionType","")

            # Set default date format
            date_format = "%d-%m-%Y"
            transactionTypeCheck=["Credit","Refund"]
            pagination = None
            siteTitleList  = []
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            if form.validate():
                

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0

                snoCount = start

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                # for each_merchant in merchants_queryset:
                #     merchantDict = fetching_user_details(each_merchant)
                #     merchantsList.append(merchantDict)
                merchantsList = list(merchants_queryset)

                pg_queryset = TransactionAPI.objects(transactionType="Payout",status__in=[0,1]).only("id","apiName" ).order_by("-id")
                # for each_pg in pg_queryset:
                #     pgDict = fetching_transaction_api_details(each_pg)
                #     pgList.append(pgDict)
                pgList = list(pg_queryset)

                multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).order_by("-id").all()
                # for each_multiple_app_sites in multiple_app_sites_queryset:
                #     multiple_app_sites_dict = fetching_multiple_app_sites(each_multiple_app_sites)
                #     siteTitleList.append(multiple_app_sites_dict)
                siteTitleList =  list(multiple_app_sites_queryset)

                # fund_transfer_queryset = FundTransfers.objects(status__in=[0,1,2,3,4,5],createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()

                # if orderId:
                #   fund_transfer_queryset = fund_transfer_queryset.filter(merchantReferenceNumber=orderId)

                if transactionType == "All":
                    transactionTypeCheck=["Credit","Debit","Refund"]
                elif transactionType == "Debit":
                    transactionTypeCheck=["Debit"]

                query=Q()
                if searchId:
                    # payouts_queryset =  FundTransfers.objects(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId)).order_by("-createdOn").all()
                    query &= (Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId))

                else:
                    # payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,
                    # transferType__in=transactionTypeCheck).order_by("-createdOn").all()
                    query = Q(createdOn__gte=startDate,createdOn__lte=endDate,transferType__in=transactionTypeCheck)
                    if merchantId:
                        # payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])
                        query &= Q(userId__in=[merchantId])

                    if pgId:
                        # payouts_queryset = payouts_queryset.filter(transactionAPIId__in=[pgId])
                        query &= Q(transactionAPIId__in=[pgId])

                    if siteTitle:
                        user_ids = Users.objects(siteTitle__icontains=siteTitle).values_list('id')
                        # payouts_queryset = payouts_queryset.filter(userId__in=user_ids)
                        query &= Q(userId__in=user_ids)

                total_count = FundTransfers.objects(query).count()

                payouts_queryset = FundTransfers.objects(query).order_by("-createdOn").limit(per_page).skip(start)

                
                for each_payout in payouts_queryset:
                    # snoCount +=1
                    payoutDict = fetching_payouts_details(each_payout)
                    # payoutDict["snoCount"]=snoCount
                    payoutsList.append(payoutDict)

                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")
            else:
                print("form errors",form.errors)
            return render_template("super_admin_templates/payout_ledger_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                pagination=pagination,
                payoutsList=payoutsList,
                transactionUniqueId=transactionUniqueId,
                merchantsList=merchantsList,
                transactionType=transactionType,
                merchantId=merchantId,
                orderId=orderId,
                pgId=pgId,
                pgList=pgList,
                searchId=searchId,
                siteTitleList=siteTitleList,
                siteTitle = siteTitle,
                snoCount=snoCount,
                form=form
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched payout ledger report data!!"
            return render_template("super_admin_templates/payout_ledger_reports_list.html", 
                error=error,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                pagination=pagination,
                payoutsList=payoutsList,
                transactionUniqueId=transactionUniqueId,
                merchantsList=merchantsList,
                merchantId=merchantId,
                orderId=orderId,
                pgList=pgList,
                pgId=pgId,
                searchId=searchId,
                siteTitleList=siteTitleList,
                siteTitle = siteTitle,
                snoCount=snoCount,
                form=form
                )
    else:
        flash("The staff member does not have permission to view Payout ledger reports.", "danger")
        return render_template("super_admin_templates/payout_ledger_reports_list.html")




@admin_reports.route("/payin_ledger_reports",methods=["POST","GET"])
@adminid_access_token_required
def payin_ledger_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    permissionsList = check_permissions(session.get("adminId"),"payinLedgerReportPermissions")
    if "view" in permissionsList:
        pagination=None
        pgOrderId=""
        merchantsList=[]
        merchantId=""
        pgId=""
        pgList=[]
        searchId=""
        siteTitleList=[]
        siteTitle =""
        payinList = []
        form=PayinLedgerSearchForm(request.args)
        try:
            adminId = session.get("adminId")
            merchantsList = []

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            pgOrderId = request.args.get("pgOrderId","")
            merchantId = request.args.get("merchantId","")
            searchId=request.args.get("searchId","")
            pgId=request.args.get("pgId","")
            siteTitle = request.args.get("siteTitle","")

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            pgList = []
            siteTitleList = []
            snoCount=0

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                merchantsList=list(merchants_queryset)

                pg_queryset = TransactionAPI.objects(transactionType="PaymentGateway",status__in=[0,1]).only("id","apiName" ).order_by("-id")
                pgList = list(pg_queryset)
                
                multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).order_by("-id").all()
                siteTitleList =  list(multiple_app_sites_queryset)

                query=Q(status__in=[1,2,4,5])

                if searchId:
                    # payin_ledger_reports = payin_ledger_reports.filter(Q(orderId__icontains=searchId) | Q(pgOrderId__icontains=searchId))
                    query=Q(orderId__icontains=searchId) | Q(pgOrderId__icontains=searchId)
                else:
                    query&=Q(createdOn__gte=startDate,createdOn__lte=endDate)
                    if siteTitle:
                        user_ids = Users.objects(siteTitle__icontains=siteTitle).only('id').values_list('id')
                        # payin_ledger_reports = payin_ledger_reports.filter(userId__in=user_ids)
                        query &= Q(userId__in=user_ids)
                    if merchantId:
                        # payin_ledger_reports = payin_ledger_reports.filter(userId__in=[merchantId])
                        query &= Q(userId__in=[merchantId])
                    if pgId:
                        # payin_ledger_reports = payin_ledger_reports.filter(paymentGatewayId__in=[pgId])
                        query &= Q(paymentGatewayId__in=[pgId])

                total_count = WalletTransactions.objects(query).count()

                payin_queryset = WalletTransactions.objects(query).order_by("-createdOn").limit(per_page).skip(start)
                    

                for each_payin in payin_queryset:
                    # snoCount +=1
                    payinDict = fetching_payin_details(each_payin)
                    # payinDict["snoCount"]=snoCount
                    payinList.append(payinDict)

                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payins")
            else:
                print("form errors",form.errors)
            return render_template("super_admin_templates/payin_ledger_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                payinList=payinList,
                pagination=pagination,
                pgOrderId=pgOrderId,
                searchId=searchId,
                merchantsList=merchantsList,
                merchantId=merchantId,
                pgId=pgId,
                pgList=pgList,
                siteTitleList=siteTitleList,
                snoCount=snoCount,
                siteTitle = siteTitle,
                form=form
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched payin ledger report data!!"
            return render_template("super_admin_templates/payin_ledger_reports_list.html", 
                error=error,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                payinList=payinList,
                pagination=pagination,
                pgOrderId=pgOrderId,
                merchantsList=merchantsList,
                merchantId=merchantId,
                pgId=pgId,
                pgList=pgList,
                searchId=searchId,
                siteTitleList=siteTitleList,
                siteTitle = siteTitle,
                form=form
                )
    else:
        flash("The staff member does not have permission to view Payin ledger reports", "danger")
        return render_template("super_admin_templates/payin_ledger_reports_list.html")

@admin_reports.route("/auto_collect_ledger_reports",methods=["POST","GET"])
@adminid_access_token_required
def auto_collect_ledger_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    form=PayoutLedgerSearchForm(request.args)
    snoCount=0
    siteTitleList=[]
    payoutsList=[]
    siteTitle =""
    orderId=""
    pagination=None
    total_count = 0

    permissionsList = check_permissions(session.get("adminId"),"autocollectLedgerReportPermissions")
    form=AutoCollectLedgerSearchForm(request.args)
    if "view" in permissionsList:
        try:
            payoutsList = []
            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            orderId = request.args.get("orderId","")

            # Set default date format
            date_format = "%d-%m-%Y"

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0

                snoCount = start
                query=Q(transferType="Credit",)
                # fund_transfer_queryset = FundTransfers.objects(transferType="Credit",createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()

                if orderId:
                    # fund_transfer_queryset = fund_transfer_queryset.filter(merchantReferenceNumber=orderId)
                    query=Q(merchantReferenceNumber=orderId)
                else:
                    query=Q(createdOn__gte=startDate,createdOn__lte=endDate)

                total_count = FundTransfers.objects(query).count()
                fund_transfer_queryset = FundTransfers.objects(query).order_by("-createdOn").limit(per_page).skip(start)

                snoCount = start

                for each_payout in fund_transfer_queryset:
                    # snoCount +=1
                    payoutDict = fetching_payouts_details(each_payout)
                    # payoutDict["snoCount"]=snoCount
                    payoutsList.append(payoutDict)

                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="auto_collect_ledger")
            else:
                print("form errors",form.errors)
            return render_template("super_admin_templates/autocollect_ledger_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                payoutsList=payoutsList,
                pagination=pagination,
                orderId=orderId,
                snoCount=snoCount,
                form=form
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched auto collect ledger data!!"
            return render_template("super_admin_templates/autocollect_ledger_reports_list.html", 
                error=error,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                payoutsList=payoutsList,
                pagination=pagination,
                orderId=orderId,
                snoCount=snoCount,
                form=form
                )
    else:
        flash("The staff member does not have permission to view Auto collect ledger reports.", "danger")
        return render_template("super_admin_templates/autocollect_ledger_reports_list.html")



@admin_reports.route("/live_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def live_transaction_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        search_element = request.form.get("search_element","")

        payoutsList = []

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")


        payouts_queryset = FundTransfers.objects(status__in=[0,1,2]).order_by("-createdOn").all()
        for each_payout in payouts_queryset:
            payoutDict = fetching_payouts_details(each_payout)
            payoutsList.append(payoutDict)


        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/live_transaction_reports_list.html",
            pagination=pagination,
            payoutsList=payoutsList,
            search_element=search_element
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched pending user data!!"
        return render_template("super_admin_templates/live_transaction_reports_list.html", 
            error=error,
            pagination=pagination,
            payoutsList=payoutsList,
            search_element=search_element
            )

@admin_reports.route("/disputes_reports",methods=["POST","GET"])
@adminid_access_token_required
def disputes_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        search_element = request.form.get("search_element","")

        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/disputes_reports_list.html",
            pagination=pagination,
            search_element=search_element
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched pending user data!!"
        return render_template("super_admin_templates/disputes_reports_list.html", 
            error=error,
            pagination=pagination,
            search_element=search_element
            )

######################################## OLD FUNCTIONALITY ###################################################### 
# @admin_reports.route("/reconciliation_reports",methods=["POST","GET"])
# def reconciliation_reports():
#     if not session.get("adminId"):
#         return redirect("admin_login")

#     reconciliationDict = {
#         "payinSuccessAmount":0,
#         "payinProccessingAmount":0,
#         "payinDebitAmount":0,
#         "payoutSuccessAmount" :0,
#         "payoutProcessingAmount":0,
#         "payoutDebitAmount":0,
#         }

#     permissionsList = check_permissions(session.get("adminId"),"reconcilationTransactionReportPermissions")
#     if "view" in permissionsList:
#         try:
#             adminId = session.get("adminId")

#             startDate = request.form.get("startDate","S")
#             endDate = request.form.get("endDate","A")
#             merchantId = request.form.get("merchantId","")
            
#             date_format = "%d-%m-%Y"

#             merchantsList = []

#             print(startDate,endDate,"START DATE AND END DATE")

#             merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
#             for each_merchant in merchants_queryset:
#                 merchantDict = fetching_user_details(each_merchant)
#                 merchantsList.append(merchantDict)

#             if request.method == "GET":
                
#                 return render_template("super_admin_templates/reconciliation_reports_list.html",merchantsList=merchantsList,reconciliationDict=reconciliationDict)

#             if request.method == "POST":
#                 try:
#                     if startDate:
#                         startDate = datetime.datetime.strptime(startDate, date_format)
#                         startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
#                     else:
#                         startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

#                     if endDate:
#                         endDate = datetime.datetime.strptime(endDate, date_format)
#                         endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
#                     else:
#                         endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
#                 except Exception as ve:
#                     app.logger.error("Date parsing error: %s", ve)
#                     startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
#                     endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

#                 print(startDate,endDate,"IN POST")

#                 payinSuccessAmount = 0
#                 payinProccessingAmount = 0
#                 payinDebitAmount = 0

#                 payoutSuccessAmount = 0
#                 payoutProcessingAmount = 0
#                 payoutDebitAmount = 0

#                 payins_queryset = WalletTransactions.objects(userId=merchantId,createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn")
#                 payinSuccessAmount = payins_queryset.filter(status=1,userType="user",creditType="Credit").sum("amount")
#                 payinProccessingAmount = payins_queryset.filter(status=2,userType="user",creditType="Credit").sum("amount")
#                 payinDebitAmount = payins_queryset.filter(status=1,userType="admin",creditType="Debit").sum("amount")

#                 payouts_queryset = FundTransfers.objects(userId=merchantId,createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn")
#                 payoutSuccessAmount = payouts_queryset.filter(status=1,userType__nin=["admin"],transferType="Debit").sum("amount")
#                 payoutProcessingAmount = payouts_queryset.filter(status=2,userType__nin=["admin"],transferType="Debit").sum("amount")
#                 payoutDebitAmount = payouts_queryset.filter(status=1,userType="admin",transferType="Credit").sum("amount")
                
#                 reconciliationDict = {
#                 "payinSuccessAmount":formatINR("{:.2f}".format(float(payinSuccessAmount))),
#                 "payinProccessingAmount":formatINR("{:.2f}".format(float(payinProccessingAmount))),
#                 "payinDebitAmount":formatINR("{:.2f}".format(float(payinDebitAmount))),
#                 "payoutSuccessAmount":formatINR("{:.2f}".format(float(payoutSuccessAmount))),
#                 "payoutProcessingAmount":formatINR("{:.2f}".format(float(payoutProcessingAmount))),
#                 "payoutDebitAmount":formatINR("{:.2f}".format(float(payoutDebitAmount)))
#                 }
#                 return render_template("super_admin_templates/reconciliation_reports_list.html",
#                     startDate=startDate.strftime(date_format),
#                     endDate=endDate.strftime(date_format),
#                     reconciliationDict=reconciliationDict,
#                     merchantsList=merchantsList,
#                     merchantId=merchantId
#                 )
#         except Exception as e:
#             app.logger.error(traceback.format_exc())
#             error = "Unable to fetched reconciliation reports data!!"
#             return render_template("super_admin_templates/reconciliation_reports_list.html", 
#                 error=error,
#                 startDate=startDate.strftime(date_format),
#                 endDate=endDate.strftime(date_format),
#                 merchantsList=merchantsList,
#                 reconciliationDict=reconciliationDict,
#                 merchantId=merchantId
#                 )
#     else:
#         flash("Staff member does not have given view reconciliation reports permissions!!")
#         return render_template("super_admin_templates/reconciliation_reports_list.html",reconciliationDict=reconciliationDict)

@admin_reports.route("/update_fundtransfer_status",methods=["POST","GET"])
@adminid_access_token_required
def update_fundtransfer_status():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId=session.get("adminId")
    
    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    client_ip=0
    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"): 
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    actionDate=datetime.datetime.now()

    jsonData = request.form.to_dict(flat=True)

    requestData = [jsonData]
    updatedrequestData = [jsonData]

    data_status={'status':'Failed','result':"failed"}
    merchant_reference_number = request.form.get("merchant_reference_number","")
    if request.headers.getlist("X-Forwarded-For"):
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    if not merchant_reference_number:
        data_status['result']="Please retry again!"
        return data_status

    try:
        order_queryset = FundTransfers.objects(merchantReferenceNumber=merchant_reference_number).first()
        if not order_queryset:
            data_status["result"]="Invalid order id!!"
            return data_status

        message = ""
        get_fundtransfer_status = get_fundtransfer_payment_status(merchant_reference_number,str(order_queryset.userId.id),client_ip)
        admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
        if get_fundtransfer_status.get("error"):
            data_status["status"]= "Failed"
            data_status["result"]=get_fundtransfer_status.get("error")
            message=admin_queryset.userName+" "+order_queryset.userId.fullName+" Failed"
        elif get_fundtransfer_status.get("status") == "SUCCESS":
            data_status["status"]=get_fundtransfer_status.get("status")
            data_status["result"]=get_fundtransfer_status.get("status")
            message=admin_queryset.userName+" "+order_queryset.userId.fullName+" SUCCESS"
        elif get_fundtransfer_status.get("status") == "PROCESSING":
            data_status["status"]=get_fundtransfer_status.get("status")
            data_status["result"]=get_fundtransfer_status.get("status")
            message=admin_queryset.userName+" "+order_queryset.userId.fullName+" PROCESSING"
        else:
            data_status["status"]=get_fundtransfer_status.get("status")
            data_status["errorMessage"]=get_fundtransfer_status.get("error_message")
        save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_fundtransfer_status","updatestatus",actionDate,client_ip,browser,message,requestData,updatedrequestData)
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status['result']="Please retry again!"
        return data_status


@admin_reports.route("/payout_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def payout_transaction_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        permissionsList = check_permissions(session.get("adminId"),"payoutTransactionReportPermissions")
        if "view" in permissionsList:
            payoutsList = []

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            selectStatus = request.args.get("selectStatus","")
            orderId = request.args.get("orderId","")
            merchantName = request.args.get("merchantName","")
            merchantId = request.args.get("merchantId","")
            status = []
            merchantsList = []

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
            for each_merchant in merchants_queryset:
                merchantDict = fetching_user_details(each_merchant)
                merchantsList.append(merchantDict)

            if selectStatus == "All" or selectStatus == "":
                status = [0,1,2]
            elif selectStatus == "Success":
                status = [1]
            elif selectStatus == "Processing":
                status = [2]
            else:
                status = [0]

            payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status).order_by("-createdOn").all()

            if merchantName:
                merchantIds = []
                merchants_queryset = Users.objects(fullName__icontains=merchantName)
                merchantIds = [str(each_merchant.id) for each_merchant in merchants_queryset]

                payouts_queryset = payouts_queryset.filter(userId__in=merchantIds)

            if orderId:
                payouts_queryset = payouts_queryset.filter(merchantReferenceNumber__icontains=orderId)

            if merchantId:
                payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])
            
            # Get the current page from the query parameters
            page = request.args.get(get_page_parameter(), type=int, default=1)

            per_page = 20  # Number of items per page

            # Query the database for the current page's data
            total_count = payouts_queryset.count()

            start = (page - 1) * per_page

            end = min(start + per_page, total_count)

            total_payouts = payouts_queryset[start:end]
            
            snoCount = start
            for each_payout in total_payouts:
                snoCount +=1
                payoutDict = fetching_payouts_details(each_payout)
                payoutDict["snoCount"]=snoCount
                payoutsList.append(payoutDict)

            # Pagination object for rendering pagination controls in the template
            pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")

            return render_template("super_admin_templates/payout_transaction_reports_list.html",
                pagination=pagination,
                payoutsList=payoutsList,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                selectStatus=selectStatus,
                orderId=orderId,
                merchantId=merchantId,
                merchantsList=merchantsList,
                merchantName=merchantName
                )
        else:
            flash("Staff member does not have given view payout transactions report permissions!!")
            return render_template("super_admin_templates/payout_transaction_reports_list.html")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched payout transaction data!!"
        return render_template("super_admin_templates/payout_transaction_reports_list.html", 
            error=error,
            pagination=pagination,
            payoutsList=payoutsList,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            selectStatus=selectStatus,
            orderId=orderId,
            merchantId=merchantId,
            merchantsList=merchantsList,
            merchantName=merchantName
            )

@admin_reports.route("/admin_download_payout_transactions_csv_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_payout_transactions_csv_reports():
    data_status={"responseStatus":0,"result":""}
    startDate = request.args.get("startDate","")
    endDate = request.args.get("endDate","")
    selectStatus = request.args.get("selectStatus","")
    orderId = request.args.get("orderId","")
    merchantId = request.args.get("merchantId","")

    try:
        status = []
        # Set default date format
        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
       
        if selectStatus == "All" or selectStatus == "":
            status = [0,1,2,3,4,5]
        elif selectStatus == "Success":
            status = [1]
        elif selectStatus == "Processing":
            status = [2]
        else:
            status = [0]

        payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status).order_by("-createdOn").all()

        if orderId:
            payouts_queryset = payouts_queryset.filter(merchantReferenceNumber__icontains=orderId)

        if merchantId:
            payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])

        reportData = admin_download_payout_csv_reports_data(startDate,endDate,payouts_queryset)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download payout transactions report data!!"
        return data_status

@admin_reports.route("/update_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def update_transaction_reports():
    pagination = None
    payoutsList = []
    total_credit_amount = 0.0
    total_failed_amount = 0.0
    processing_amount=0.0
    overall_credit_amount = 0.0
    overall_debit_amount = 0.0
    refund_amount=0.0
    total_debit_sucess_amount=0.0
    pgList=[]
    selectStatus=""
    merchantName=""
    merchantRefNo= ""
    merchantsList=[]
    merchantId=""
    pgId=""
    orderId=""
    searchId=""
    siteTitleList=[]
    siteTitle = ""
    startDate = datetime.datetime.now()
    endDate = datetime.datetime.now()
    date_format = "%d-%m-%Y"
    form=PayoutSearchForm(request.args)
    status = []
    merchantsList = []
    pgList = []
    transactionTypeCheck=["Credit","Debit","Refund"]
    snoCount=0
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        permissionsList = check_permissions(session.get("adminId"),"allTransactionsPermissions")
        if "view" in permissionsList:
            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            selectStatus = request.args.get("selectStatus","")
            merchantRefNo = request.args.get("merchantRefNo","")
            orderId = request.args.get("orderId","")
            searchId=request.args.get("searchId","")
            merchantName = request.args.get("merchantName","")
            merchantId = request.args.get("merchantId","")
            pgId = request.args.get("pgId","")
            transactionType = request.args.get("transactionType","")
            siteTitle = request.args.get("siteTitle","")

            # Set default date format
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            
            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                for each_merchant in merchants_queryset:
                    # merchantDict = fetching_user_details(each_merchant)
                    merchantDict = {
                        "id": each_merchant.id,
                        "fullName": each_merchant.fullName,
                        "phoneNumber": each_merchant.phoneNumber
                    }
                    merchantsList.append(merchantDict)
                
                pg_queryset = TransactionAPI.objects(transactionType="Payout",status__in=[0,1]).only("id","apiName" ).order_by("-id")
                for each_pg in pg_queryset:
                    # pgDict = fetching_transaction_api_details(each_pg)
                    pgDict = {
                        "id": each_pg.id,
                        "apiName": each_pg.apiName
                    }
                    pgList.append(pgDict)

                if selectStatus == "All" or selectStatus == "":
                    status = [0,1,2,4,5]
                elif selectStatus == "Success":
                    status = [1]
                elif selectStatus == "Processing":
                    status = [2]
                elif selectStatus == "Reversal":
                    status = [4]
                elif selectStatus == "Refund":
                    status = [5]
                else:
                    status = [0]

                if transactionType == "Credit":
                    transactionTypeCheck=["Credit","Refund"]
                elif transactionType == "Debit":
                    transactionTypeCheck=["Debit"]

               

                # if orderId:
                #     payouts_queryset = payouts_queryset.filter(transactionUniqueId__icontains=orderId)
                #     query &= Q(transactionUniqueId__icontains=orderId)
                query=Q()
                if searchId:
                    # payouts_queryset =  FundTransfers.objects(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId)).order_by("-createdOn").all()
                    query &= (Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId))

                else:
                    query = Q(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status,transferType__in=transactionTypeCheck)
                    if merchantId:
                        # payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])
                        query &= Q(userId__in=[merchantId])

                    if pgId:
                        # payouts_queryset = payouts_queryset.filter(transactionAPIId__in=[pgId])
                        query &= Q(transactionAPIId__in=[pgId])
                
                if siteTitle:
                    user_ids = Users.objects(siteTitle__icontains=siteTitle).only("id").values_list('id')
                    # payouts_queryset = payouts_queryset.filter(userId__in=user_ids)
                    query &= Q(userId__in=user_ids)
                total_count = FundTransfers.objects(query).count()
                start_time = datetime.datetime.now()
                payouts_queryset = FundTransfers.objects(query).order_by("-createdOn").limit(per_page).skip(start)
                end_time = datetime.datetime.now()
                
                print("Query Time:", (end_time - start_time).total_seconds(), "seconds")

                # Get the current page from the query parameters
                # end = min(start + per_page, total_count)

                # total_payouts = payouts_queryset[start:end]
                
                # snoCount = start
                # total_credit_amount = round(total_payouts.filter(transferType="Credit", status=1).sum("amount") or 0.0,2)
                # total_debit_sucess_amount = round(total_payouts.filter(transferType="Debit", status=1).sum("amount") or 0.0,2)
                # total_failed_amount = round(total_payouts.filter(transferType="Debit",status=0).sum("amount",) or 0.0,2)
                # processing_amount = round(total_payouts.filter(transferType="Debit",status=2).sum("amount") or 0.0,2)
                # refund_amount = round(total_payouts.filter(transferType="Refund").sum("amount") or 0.0,2)

                for payout in payouts_queryset:
                    if payout.transferType == "Credit" and payout.status == 1:
                        total_credit_amount += payout.amount
                    elif payout.transferType == "Debit" and payout.status == 1:
                        total_debit_sucess_amount += payout.amount
                    elif payout.transferType == "Debit" and payout.status == 0:
                        total_failed_amount += payout.amount
                    elif payout.transferType == "Debit" and payout.status == 2:
                        processing_amount += payout.amount
                    elif payout.transferType == "Refund":
                        refund_amount += payout.amount

                total_credit_amount = round(total_credit_amount, 2)
                total_debit_sucess_amount = round(total_debit_sucess_amount, 2)
                total_failed_amount = round(total_failed_amount, 2)
                processing_amount = round(processing_amount, 2)
                refund_amount = round(refund_amount, 2)

                multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).only('siteTitle', 'siteCode').order_by("-id").all()
                siteTitleList =  list(multiple_app_sites_queryset)
                
                for each_payout in payouts_queryset:
                    # snoCount +=1
                    payoutDict = fetching_payouts_details(each_payout)
                    # payoutDict["snoCount"]=snoCount
                    payoutsList.append(payoutDict)
                
                overall_payouts_queryset = FundTransfers.objects().only("transferType","amount")
                overall_credit_amount = round(overall_payouts_queryset.filter(transferType="Credit",status=1).sum("amount") or 0.0,2)
                overall_debit_amount = round(overall_payouts_queryset.filter(transferType="Debit",status__in=[1,2]).sum("amount") or 0.0,2)

                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")
            else:
                print("form errors",form.errors)
            # Pagination object for rendering pagination controls in the template
            

            return render_template("super_admin_templates/update_transaction_reports_list.html",
                pagination=pagination,
                pgList=pgList,
                payoutsList=payoutsList,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                selectStatus=selectStatus,
                merchantName=merchantName,
                merchantRefNo=merchantRefNo,
                merchantsList=merchantsList,
                merchantId=merchantId,
                orderId=orderId,
                searchId=searchId,
                transactionType=transactionType,
                pgId=pgId,
                totalCreditAmount=total_credit_amount,
                totalDebitAmount=total_failed_amount,
                overAllCrediAmount=overall_credit_amount,
                overAllDebitAmount=overall_debit_amount,
                processingAmount=processing_amount,
                refundAmount=refund_amount,
                totalDebitSucessAmount=total_debit_sucess_amount,
                siteTitleList=siteTitleList,
                siteTitle = siteTitle,
                form=form,
                snoCount=snoCount
                )
        else:
            flash("The staff member does not have permission to view All transactions.", "danger")
            return redirect(url_for("admin.dashboard"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched all transaction reports data!!"
        return render_template("super_admin_templates/update_transaction_reports_list.html", 
            error=error,
            pagination=pagination,
            payoutsList=payoutsList,
            pgList=pgList,
            selectStatus=selectStatus,
            merchantName=merchantName,
            merchantRefNo=merchantRefNo,
            merchantsList=merchantsList,
            merchantId=merchantId,
            pgId=pgId,
            orderId=orderId,
            searchId=searchId,
            siteTitleList=siteTitleList,
            siteTitle = siteTitle,
            form=form,
            snoCount=snoCount
            )

@admin_reports.route("/admin_download_all_transactions_csv_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_all_transactions_csv_reports():
    data_status={"responseStatus":0,"result":""}
    startDate = request.args.get("startDate","")
    endDate = request.args.get("endDate","")
    selectStatus = request.args.get("selectStatus","")
    merchantRefNo = request.args.get("merchantRefNo","")
    orderId = request.args.get("orderId","")
    merchantName = request.args.get("merchantName","")
    merchantId = request.args.get("merchantId","")

    try:
        status = []
        # Set default date format
        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
       
        if selectStatus == "All" or selectStatus == "":
            status = [0,1,2]
        elif selectStatus == "Success":
            status = [1]
        elif selectStatus == "Processing":
            status = [2]
        else:
            status = [0]

        payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status).order_by("-createdOn").all()

        if merchantRefNo:
            payouts_queryset = payouts_queryset.filter(merchantReferenceNumber__icontains=merchantRefNo)

        if orderId:
            payouts_queryset = payouts_queryset.filter(transactionUniqueId__icontains=orderId)

        if merchantId:
            payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])

        reportData = admin_download_payout_csv_reports_data(startDate,endDate,payouts_queryset)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download payout report data!!"
        return data_status


@admin_reports.route("/success_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def success_transaction_reports():
    payoutsList=[]
    pagination=None
    merchantName=""
    orderId=''
    searchId=''
    merchantId=''
    merchantsList=[]
    merchantRefNo=""
    siteTitleList=[]
    pgId=""
    pgList = []
    siteTitle = ""
    transactionTypeCheck=["Credit","Debit","Refund"]
    form=PayoutSuccessSearchForm(request.args)
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        permissionsList = check_permissions(session.get("adminId"),"successTransactionsPermissions")
        if "view" in permissionsList:
            payoutsList = []
            merchantsList = []
            total_credit_amount = 0.0
            total_debit_amount = 0.0
            overall_credit_amount = 0.0
            overall_debit_amount = 0.0
            processing_amount = 0.0
            refund_amount = 0.0
            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            merchantRefNo = request.args.get("merchantRefNo","")
            merchantName = request.args.get("merchantName","")
            orderId = request.args.get("orderId","")
            searchId=request.args.get("searchId","")
            merchantId = request.args.get("merchantId","")
            pgId = request.args.get("pgId","")
            transactionType = request.args.get("transactionType","")
            siteTitle = request.args.get("siteTitle","")
            siteTitleList = []
            snoCount = 0

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            if form.validate():
                
                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0
            
                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                for each_merchant in merchants_queryset:
                    # merchantDict = fetching_user_details(each_merchant)
                    merchantDict = {
                        "id": each_merchant.id,
                        "fullName": each_merchant.fullName,
                        "phoneNumber": each_merchant.phoneNumber
                    }
                    merchantsList.append(merchantDict)
                pg_queryset = TransactionAPI.objects(transactionType="Payout",status__in=[0,1]).only("id","apiName" ).order_by("-id")
                for each_pg in pg_queryset:
                    # pgDict = fetching_transaction_api_details(each_pg)
                    pgDict = {
                        "id": each_pg.id,
                        "apiName": each_pg.apiName
                    }
                    pgList.append(pgDict)

                if transactionType == "Credit":
                    transactionTypeCheck=["Credit","Refund"]
                elif transactionType == "Debit":
                    transactionTypeCheck=["Debit"]

                if searchId:
                    query=Q()
                    # payouts_queryset =  FundTransfers.objects(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId),status=1).order_by("-createdOn").all()
                    query &= (Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId))

                else:
                    query = Q(createdOn__gte=startDate,createdOn__lte=endDate,transferType__in=transactionTypeCheck)
                    # payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,status=1).order_by("-createdOn").all()
                    if merchantId:
                        # payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])
                        query &= Q(userId__in=[merchantId])
                    if pgId:
                        # payouts_queryset = payouts_queryset.filter(transactionAPIId__in=[pgId])
                        query &= Q(transactionAPIId__in=[pgId])
                    if siteTitle:
                        user_ids = Users.objects(siteTitle__icontains=siteTitle).only("id").values_list('id')
                    # payouts_queryset = payouts_queryset.filter(userId__in=user_ids)
                        query &= Q(userId__in=user_ids)
            
                total_count = FundTransfers.objects(query).count()
                payouts_queryset = FundTransfers.objects(query).order_by("-createdOn").limit(per_page).skip(start)


                for payout in payouts_queryset:
                    if payout.transferType == "Credit" and payout.status == 1:
                        total_credit_amount += payout.amount
                    elif payout.transferType == "Debit":
                        total_debit_amount += payout.amount
                    elif payout.transferType == "Debit" and payout.status == 2:
                        processing_amount += payout.amount
                    elif payout.transferType == "Refund":
                        refund_amount += payout.amount

                # total_credit_amount = round(payouts_queryset.filter(transferType="Credit",status=1).sum("amount") or 0.0,2)
                # total_debit_amount = round(payouts_queryset.filter(transferType="Debit").sum("amount") or 0.0,2)
                # processing_amount = round(payouts_queryset.filter(transferType="Debit",status=2).sum("amount") or 0.0,2)
                # refund_amount = round(payouts_queryset.filter(transferType="Refund",).sum("amount") or 0.0,2)
                total_credit_amount = round(total_credit_amount)
                total_debit_amount = round(total_debit_amount)
                processing_amount = round(processing_amount)
                refund_amount = round(refund_amount)


                for each_payout in payouts_queryset:
                    # if each_payout.transferType == "Credit":
                    #     total_credit_amount += each_payout.amount
                    # elif each_payout.transferType == "Debit":
                    #     total_debit_amount += each_payout.amount
                    # snoCount +=1
                    payoutDict = fetching_payouts_details(each_payout)
                    # payoutDict["snoCount"]=snoCount
                    payoutsList.append(payoutDict)

                multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).only('siteTitle', 'siteCode').order_by("-id").all()
                siteTitleList =  list(multiple_app_sites_queryset)
                # for each_multiple_app_sites in multiple_app_sites_queryset:
                #     multiple_app_sites_dict = fetching_multiple_app_sites(each_multiple_app_sites)
                #     siteTitleList.append(multiple_app_sites_dict)
                
                # overall_payouts_queryset = FundTransfers.objects(status="Success")
                overall_credit_amount =round(payouts_queryset.filter(transferType="Credit").sum("amount") or 0.0,2)
                overall_debit_amount =round(payouts_queryset.filter(transferType="Debit").sum("amount") or 0.0,2)

                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="success_payouts")

            else:
                print("form errors",form.errors)

            return render_template("super_admin_templates/success_transaction_reports_list.html",
                pagination=pagination,
                payoutsList=payoutsList,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                merchantName=merchantName,
                orderId=orderId,
                searchId=searchId,
                merchantId=merchantId,
                merchantsList=merchantsList,
                pgList=pgList,
                merchantRefNo=merchantRefNo,
                transactionType=transactionType,
                totalCreditAmount=total_credit_amount,
                totalDebitAmount=total_debit_amount,
                refundAmount=refund_amount,
                processingAmount=processing_amount,
                overAllCreditAmount=overall_credit_amount,
                overAllDebitAmount=overall_debit_amount,
                siteTitleList = siteTitleList,
                siteTitle = siteTitle,
                pgId=pgId,
                snoCount=snoCount,
                form=form
                
                )
        else:
            flash("The staff member does not have permission to view Success transactions.", "danger")
            return redirect(url_for("admin.dashboard"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched success transaction reports data!!"
        return render_template("super_admin_templates/success_transaction_reports_list.html", 
            error=error,
            payoutsList=payoutsList,
            pagination=pagination,
            merchantName=merchantName,
            pgList=pgList,
            orderId=orderId,
            searchId=searchId,
            merchantId=merchantId,
            merchantsList=merchantsList,
            merchantRefNo=merchantRefNo,
            siteTitleList = siteTitleList,
            pgId=pgId,
            form=form,
            siteTitle = siteTitle,
            snoCount=snoCount,
            )


@admin_reports.route("/admin_download_payout_success_transactions_csv_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_payout_success_transactions_csv_reports():
    data_status={"responseStatus":0,"result":""}

    startDate = request.args.get("startDate","")
    endDate = request.args.get("endDate","")
    merchantRefNo = request.args.get("merchantRefNo","")
    orderId = request.args.get("orderId","")
    merchantId = request.args.get("merchantId","")

    try:
        # Set default date format
        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
       
        payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,status=1).order_by("-createdOn").all()

        if merchantRefNo:
            payouts_queryset = payouts_queryset.filter(merchantReferenceNumber__icontains=merchantRefNo)

        if orderId:
            payouts_queryset = payouts_queryset.filter(transactionUniqueId__icontains=orderId)

        if merchantId:
            payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])

        reportData = admin_download_payout_csv_reports_data(startDate,endDate,payouts_queryset)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download success payout report data!!"
        return data_status

@admin_reports.route("/pending_payout_transactions", methods=["POST", "GET"])
@adminid_access_token_required
def pending_payout_transactions():
    pendingPayoutsList=[]
    pagination=None
    merchantName=""
    selectStatus=""
    orderId=''
    searchId=''
    merchantId=''
    pgId=''
    merchantsList=[]
    merchantRefNo=""
    siteTitleList=[]
    pgList = []
    siteTitle = ""
    snoCount=0
    form=PayoutPendingSearchForm(request.args)
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        permissionsList = check_permissions(session.get("adminId"),"pendingTransactionsPermissions")
        if "view" in permissionsList:

            startDate = request.args.get("startDate", "")
            endDate = request.args.get("endDate", "")
            selectStatus = request.args.get("selectStatus", "")
            orderId = request.args.get("orderId", "")
            searchId=request.args.get("searchId","")
            merchantName = request.args.get("merchantName", "")
            merchantId = request.args.get("merchantId", "")
            pgId = request.args.get("pgId","")
            siteTitle =  request.args.get("siteTitle", "")
            siteTitleList = []

            status = []
            pendingPayoutsList = []
            merchantsList = []
            pgList = []
            total_pending_amount = 0.0
            overall_credit_amount = 0.0
            overall_debit_amount = 0.0
            total_debit_amount=0.0

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            snoCount=0

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                for each_merchant in merchants_queryset:
                    # merchantDict = fetching_user_details(each_merchant)
                    merchantDict = {
                        "id": each_merchant.id,
                        "fullName": each_merchant.fullName,
                        "phoneNumber": each_merchant.phoneNumber
                    }
                    merchantsList.append(merchantDict)

                pg_queryset = TransactionAPI.objects(transactionType="Payout",status__in=[0,1]).only("id","apiName" ).order_by("-id")
                for each_pg in pg_queryset:
                    # pgDict = fetching_transaction_api_details(each_pg)
                    pgDict = {
                        "id": each_pg.id,
                        "apiName": each_pg.apiName
                    }
                    pgList.append(pgDict)

                if selectStatus == "All" or selectStatus =="":
                    status = [0, 2]
                elif selectStatus == "Processing":
                    status = [2]
                else:
                    status = [0]


                query = Q(status__in=status)
                if searchId:
                    # payouts_queryset =  FundTransfers.objects(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId),status__in=status).order_by("-createdOn").all()

                    query &= (Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId) & Q(status__in=status)) 

                else:
                    query = Q(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status)
                    # payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status).order_by("-createdOn").all()
                    if merchantId:
                        # payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])
                        query &= Q(userId__in=[merchantId])

                    if pgId:
                        # payouts_queryset = payouts_queryset.filter(transactionAPIId__in=[pgId])
                        query &= Q(transactionAPIId__in=[pgId])

                    if siteTitle:
                        user_ids = Users.objects(siteTitle__icontains=siteTitle).only("id").values_list('id')
                        # payouts_queryset = payouts_queryset.filter(userId__in=user_ids)
                        query &= Q(userId__in=user_ids)
                

                total_count = FundTransfers.objects(query).count()
                payouts_queryset = FundTransfers.objects(query).order_by("-createdOn").limit(per_page).skip(start)

                total_debit_amount = round(payouts_queryset.filter(transferType="Debit").sum("amount",) or 0.0,2)

                for each_payout in payouts_queryset:
                    # snoCount +=1
                    payoutDict = fetching_payouts_details(each_payout)
                    # payoutDict["snoCount"]=snoCount
                    pendingPayoutsList.append(payoutDict)
                
                multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).order_by("-id").all()
                siteTitleList =  list(multiple_app_sites_queryset)

                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")
            else:
                print("form errors", form.errors)

            return render_template("super_admin_templates/pending_payout_transactions.html",
                                   pagination=pagination,
                                   pendingPayoutsList=pendingPayoutsList,
                                   pgList=pgList,
                                   selectStatus=selectStatus,
                                   orderId=orderId,
                                   searchId=searchId,
                                   merchantId=merchantId,
                                   pgId=pgId,
                                   merchantsList=merchantsList,
                                   startDate=startDate.strftime(date_format),
                                   endDate=endDate.strftime(date_format),
                                   merchantName=merchantName,
                                   totalPendingAmount=total_debit_amount,
                                   siteTitleList=siteTitleList,
                                   siteTitle=siteTitle,
                                   snoCount=snoCount,
                                   form=form
                                   )
        else:
            flash("The staff member does not have permissions to view Pending payout transactions.")
            return redirect(url_for("admin.dashboard"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched payout pending transaction data!!"
        return render_template("super_admin_templates/pending_payout_transactions.html",
                               error=error,
                               pagination=pagination,
                               pendingPayoutsList=pendingPayoutsList,
                               pgList=pgList,
                               selectStatus=selectStatus,
                               orderId=orderId,
                               searchId=searchId,
                               merchantId=merchantId,
                               pgId=pgId,
                               merchantsList=merchantsList,
                               startDate=startDate.strftime(date_format),
                               endDate=endDate.strftime(date_format),
                               merchantName=merchantName,
                               siteTitleList=siteTitleList,
                               siteTitle=siteTitle,
                                form=form)


@admin_reports.route("admin_download_pending_payout_transactions_csv_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_pending_payout_transactions_csv_reports():
    data_status={"responseStatus":0,"result":""}

    startDate = request.args.get("startDate", "")
    endDate = request.args.get("endDate", "")
    selectStatus = request.args.get("selectStatus", "")
    orderId = request.args.get("orderId", "")
    merchantId = request.args.get("merchantId", "")

    try:
        status = []
        # Set default date format
        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

        if selectStatus == "All" or selectStatus =="":
            status = [0, 2]
        elif selectStatus == "Processing":
            status = [2]
        else:
            status = [0]
   
        payouts_queryset = FundTransfers.objects(createdOn__gte=startDate, createdOn__lte=endDate, status__in=status).order_by("-createdOn").all()

        if orderId:
            payouts_queryset = payouts_queryset.filter(transactionUniqueId__icontains=orderId)

        if merchantId:
            payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])

        reportData = admin_download_payout_csv_reports_data(startDate,endDate,payouts_queryset)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download pending payout report data!!"
        return data_status


@admin_reports.route("/bank_pending_payout_transactions", methods=["POST", "GET"])
@adminid_access_token_required
def bank_pending_payout_transactions():
    payinList = []
    merchantsList = []
    pendingPayoutsList=[]
    pgList=[]

    page = ""
    total_count = ""
    per_page = ""
    snoCount = 0
    pagination = ""
    total_pending_amount = 0.0
    selectStatus=""
    searchId=""
    merchantId=""
    startDate=""
    endDate=""
    
    form = BankPendingPayoutTransactions(request.args)
    
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        permissionsList = check_permissions(session.get("adminId"),"bankPendingPayoutTransactionPermission")
        if "view" in permissionsList:

            startDate = request.args.get("startDate", "")
            endDate = request.args.get("endDate", "")
            selectStatus = request.args.get("selectStatus", "")
            # orderId = request.args.get("orderId", "")
            searchId=request.args.get("searchId","")
            # merchantName = request.args.get("merchantName", "")
            merchantId = request.args.get("merchantId", "")
            pgId = request.args.get("pgId","")
            # siteTitle =  request.args.get("siteTitle", "")
    

            status = [0, 2]

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            merchants_queryset = Users.objects(status__nin=[2]).only("id","phoneNumber","fullName")
            merchantsList = list(merchants_queryset)

            pg_queryset = TransactionAPI.objects(transactionType="Payout",status__in=[0,1]).only("id","apiName" ).order_by("-id")
                
            pgList = list(pg_queryset)
            
            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20
                start = (page - 1) * per_page
                snoCount = start
            
            # for each_merchant in merchants_queryset:
            #     merchantDict = fetching_user_details(each_merchant)
            #     merchantsList.append(merchantDict)

                if selectStatus == "All" or selectStatus =="":
                    status = [0, 2]
                elif selectStatus == "Processing":
                    status = [2]
                else:
                    status = [0]

                filters = Q(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status)   



                if merchantId:
                    filters &= Q(userId=merchantId)

                if pgId:
                        # payouts_queryset = payouts_queryset.filter(transactionAPIId__in=[pgId])
                    filters &= Q(transactionAPIId=pgId)

                if searchId:
                    filters &=  ( Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId) | Q(pgOrderId__icontains=searchId) )
                    

                total_count = FundTransfers.objects(filters).count()
                payouts_queryset = (FundTransfers.objects(filters)
                                                    .skip(start)
                                                    .limit(per_page)
                )

                for each_payout in payouts_queryset:
                    # snoCount +=1
                    payoutDict = fetching_payouts_details(each_payout)
                    # payoutDict["snoCount"]=snoCount
                    pendingPayoutsList.append(payoutDict)
                

                # print("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",pendingPayoutsList)
              
                # if searchId:
                #     filters &= Q(merchantReferenceNumber__icontains__icontains=searchId | Q(pgOrderId__icontains=searchId)).all()

                # else:
                #     payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,bankResponseStatus__in=status,fundTransferType__in=["Instant","bulk"],transferType="Debit").order_by("-createdOn").all()
                #     if merchantId:
                #         payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])

                    # if siteTitle:
                    #     user_ids = Users.objects(siteTitle__icontains=siteTitle).values_list('id')
                    #     payouts_queryset = payouts_queryset.filter(userId__in=user_ids)


                # Get the current page from the query parameters
                # page = request.args.get(get_page_parameter(), type=int, default=1)

                # per_page = 20  # Number of items per page

                # # Query the database for the current page's data
                # total_count = payouts_queryset.count()

                # start = (page - 1) * per_page

                # end = min(start + per_page, total_count)

                # total_payouts = payouts_queryset[start:end]
                


                # total_debit_amount = round(total_payouts.filter(transferType="Debit").sum("amount",) or 0.0,2)
                # for each_payout in payouts_queryset:
                #     snoCount +=1
                #     payoutDict = fetching_payouts_details(each_payout)
                #     payoutDict["snoCount"]=snoCount
                #     pendingPayoutsList.append(payoutDict)
                
                # snoCount = start
                
                # multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).order_by("-id").all()
                # for each_multiple_app_sites in multiple_app_sites_queryset:
                #     multiple_app_sites_dict = fetching_multiple_app_sites(each_multiple_app_sites)
                #     siteTitleList.append(multiple_app_sites_dict)
                snoCount = start

                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")

            else:
                print("form.errors",form.errors)


            return render_template("super_admin_templates/bank_pending_payout_transactions.html",
                                   pagination=pagination,
                                   pendingPayoutsList=pendingPayoutsList,
                                   pgList=pgList,
                                   selectStatus=selectStatus,
                                   searchId=searchId,
                                   merchantId=merchantId,
                                   pgId=pgId,
                                   merchantsList=merchantsList,
                                   startDate=startDate.strftime(date_format),
                                   endDate=endDate.strftime(date_format),
                                   form = form,
                                   page = page,
                                   totalPendingAmount=total_pending_amount,
                                   snoCount = snoCount
                               
                          
                                   )
        else:
            flash("The staff member do not have permission to view Bank pending payout transactions.")
            return render_template("super_admin_templates/bank_pending_payout_transactions.html")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched payout pending transaction data!!"
        return render_template("super_admin_templates/bank_pending_payout_transactions.html",
                               error=error,
                               pagination=pagination,
                               pendingPayoutsList=pendingPayoutsList,
                               pgList=pgList,
                               selectStatus=selectStatus,
                               searchId=searchId,
                               merchantId=merchantId,
                               pgId=pgId,
                               merchantsList=merchantsList,
                               startDate=startDate.strftime(date_format),
                               endDate=endDate.strftime(date_format),
                               form = form,
                               page = page,
                               totalPendingAmount=total_pending_amount,
                               snoCount = snoCount
                           
                               )

# @admin_reports.route("/view_pending_payout_transaction",methods=["POST","GET"])
# def view_pending_payout_transaction():
#     try:
#         if not session.get("adminId"):
#             return redirect("admin_login")
#         adminId = session.get("adminId")

#         payoutTransactionId = request.args.get("payoutTransactionId","")

#         payoutDict = {}
#         payout_queryset = FundTransfers.objects(id=payoutTransactionId).order_by("-id").first()
#         if payout_queryset:
#             payoutDict = fetching_payouts_details(payout_queryset)
#             return redirect(url_for(admin_reports.pending_payout_transactions),payoutDict=payoutDict)
#         else:
#             flash("Invalid transaction id!!")
#             return redirect(url_for(admin_reports.pending_payout_transactions))
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         error = "Unable to fetched payout pending transaction data!!"
#         return render_template("super_admin_templates/pending_payout_transactions.html", 
#             error=error,
#             payoutDict=payoutDict
#             )

@admin_reports.route("/auto_collect_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def auto_collect_transaction_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    permissionsList = check_permissions(session.get("adminId"),"autoCollectReportPermissions")
    if "view" in permissionsList:
        try:
            startDate = request.form.get("startDate","")
            endDate = request.form.get("endDate","")
            orderId = request.form.get("orderId","")
            virtualAcId = request.form.get("virtualAcId","")
            selectStatus = request.form.get("selectStatus","")
            utrNo = request.form.get("utrNo","")



            return render_template("super_admin_templates/auto_collect_transaction_reports_list.html",
                startDate=startDate,
                endDate=endDate,
                virtualAcId=virtualAcId,
                orderId=orderId,
                selectStatus=selectStatus,
                utrNo=utrNo
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched auto collect transaction data!!"
            return render_template("super_admin_templates/auto_collect_transaction_reports_list.html", 
                error=error,
                startDate=startDate,
                endDate=endDate,
                virtualAcId=virtualAcId,
                orderId=orderId,
                selectStatus=selectStatus,
                utrNo=utrNo
                )
    else:
        flash("The staff member does not have permission to view Auto collect transactions reports", "danger")
        return redirect(url_for("admin.dashboard"))
       

@admin_reports.route("/search_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def search_transaction_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        reportsList = []

        orderId = request.form.get("orderId","")
        clientOrderId = request.form.get("clientOrderId","")
        merchantMail = request.form.get("merchantMail","")
        paymentId = request.form.get("paymentId","")
        contactNumber = request.form.get("contactNumber","")

        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/search_transaction_reports_list.html",
            pagination=pagination,
            orderId=orderId,
            clientOrderId=clientOrderId,
            merchantMail=merchantMail,
            paymentId=paymentId,
            contactNumber=contactNumber,
            reportsList=reportsList
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched search transaction data!!"
        return render_template("super_admin_templates/search_transaction_reports_list.html", 
            error=error,
            pagination=pagination,
            orderId=orderId,
            clientOrderId=clientOrderId,
            merchantMail=merchantMail,
            paymentId=paymentId,
            contactNumber=contactNumber,
            reportsList=reportsList
            )

@admin_reports.route("/download_pg_reports",methods=["POST","GET"])
@adminid_access_token_required
def download_pg_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")
        reportType = request.form.get("reportType","")

        downloadPayinReportsList = []
        payout_download_reports_queryset = PayoutDownloadReports.objects(walletType="payin").order_by("-createdOn").all()
        for each_payin_report in payout_download_reports_queryset:
            downloadReportDict = fetching_payout_admin_download_reports(each_payin_report)
            downloadPayinReportsList.append(downloadReportDict)

        return render_template("super_admin_templates/download_pg_reports_list.html",
            downloadPayinReportsList=downloadPayinReportsList,
            startDate=startDate,
            endDate=endDate,
            reportType=reportType
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched download pg report data!!"
        return render_template("super_admin_templates/download_pg_reports_list.html", 
            error=error,
            downloadPayinReportsList=downloadPayinReportsList,
            startDate=startDate,
            endDate=endDate,
            reportType=reportType
            )

# @admin_reports.route("/admin_approved_for_payout_download_report",methods=["POST","GET"])
# @adminid_access_token_required
# def admin_approved_for_payout_download_report():
# 	if not session.get("adminId"):
# 		return redirect("admin_login")
# 	adminId = session.get("adminId")

# 	payoutDownloadReportId = request.args.get("payoutDownloadReportId","")
# 	try:
# 		if payoutDownloadReportId:
# 			payout_download_report_queryset = PayoutDownloadReports.objects(id=payoutDownloadReportId).first()
# 			if not payout_download_report_queryset:
# 				flash("Invaild download report id!!")
# 				return redirect(url_for("admin_reports.download_payout_reports"))

# 			if payout_download_report_queryset.status == 0:
# 				if payout_download_report_queryset.walletType == "payout":
# 					payout_csv_file,fileSize = download_payout_csv_report_data(payout_download_report_queryset)
# 					downloadFile = payout_csv_file
# 					fileSize = str(fileSize)
# 				elif payout_download_report_queryset.walletType == "auto_collect":
# 					autocollect_csv_file,fileSize = fetching_auto_collect_csv_download_reports(payout_download_report_queryset)
# 					downloadFile = autocollect_csv_file
# 					fileSize = str(fileSize)
# 				else:
# 					payin_csv_file,fileSize = download_payin_csv_report_data(payout_download_report_queryset)
# 					downloadFile = payin_csv_file
# 					fileSize = str(fileSize)
# 				payout_download_report_queryset.update(status=2,generatedOn=datetime.datetime.now(),downloadFile=downloadFile,fileSize=fileSize)
# 				flash("Admin generated successfully!")
# 			elif payout_download_report_queryset.status == 2:
# 				payout_download_report_queryset.update(status=1)
# 				flash("Admin approved successfully!")

# 			if payout_download_report_queryset.walletType == "payin":
# 				return redirect(url_for("admin_reports.download_pg_reports"))
# 			elif payout_download_report_queryset.walletType == "payout":
# 				return redirect(url_for("admin_reports.download_payout_reports"))
# 			elif payout_download_report_queryset.walletType == "auto_collect":
# 				return redirect(url_for("admin_reports.download_auto_collect_reports"))
# 		else:
# 			return redirect(url_for("admin_reports.download_payout_reports"))
# 	except Exception as e:
# 		app.logger.error(traceback.format_exc())
# 		flash("Unable to approve admin for download report!!")
# 		return redirect(url_for("admin_reports.download_payout_reports"))


@admin_reports.route("/admin_approved_for_payout_download_report",methods=["POST","GET"])
@adminid_access_token_required
def admin_approved_for_payout_download_report():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    servicePage = request.args.get("servicePage")
    search_element = request.args.get("search_element", "")
    payoutDownloadReportId = request.args.get("payoutDownloadReportId","")
    try:
        if payoutDownloadReportId:
            payout_download_report_queryset = PayoutDownloadReports.objects(id=payoutDownloadReportId).first()
            if not payout_download_report_queryset:
                flash("Invaild download report id","danger")
                return redirect(url_for("admin_reports.download_payout_reports",servicePage=servicePage,search_element=search_element))

            if payout_download_report_queryset.status == 0:
                if payout_download_report_queryset.walletType == "payout":
                    payout_csv_file,fileSize = download_payout_csv_report_data(payout_download_report_queryset)
                    downloadFile = payout_csv_file
                    fileSize = str(fileSize)
                elif payout_download_report_queryset.walletType == "auto_collect":
                    autocollect_csv_file,fileSize = fetching_auto_collect_csv_download_reports(payout_download_report_queryset)
                    downloadFile = autocollect_csv_file
                    fileSize = str(fileSize)
                else:
                    payin_csv_file,fileSize = download_payin_csv_report_data(payout_download_report_queryset)
                    downloadFile = payin_csv_file
                    fileSize = str(fileSize)
                payout_download_report_queryset.update(status=2,generatedOn=datetime.datetime.now(),downloadFile=downloadFile,fileSize=fileSize)
                flash("Admin generated successfully!","success")
            elif payout_download_report_queryset.status == 2:
                payout_download_report_queryset.update(status=1)
                flash("Admin approved successfully!","success")

            if payout_download_report_queryset.walletType == "payin":
                return redirect(url_for("admin_reports.download_pg_reports",servicePage=servicePage,search_element=search_element))
            elif payout_download_report_queryset.walletType == "payout":
                return redirect(url_for("admin_reports.download_payout_reports",servicePage=servicePage,search_element=search_element))
            elif payout_download_report_queryset.walletType == "auto_collect":
                return redirect(url_for("admin_reports.download_auto_collect_reports",servicePage=servicePage,search_element=search_element))
        else:
            return redirect(url_for("admin_reports.download_payout_reports",servicePage=servicePage,search_element=search_element))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash("Unable to approve admin for download report!!")
        return redirect(url_for("admin_reports.download_payout_reports",servicePage=servicePage,search_element=search_element))



# @admin_reports.route("/download_payout_reports",methods=["POST","GET"])
# @adminid_access_token_required
# def download_payout_reports():
#     if not session.get("adminId"):
#         return redirect("admin_login")
#     adminId = session.get("adminId")
#     permissionsList = check_permissions(session.get("adminId"),"downloadpayoutReportPermissions")
#     if "view" in permissionsList:
#         try:
#             startDate = request.form.get("startDate","")
#             endDate = request.form.get("endDate","")
#             reportType = request.form.get("reportType","")

#             downloadPayoutReportsList = []
#             payout_download_reports_queryset = PayoutDownloadReports.objects(walletType="payout").order_by("-createdOn").all()
#             for each_payout_report in payout_download_reports_queryset:
#                 downloadReportDict = fetching_payout_admin_download_reports(each_payout_report)
#                 downloadPayoutReportsList.append(downloadReportDict)


#             return render_template("super_admin_templates/download_payout_reports_list.html",
#                 startDate=startDate,
#                 endDate=endDate,
#                 downloadPayoutReportsList=downloadPayoutReportsList,
#                 reportType=reportType
#                 )
#         except Exception as e:
#             app.logger.error(traceback.format_exc())
#             error = "Unable to fetched download payout report data!!"
#             return render_template("super_admin_templates/download_payout_reports_list.html", 
#                 error=error,
#                 startDate=startDate,
#                 endDate=endDate,
#                 downloadPayoutReportsList=downloadPayoutReportsList,
#                 reportType=reportType
#                 )
#     else:
#         flash("Staff member does not have given view download payout reports permissions!!")
#         return render_template("super_admin_templates/download_payout_reports_list.html")



@admin_reports.route("/download_payout_reports",methods=["POST","GET"])
@adminid_access_token_required
def download_payout_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    downloadPayoutReportsList=[]
    pagination = None
    search_element=""
    snoCount=0
    servicePage=None
    merchantsList=[]
    form = DownloadPayoutReportsForm(request.args)
    permissionsList = check_permissions(session.get("adminId"),"downloadpayoutReportPermissions")
    if "view" in permissionsList:
        startDate = request.args.get("startDate","")
        endDate = request.args.get("endDate","")
        reportType = request.args.get("reportType","")
        merchantId = request.args.get("merchantId", "")
        date_format = "%d-%m-%Y"
        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
                    
        if form.validate():
            try:
                merchantsList=[]
                search_element = request.args.get("search_element", "")
                servicePage = request.args.get(get_page_parameter("servicePage"), type=int, default=1)
                print(servicePage,"((((((((((servicePage))))))))))")
                per_page = 20
                start = (servicePage - 1) * per_page
                total_count=0
                filters = Q(status__in=[0, 1, 2])
                print(per_page,"((((((((((((((per_page))))))))))))))")
                downloadPayoutReportsList = []
                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                for each_merchant in merchants_queryset:
                    # merchantDict = fetching_user_details(each_merchant)
                    merchantDict = {
                        "id": each_merchant.id,
                        "fullName": each_merchant.fullName,
                        "phoneNumber": each_merchant.phoneNumber
                    }
                    merchantsList.append(merchantDict)
                if merchantId:
                    filters &= Q(userId=merchantId)
                total_count = PayoutDownloadReports.objects(filters).count()
        
                payout_download_reports_queryset = (
                    PayoutDownloadReports.objects(filters)
                    .only("id","userId","reportType","createdOn","startDate","endDate","status","walletType", "dateRange","downloadFile", "fileSize")
                    .order_by("-id")
                    .skip(start)
                    .limit(per_page)
                )
                
                    
                # user_queryset = Users.objects(id=userId).first()
                # if user_queryset:
                # 	payinDict["userName"] = user_queryset.fullName
                # else:
                # 	payinDict["userName"] = ""
                
                # payout_download_reports_queryset = PayoutDownloadReports.objects(walletType="payout").order_by("-createdOn")
                for each_payout_report in payout_download_reports_queryset:
                    downloadReportDict = fetching_payout_admin_download_reports(each_payout_report)
                    downloadPayoutReportsList.append(downloadReportDict)
                snoCount = start
                print("************data*******", downloadPayoutReportsList)
                pagination = Pagination(servicePage=servicePage, total=total_count, per_page=per_page,page_parameter ="servicePage", alignment="right", record_name="Payout_reports",href=f"?search_element={search_element}&servicePage={{0}}")
                return render_template("super_admin_templates/download_payout_reports_list.html",
                    startDate=startDate.strftime(date_format),
                    endDate=endDate.strftime(date_format),
                    downloadPayoutReportsList=downloadPayoutReportsList,
                    reportType=reportType,
                    search_element=search_element,
                    snoCount=snoCount,
                    servicePage = servicePage,
                    form=form,
                    merchantId=merchantId,
                    merchantsList=merchantsList,
                    pagination=pagination,
                    )
            except Exception as e:
                app.logger.error(traceback.format_exc())
                error = "Unable to fetched download payout report data!!"
                return render_template("super_admin_templates/download_payout_reports_list.html", 
                    error=error,
                    # startDate=startDate,
                    # endDate=endDate,
                    downloadPayoutReportsList=downloadPayoutReportsList,
                    # reportType=reportType,
                    search_element=search_element,
                    snoCount=snoCount,
                    servicePage = servicePage,
                    form=form,
                    merchantId=merchantId,
                    merchantsList=merchantsList,
                    pagination=pagination,
                    )
        else:
            return render_template("super_admin_templates/download_payout_reports_list.html",
                    startDate=startDate.strftime(date_format),
                    endDate=endDate.strftime(date_format),
                    downloadPayoutReportsList=downloadPayoutReportsList,
                    reportType=reportType,
                    search_element=search_element,
                    snoCount=snoCount,
                    servicePage = servicePage,
                    form=form,
                    merchantId=merchantId,
                    merchantsList=merchantsList,
                    pagination=pagination,
                    )
    else:
        flash("The staff member does not have permission to view Download payout reports.", "danger")
        return redirect(url_for("admin.dashboard"))




@admin_reports.route("/payout_download_csv_list",methods=["POST","GET"])
@adminid_access_token_required
def payout_download_csv_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    downloadPayoutCSVReportsList = []
    
    adminId = session.get("adminId")
    try:
        downloadPayoutCSVReportsList = []
        fund_transfer_queryset = FundTransfers.objects(status__in=[0,1,2]).order_by("-createdOn").all()
        for each_payout_report in fund_transfer_queryset:
            downloadReportDict = fetching_payout_csv_download_reports(each_payout_report)
            downloadPayoutReportsList.append(downloadReportDict)

        fieldnames = ['Account Number', 'Account IFSCCode', 'Beneficiary Name','Beneficiary Mail','Beneficiary Phone','Amount','Payment Mode','Comment','Order Id','Bank Branch','Transfer Type','Transaction UniqueId','Txn Date','Transaction Status']
        temp_csv_file_name = "/media/payout_download_csv_reports_list/"+str(round(time.time() * 1000))+".csv"

        if not os.path.exists(os.path.join(app.config['SITE_ROOT'], "media/payout_download_csv_reports_list/")):
            os.makedirs(os.path.join(app.config['SITE_ROOT'], "media/payout_download_csv_reports_list/"))

        full_file_name = app.config['SITE_ROOT']+temp_csv_file_name
        with open(full_file_name, 'w', encoding='UTF8', newline='') as f:
            writer = csv.DictWriter(f, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(downloadPayoutReportsList)

        return send_file(
            app.config['SITE_ROOT']+temp_csv_file_name,
            mimetype='text/csv',
            download_name='Payout download report list.csv',
            as_attachment=True
        )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash("Unable to export CSV data!!")
        return redirect(url_for("admin_reports.download_payout_reports"))

@admin_reports.route("/download_auto_collect_reports",methods=["POST","GET"])
@adminid_access_token_required
def download_auto_collect_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")
        reportType = request.form.get("reportType","")

        downloadAutocollectReportsList = []
        payout_download_reports_queryset = PayoutDownloadReports.objects(status__in=[0,1],walletType="auto_collect").order_by("-createdOn").all()
        for each_auto_collect_report in payout_download_reports_queryset:
            downloadReportDict = fetching_payout_admin_download_reports(each_auto_collect_report)
            downloadAutocollectReportsList.append(downloadReportDict)

        return render_template("super_admin_templates/download_auto_collect_reports_list.html",
            downloadAutocollectReportsList=downloadAutocollectReportsList,
            startDate=startDate,
            endDate=endDate,
            reportType=reportType
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched download payout report data!!"
        return render_template("super_admin_templates/download_auto_collect_reports_list.html", 
            error=error,
            downloadAutocollectReportsList=downloadAutocollectReportsList,
            startDate=startDate,
            endDate=endDate,
            reportType=reportType
            )

@admin_reports.route("/sms_reports",methods=["POST","GET"])
@adminid_access_token_required
def sms_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")
        contactNumber = request.form.get("contactNumber","")
        merchantMail = request.form.get("merchantMail","")
        txnType = request.form.get("txnType","")


        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/sms_reports_list.html",
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            contactNumber=contactNumber,
            merchantMail=merchantMail,
            txnType=txnType
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched sms data!!"
        return render_template("super_admin_templates/sms_reports_list.html", 
            error=error,
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            contactNumber=contactNumber,
            merchantMail=merchantMail,
            txnType=txnType
            )

@admin_reports.route("/gst_tds_reports",methods=["POST","GET"])
@adminid_access_token_required
def gst_tds_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
 
    tartMonthYear = None
    selectYear = None
    selectMonth = None
    endMonthYear=None
    startMonthYear=None
    current_year = None
    last_year = None
    pagination = None
    usersList=[]
    userDict={}
    # snoCount=0
    # Page=""
    # pagination=None
    permissionsList = check_permissions(session.get("adminId"),"gstAndTdsReportPermissions")
    form = GstTdsReportSearchForm(request.args)
    if "view" in permissionsList:
        try:
            year = request.form.get("year","")
            month = request.form.get("month","")
            merchantMail = request.form.get("merchantMail","")
 
            userId = request.args.get("userId", "")
            selectYear = request.args.get("selectYear", default=str(datetime.datetime.now().year))
            selectMonth = request.args.get("selectMonth", default=datetime.datetime.now().strftime("%B"))
 
            month_number = datetime.datetime.strptime(selectMonth, "%B").month
            current_year = datetime.datetime.now().year
            last_year = current_year - 1
 
            startMonthYear = datetime.datetime(int(selectYear), month_number, 1)
            endMonthYear = datetime.datetime(int(selectYear), month_number, monthrange(int(selectYear), month_number)[1])
            startMonthYear = startMonthYear.replace(hour=0, minute=0, second=0, microsecond=0)
            endMonthYear = endMonthYear.replace(hour=23, minute=59, second=59, microsecond=999999)
           
            user_queryset = (
                Users.objects(status=1)
                .only("id","fullName")
                .order_by("-id")
            )
            usersList=list(user_queryset)
 
            # Page = request.args.get(get_page_parameter("Page"), type=int, default=1)
            # per_page = 20
            # start = (Page - 1) * per_page
            # total_count = 0
           
            filters = Q(status__in=[0, 1])
            if form.validate():
                filters &= Q(createdOn__gte=startMonthYear, createdOn__lte=endMonthYear)
                if userId:
                    filters &= Q(userId=userId)
 
                # total_count = Users.objects(filters).count()
 
                # user_queryset = (
                #   Users.objects(filters)
                #   .only("id", "userId", "status","createdOn")
                #   .order_by("-id")
                #   .skip(start)
                #   .limit(per_page)
                # )
               
                # usersList = list(user_queryset)
            # else:
            #   usersList=[]
               
 
            # snoCount = start
            # pagination = Pagination(Page=Page, total=total_count, per_page=per_page,page_parameter ="Page", alignment="right", record_name="gstandtds",href=f"?selectYear={selectYear}&selectMonth={selectMonth}&userId={userId}&Page={{0}}")
 
            return render_template("super_admin_templates/gst_tds_reports_list.html",
                pagination=pagination,
                year=year,
                month=month,
                merchantMail=merchantMail,
                startMonthYear=startMonthYear,
                selectYear=selectYear,
                selectMonth=selectMonth,
                endMonthYear=endMonthYear,
                current_year=current_year,
                last_year=last_year,
                # snoCount=snoCount,
                # Page=Page,
                # pagination=pagination,
                userId=userId,
                usersList=usersList,
                form=form,
 
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched GST/TDS data!!"
            return render_template("super_admin_templates/gst_tds_reports_list.html",
                error=error,
                pagination=pagination,
                year=year,
                month=month,
                merchantMail=merchantMail,
                startMonthYear=startMonthYear,
                selectYear=selectYear,
                selectMonth=selectMonth,
                endMonthYear=endMonthYear,
                current_year=current_year,
                last_year=last_year,
                userId=userId,
                # snoCount=snoCount,
                # Page=Page,
                # pagination=pagination,
                usersList=usersList,
                form=form,
               
                )
    else:
        flash("The staff member does not have permission to view GST/TDS report details.", "danger")
        return redirect(url_for("admin.dashboard"))

@admin_reports.route("/withdrawal_reports",methods=["POST","GET"])
@adminid_access_token_required
def withdrawal_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")

        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/withdrawal_reports_list.html",
            pagination=pagination,
            startDate=startDate,
            endDate=endDate
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched sms data!!"
        return render_template("super_admin_templates/withdrawal_reports_list.html", 
            error=error,
            pagination=pagination,
            startDate=startDate,
            endDate=endDate
            )

@admin_reports.route("/balance_summary_reports",methods=["POST","GET"])
@adminid_access_token_required
def balance_summary_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")
        selectMerchant = request.form.get("selectMerchant","")

        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/balance_summary_reports_list.html",
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            selectMerchant=selectMerchant
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched sms data!!"
        return render_template("super_admin_templates/balance_summary_reports_list.html", 
            error=error,
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            selectMerchant=selectMerchant
            )

@admin_reports.route("/balance_missing_summary_reports",methods=["POST","GET"])
@adminid_access_token_required
def balance_missing_summary_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")
        selectMerchantMail = request.form.get("selectMerchantMail","")

        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/balance_missing_summary_reports_list.html",
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            selectMerchantMail=selectMerchantMail
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched sms data!!"
        return render_template("super_admin_templates/balance_missing_summary_reports_list.html", 
            error=error,
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            selectMerchantMail=selectMerchantMail
            )

@admin_reports.route("/merchant_usage_reports",methods=["POST","GET"])
@adminid_access_token_required
def merchant_usage_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")

        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/merchant_usage_reports_list.html",
            pagination=pagination,
            startDate=startDate,
            endDate=endDate
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched sms data!!"
        return render_template("super_admin_templates/merchant_usage_reports_list.html", 
            error=error,
            pagination=pagination,
            startDate=startDate,
            endDate=endDate
            )

@admin_reports.route("/pag_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def pag_transaction_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        startDate = request.form.get("startDate","")
        endDate = request.form.get("endDate","")
        selectStatus = request.form.get("selectStatus","")
        merchantMail = request.form.get("merchantMail","")
        txnType = request.form.get("txnType","")
        enterRRN = request.form.get("enterRRN","")


        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)
        per_page = 20  # Number of items per page

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=0, per_page=per_page, alignment="right")

        return render_template("super_admin_templates/pag_transaction_reports_list.html",
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            selectStatus=selectStatus,
            merchantMail=merchantMail,
            enterRRN=enterRRN,
            txnType=txnType
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched sms data!!"
        return render_template("super_admin_templates/pag_transaction_reports_list.html", 
            error=error,
            pagination=pagination,
            startDate=startDate,
            endDate=endDate,
            selectStatus=selectStatus,
            merchantMail=merchantMail,
            enterRRN=enterRRN,
            txnType=txnType
            )

@admin_reports.route("/payment_links_reports",methods=["POST","GET"])
@adminid_access_token_required
def payment_links_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        permissionsList = check_permissions(session.get("adminId"),"paymentLinkPermissions")
        if "view" in permissionsList:
            startDate = request.form.get("startDate", "")
            endDate = request.form.get("endDate", "")
            selectStatus = request.form.get("selectStatus", "")
            paymentLink = request.form.get("paymentLink","")

            paymentLinksList = []

            currentDate = datetime.datetime.now()

            date_format = "%d-%m-%Y"
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
     
                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            payment_links_queryset = PaymentLinks.objects(createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()
            
            status = []
            # Apply filters based on selectStatus and other conditions
            if selectStatus in ["All", "Active", "Deactive", "Expired", ""]:
                if paymentLink:
                    payment_links_queryset = payment_links_queryset.filter(paymentLink=paymentLink)

                if selectStatus == "All":
                    status = [0,1,3]
                elif selectStatus == "Active":
                    status = [1]
                elif selectStatus == "Deactive":
                    status = [0]
                elif selectStatus == "Expired":
                    status = [3]

            # Apply the combined filter to the queryset
            payment_links_queryset = payment_links_queryset.filter(status__in=status)

            for each_payment_link in payment_links_queryset:
                paymentLinkDict = fetching_payment_link_details(each_payment_link)
                paymentLinksList.append(paymentLinkDict)

            return render_template("super_admin_templates/payment_links_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                selectStatus=selectStatus,
                paymentLinksList=paymentLinksList,
                paymentLink=paymentLink
                )
        else:
            flash("Staff member does not have given view payment links permissions!!")
            return render_template("super_admin_templates/payment_links_list.html")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched payment links data!!"
        return render_template("super_admin_templates/payment_links_list.html", 
            error=error,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            selectStatus=selectStatus,
            paymentLinksList=paymentLinksList,
            paymentLink=paymentLink
            )

@admin_reports.route("/payment_pages_reports",methods=["POST","GET"])
@adminid_access_token_required
def payment_pages_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        permissionsList = check_permissions(session.get("adminId"),"paymentPagePermissions")
        if "view" in permissionsList:
            merchantMail = request.form.get("merchantMail","")

            merchantsList = []

            merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn").all()
            if merchantMail:
                merchants_queryset = merchants_queryset.filter(email__icontains=merchantMail)
            for each_merchant in merchants_queryset:
                if each_merchant.merchantPaymentLink:
                    merchantDict = fetching_user_details(each_merchant)
                    merchantsList.append(merchantDict)

            return render_template("super_admin_templates/payment_pages_list.html",
                merchantsList=merchantsList,
                merchantMail=merchantMail
                )
        else:
            flash("Staff member does not have given view payment pages permissions!!")
            return render_template("super_admin_templates/payment_pages_list.html")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched payment pages data!!"
        return render_template("super_admin_templates/payment_pages_list.html", 
            error=error,
            merchantMail=merchantMail,
            merchantsList=merchantsList
            )

@admin_reports.route("/payment_buttons_reports",methods=["POST","GET"])
@adminid_access_token_required
def payment_buttons_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        
        permissionsList = check_permissions(session.get("adminId"),"paymentButtonPermissions")
        if "view" in permissionsList:
            paymentButtonsList = []

            startDate = request.form.get("startDate", "")
            endDate = request.form.get("endDate", "")
            selectStatus = request.form.get("selectStatus", "")

            currentDate = datetime.datetime.now()

            date_format = "%d-%m-%Y"
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
     
                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            payment_buttons_queryset = PaymentButtons.objects(createdOn__gte=startDate,createdOn__lte=endDate,status__nin=[2]).order_by("-createdOn")

            # Apply date filters and status filters
            status = [0,1]
            if selectStatus in ["All", "Active", "Deactive",""]:
                if selectStatus == "All":
                    status = [0,1]
                elif selectStatus == "Active":
                    status = [1]
                elif selectStatus == "Deactive":
                    status = [0]

                # Apply the combined filter to the queryset
                payment_buttons_queryset = payment_buttons_queryset.filter(status__in=status)

            for each_payment_button in payment_buttons_queryset:
                paymenButtonDict = fetching_payment_button_details(each_payment_button)
                paymentButtonsList.append(paymenButtonDict)

            return render_template("super_admin_templates/payment_buttons_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                selectStatus=selectStatus,
                paymentButtonsList=paymentButtonsList
                )
        else:
            flash("Staff member does not have given view payment buttons permissions!!")
            return render_template("super_admin_templates/payment_buttons_list.html")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched payment buttons data!!"
        return render_template("super_admin_templates/payment_buttons_list.html", 
            error=error,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            selectStatus=selectStatus,
            paymentButtonsList=paymentButtonsList
            )


@admin_reports.route("/update_manual_payout_status",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def update_manual_payout_status():
    
    if not session.get("adminId"):
        flash("Session expired. Please log in again.", "danger")
        data_status["responseStatus"]=4
        return data_status
    adminId=session.get("adminId")
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    latitude = request.form.get("latitude", "")
    longitude = request.form.get("longitude", "")
    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    existing_record = ""
    client_ip=0
    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"): 
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    actionDate=datetime.datetime.now()
   
    
    data_status={'status':0,'result':"failed."}
    status=request.form.get('transactionStatus')
    orderId=request.form.get('merchantReferenceNumber')
    errorMessage=request.form.get('errorMessage')
    jsonData = request.form.to_dict(flat=True)

    print("orderId=",orderId,"status=",status)
    form = TransactionStatusForm(request.form)

    data = request.form.to_dict()
               
                
    otp_check_id = request.form.get("otpLogid", "")
    defaultVerificationId = request.form.get("defaultVerificationId", "")
    print("otp_check_id",otp_check_id)
    if not otp_check_id:
        flash("Invalid Request.")
        data_status["responseStatus"]=4
        return data_status

    otpcheck_queryset = OtpChecks.objects(adminId=adminId,defaultVerificationField=defaultVerificationId, id=str(otp_check_id), status=1).first()

    if not otpcheck_queryset:
        flash("Invalid Request.")
        data_status["responseStatus"]=4
        return data_status
       
    try:
        if form.validate_on_submit():
            if orderId and status and errorMessage:
                fund_transfer_queryset = FundTransfers.objects(merchantReferenceNumber=orderId).first()

                existing_record = fund_transfer_queryset.to_json()
                admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
                message=admin_queryset.userName+" updated Payout Status successfully!"
                requestData=[fund_transfer_queryset]
                updatedrequestData=[jsonData]
                save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_manual_payout_status","update",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude)
                 
                if fund_transfer_queryset:
                    user_queryset = Users.objects(id=str(fund_transfer_queryset.userId.id)).first()
                    actuallBalance = user_queryset.payoutBalance
                    transaction_amount = float(fund_transfer_queryset.grandTotal)
                    if status == "1":    
                        fund_transfer_queryset.update(
                            responseCallBackTime=datetime.datetime.now(),
                            errorMessage = errorMessage,
                            manualStatusChange = 1,
                            status=1
                            )
                    elif status == "6":
                        balanceResult=user_payout_balance_update(str(fund_transfer_queryset.userId.id),float(fund_transfer_queryset.grandTotal),"Debit",str(fund_transfer_queryset.transactionAPIId.id))
                        if fund_transfer_queryset.status==0 or fund_transfer_queryset.status==4:
                            getrefund_record=FundTransfers.objects(transactionUniqueId=fund_transfer_queryset.merchantReferenceNumber,userId=str(fund_transfer_queryset.userId.id)).count()
                            if getrefund_record>0:
                                merchantReferenceNumber=str(random_digit_generate(16))
                                if fund_transfer_queryset.slabId:
                                    slabId = str(fund_transfer_queryset.slabId.id)
                                else:
                                    slabId = None
                                    
                                fund_transfer_table = FundTransfers(
                                    userId=str(fund_transfer_queryset.userId.id),
                                    transactionAPIId=str(fund_transfer_queryset.transactionAPIId.id),
                                    bankId=None,
                                    transactionUniqueId=str(fund_transfer_queryset.transactionUniqueId),
                                    bankName=str(fund_transfer_queryset.bankName),
                                    merchantReferenceNumber=str(merchantReferenceNumber),
                                    fundTransferId=str(fund_transfer_queryset.id),
                                    pgOrderId=str(fund_transfer_queryset.pgOrderId),
                                    fundTransferType="instant",
                                    accountType="bank",
                                    apiType="api",
                                    slabId=slabId,
                                    transferType="Debit",
                                    bankBranch=str(fund_transfer_queryset.bankBranch),
                                    accountNumber=str(fund_transfer_queryset.accountNumber),
                                    bankReferenceNumber=str(fund_transfer_queryset.bankReferenceNumber),
                                    accountIFSCCode=str(fund_transfer_queryset.accountIFSCCode),
                                    beneficiaryName=str(fund_transfer_queryset.beneficiaryName),
                                    uniqueRequestNumber=str(fund_transfer_queryset.beneficiaryName),
                                    amount=round(float(fund_transfer_queryset.amount),2),
                                    grandTotal=round(float(fund_transfer_queryset.grandTotal),2),
                                    beneficiaryMail=str(fund_transfer_queryset.beneficiaryMail),
                                    beneficiaryPhone=str(fund_transfer_queryset.beneficiaryPhone),
                                    paymentMode=str(fund_transfer_queryset.paymentMode),
                                    narration=str(fund_transfer_queryset.narration),
                                    commissionCharges=fund_transfer_queryset.commissionCharges,
                                    transactionData=fund_transfer_queryset.transactionData,
                                    currentBalance=round(float(balanceResult.get('userCurrentBalance')),2),
                                    previousBalance=round(float(balanceResult.get('userPreviousBalance')),2),
                                    createdOn=datetime.datetime.now(),
                                    statusCount = 1,
                                    errorMessage=errorMessage,
                                    clientIp=fund_transfer_queryset.clientIp,
                                    manualStatusChange = 1,
                                    status=1
                                    )
                                save_table = fund_transfer_table.save()
                            else:
                                fund_transfer_queryset.update(
                                    responseCallBackTime=datetime.datetime.now(),
                                    currentBalance=round(float(balanceResult.get('userCurrentBalance')),2),
                                    previousBalance=round(float(balanceResult.get('userPreviousBalance')),2),
                                    errorMessage = errorMessage,
                                    manualStatusChange = 1,
                                    status=1
                                    )    
                        else:
                            fund_transfer_queryset.update(
                                responseCallBackTime=datetime.datetime.now(),
                                currentBalance=round(float(balanceResult.get('userCurrentBalance')),2),
                                previousBalance=round(float(balanceResult.get('userPreviousBalance')),2),
                                errorMessage = errorMessage,
                                manualStatusChange = 1,
                                status=1
                                )
                    elif status=="0":
                        fund_transfer_queryset.update(
                            responseCallBackTime=datetime.datetime.now(),
                            errorMessage =errorMessage,
                            manualStatusChange = 1,
                            status=0
                            )
                    elif status=="4":
                        merchantReferenceNumber=str(random_digit_generate(16))
                        if fund_transfer_queryset.slabId:
                            slabId = str(fund_transfer_queryset.slabId.id)
                        else:
                            slabId = None
                        fund_transfer_table = FundTransfers(
                            userId=str(fund_transfer_queryset.userId.id),
                            transactionAPIId=str(fund_transfer_queryset.transactionAPIId.id),
                            bankId=None,
                            transactionUniqueId=str(fund_transfer_queryset.transactionUniqueId),
                            bankName=str(fund_transfer_queryset.bankName),
                            merchantReferenceNumber=str(merchantReferenceNumber),
                            fundTransferId=str(fund_transfer_queryset.id),
                            pgOrderId=str(fund_transfer_queryset.pgOrderId),
                            bankReferenceNumber=str(fund_transfer_queryset.bankReferenceNumber),
                            fundTransferType="instant",
                            accountType="bank",
                            apiType="api",
                            slabId=slabId,
                            transferType="Credit",
                            bankBranch=str(fund_transfer_queryset.bankBranch),
                            accountNumber=str(fund_transfer_queryset.accountNumber),
                            accountIFSCCode=str(fund_transfer_queryset.accountIFSCCode),
                            beneficiaryName=str(fund_transfer_queryset.beneficiaryName),
                            uniqueRequestNumber=str(fund_transfer_queryset.beneficiaryName),
                            amount=round(float(fund_transfer_queryset.amount),2),
                            grandTotal=round(float(fund_transfer_queryset.grandTotal),2),
                            beneficiaryMail=str(fund_transfer_queryset.beneficiaryMail),
                            beneficiaryPhone=str(fund_transfer_queryset.beneficiaryPhone),
                            paymentMode=str(fund_transfer_queryset.paymentMode),
                            narration=str(fund_transfer_queryset.narration),
                            commissionCharges=fund_transfer_queryset.commissionCharges,
                            transactionData=fund_transfer_queryset.transactionData,
                            createdOn=datetime.datetime.now(),
                            statusCount = 1,
                            errorMessage=errorMessage,
                            clientIp=fund_transfer_queryset.clientIp,
                            manualStatusChange = 1,
                            status=5
                            )
                        save_table = fund_transfer_table.save()
                        savedId = str(save_table.id)
                        if savedId:
                            balanceResult=user_payout_balance_update(str(fund_transfer_queryset.userId.id),float(fund_transfer_queryset.grandTotal),"Credit",str(fund_transfer_queryset.transactionAPIId.id))
                            if balanceResult.get('responseStatus')==0:
                                responseBody["error"]="Unable to connect to the server!!"
                                return redirect(url_for('admin_reports.update_transaction_reports'))
                            save_table.update(currentBalance=round(float(balanceResult.get('userCurrentBalance')),2),previousBalance=round(float(balanceResult.get('userPreviousBalance')),2))   
                        fund_transfer_queryset.update(
                            responseCallBackTime=datetime.datetime.now(),
                            errorMessage = errorMessage,
                            manualStatusChange = 1,
                            status=0
                            )
                    else:
                        # flash("Server Connection Error!.")
                        data_status["responseStatus"]=4
                        data_status["result"]="Server Connection Error"
                        return data_status
                    flash("status successfully updated.")
                    data_status["responseStatus"]=1
                    return data_status
                else:
                    # flash("Server Connection Error!.")
                    data_status["responseStatus"]=4
                    data_status["result"]="Server Connection Error"
                    return data_status
            else:
                # flash("Server Connection Error!.")
                data_status["responseStatus"]=4
                data_status["result"]="Server Connection Error"
                return data_status

        else:
            data_status["result"]=form.errors
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash("Unable to fetched payment data")
        data_status["responseStatus"]=4
        return data_status


# @admin_reports.route("/save_slab",methods=["GET"])
# def save_slab():
#   data_status={"responseSatus":0,"result":""}
#   try:
#       userId = "667d13c17ebce740151a9437"
#       slabId = "66825a3959b5a7514e11bdc8"

#       fund_transfer_queryset = FundTransfers.objects(userId=str(userId)).order_by("-id").all()
#       for each_slab_update in fund_transfer_queryset:
#           each_slab_update.update(slabId=ObjectId(slabId))

#       data_status["responseSatus"]=1
#       data_status["result"]="Success"
#       data_status["totalCount"]=fund_transfer_queryset.count()
#       return data_status
#   except Exception as e:
#       app.logger.error(traceback.format_exc())
#       data_status["result"]="Unsuccess"
#       return data_status

@admin_reports.route("/payin_settlement_reports",methods=["POST","GET"])
@adminid_access_token_required
def payin_settlement_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
            
    form = PayinSettlementReportsForm(request.args)
    payinList = []
    merchantsList = []
    page = ""
    total_count = ""
    per_page = ""
    snoCount = 0
    pagination = ""
    permissionsList = check_permissions(session.get("adminId"),"payinSettlementPermissions")
    if "view" in permissionsList:
        try:   
            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            orderId = request.args.get("orderId","")
            merchantId = request.args.get("merchantId","")

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            
            
            merchants_queryset = Users.objects(status__nin=[2]).only("id","phoneNumber","fullName")
            merchantsList = list(merchants_queryset)

            if form.validate():
                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20
                start = (page - 1) * per_page
                snoCount = start

                filters = Q(status__nin=[2],createdOn__gte=startDate,createdOn__lte=endDate) 
               
                if orderId:
                    filters &= Q(orderId=orderId)
             
                if merchantId:
                    filters &= Q(userId=merchantId) 
                
                payin_settlement_reports = WalletTransactions.objects(filters).only("id", "userId", "orderId", "amount", "createdOn", "creditType", "comment").skip(start).limit(per_page)
                payinList = list(payin_settlement_reports)

                total_count = payin_settlement_reports.count()
                snoCount = start
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payins")

            else:
                print("form errors", form.errors)

            return render_template("super_admin_templates/payin_settlement_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                payinList=payinList,
                pagination=pagination,
                merchantsList=merchantsList,
                merchantId=merchantId,
                orderId=orderId,
                form = form,
                page = page,
                snoCount = snoCount
                )
            
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched payin settlement report data!!"
            return render_template("super_admin_templates/payin_settlement_reports_list.html", 
                error=error,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                payinList=payinList,
                pagination=pagination,
                merchantsList=merchantsList,
                merchantId=merchantId,
                orderId=orderId,
                form = form,
                page = page,
                snoCount = snoCount
                )
    else:
        flash("The staff member does not have permission to view Payin settlement reports.", "danger")
        return redirect(url_for("admin.dashboard"))
        

@admin_reports.route("/payout_settlement_reports",methods=["POST","GET"])
@adminid_access_token_required
def payout_settlement_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    form = PayoutSettlementReportForm(request.args)
    payoutsList = []
    merchantsList = []
    page = None
    snoCount = 0
    pagination = None
    permissionsList = check_permissions(session.get("adminId"),"payoutSettlementPermissions")
    if "view" in permissionsList:
        try:
            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            orderId = request.args.get("orderId","")
            merchantId = request.args.get("merchantId","")

            # Set default date format
            date_format = "%d-%m-%Y"
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)

                per_page = 20
                start = (page - 1) * per_page
                snoCount = int(start)

                total_count=0

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                merchantsList = list(merchants_queryset)

                query = Q(createdOn__gte=startDate,createdOn__lte=endDate)

                # if merchantId:
                #     query  &= Q(userId__in=[merchantId])
                
                # if orderId:
                #     query  &= Q(userId__in=[orderId])

                if orderId:
                    print("orderId", orderId)
                    query &= Q(merchantReferenceNumber__icontains=orderId)

                if merchantId:
                    print("merchantId", merchantId)
                    query &= Q(userId__icontains=merchantId)

                fund_transfer_queryset = (
                    FundTransfers.objects(query)
                    .only("id","userId","createdOn","merchantReferenceNumber","transferType","amount","narration")
                    .order_by("-createdOn")
                    .skip(start)
                    .limit(per_page)
                )

                total_count = FundTransfers.objects(query).count()

                payoutsList= list(fund_transfer_queryset)


                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")
            else:
                print("form errors", form.errors)
            # merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
            # for each_merchant in merchants_queryset:
            #     merchantDict = fetching_user_details(each_merchant)
            #     merchantsList.append(merchantDict)

            # fund_transfer_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,userType="admin").order_by("-createdOn").all()

            # if orderId:
            #     fund_transfer_queryset = fund_transfer_queryset.filter(merchantReferenceNumber=orderId)

            # if merchantId:
            #     fund_transfer_queryset = fund_transfer_queryset.filter(userId__in=[merchantId])

            # Get the current page from the query parameters
            # page = request.args.get(get_page_parameter(), type=int, default=1)

            # per_page = 20  # Number of items per page

            # # Query the database for the current page's data
            # total_count = fund_transfer_queryset.count()

            # start = (page - 1) * per_page

            # end = min(start + per_page, total_count)

            # total_payouts = fund_transfer_queryset[start:end]
            
            # snoCount = start
            # for each_payout in total_payouts:
            #     snoCount +=1
            #     payoutDict = fetching_payouts_details(each_payout)
            #     payoutDict["snoCount"]=snoCount
            #     payoutsList.append(payoutDict)

            # # Pagination object for rendering pagination controls in the template
            # pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")

            return render_template("super_admin_templates/payout_settlement_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                pagination=pagination,
                payoutsList=payoutsList,
                merchantsList=merchantsList,
                merchantId=merchantId,
                orderId=orderId,
                form = form,
                page=page,
                snoCount = snoCount
                )
            
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched payout settlement report data!!"
            return render_template("super_admin_templates/payout_settlement_reports_list.html", 
                error=error,
                pagination=pagination,
                payoutsList=payoutsList,
                merchantsList=merchantsList,
                merchantId=merchantId,
                orderId=orderId,
                form = form,
                page=page,
                snoCount = snoCount
                )
    else:
        flash("The staff member does not have permission to view Payout settlement reports", "danger")
        return redirect(url_for("admin.dashboard"))
       

######################################## OLD COMMISSION REPORTS CODE ###################################################
# @admin_reports.route("/commission_settlement_reports",methods=["POST","GET"])
# def commission_settlement_reports():
#   try:
#       if not session.get("adminId"):
#           return redirect("admin_login")
#       adminId = session.get("adminId")
#       permissionsList = check_permissions(session.get("adminId"),"payoutSettlementPermissions")
#       if "view" in permissionsList:
#           commissionsList = []
#           merchantsList = []

#           startDate = request.args.get("startDate","")
#           endDate = request.args.get("endDate","")
#           merchantId = request.args.get("merchantId","")

#           # Set default date format
#           date_format = "%d-%m-%Y"
#           pagination = None
#           try:
#               if startDate:
#                   startDate = datetime.datetime.strptime(startDate, date_format)
#                   startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
#               else:
#                   startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

#               if endDate:
#                   endDate = datetime.datetime.strptime(endDate, date_format)
#                   endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
#               else:
#                   endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
#           except Exception as ve:
#               app.logger.error("Date parsing error: %s", ve)
#               startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
#               endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

#           merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
#           for each_merchant in merchants_queryset:
#               merchantDict = fetching_user_details(each_merchant)
#               merchantsList.append(merchantDict)

#           commission_transactions_queryset = UserCommissions.objects(createdOn__gte=startDate,createdOn__lte=endDate,transferType="Credit").order_by("-createdOn")

#           # if orderId:
#           #   commission_transactions_queryset = commission_transactions_queryset.filter(merchantReferenceNumber=orderId)

#           if merchantId:
#               commission_transactions_queryset = commission_transactions_queryset.filter(userId__in=[merchantId])

#           # Get the current page from the query parameters
#           page = request.args.get(get_page_parameter(), type=int, default=1)

#           per_page = 20  # Number of items per page

#           # Query the database for the current page's data
#           total_count = commission_transactions_queryset.count()

#           start = (page - 1) * per_page

#           end = min(start + per_page, total_count)

#           total_commissions = commission_transactions_queryset[start:end]
            
#           snoCount = start
#           for each_commission in total_commissions:
#               snoCount +=1
#               commissionDict = fetching_commission_transaction_details(each_commission)
#               commissionDict["snoCount"]=snoCount
#               commissionsList.append(commissionDict)

#           # Pagination object for rendering pagination controls in the template
#           pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="commissions")

#           return render_template("super_admin_templates/commission_settlement_reports.html",
#               startDate=startDate.strftime(date_format),
#               endDate=endDate.strftime(date_format),
#               pagination=pagination,
#               commissionsList=commissionsList,
#               merchantsList=merchantsList,
#               merchantId=merchantId
#               )
#       else:
#           flash("Staff member does not have given view commissions settlement reports permissions!!")
#           return render_template("super_admin_templates/commission_settlement_reports.html")
#   except Exception as e:
#       app.logger.error(traceback.format_exc())
#       error = "Unable to fetched commissions settlement report data!!"
#       return render_template("super_admin_templates/commission_settlement_reports.html", 
#           error=error,
#           pagination=pagination,
#           startDate=startDate.strftime(date_format),
#           endDate=endDate.strftime(date_format),
#           commissionsList=commissionsList,
#           merchantsList=merchantsList,
#           merchantId=merchantId
#           )


def fetching_admin_balances_logs_details(each_admin_balance_log):
    adminBalanceLogDict = {}
    try:
        adminBalanceLogDict = {
        "id":str(each_admin_balance_log.id),
        "transferType":each_admin_balance_log.transferType,
        "walletType":each_admin_balance_log.walletType,
        "previousBalance":formatINR("{:.2f}".format(float(each_admin_balance_log.previousBalance))),
        "currentBalance":formatINR("{:.2f}".format(float(each_admin_balance_log.currentBalance))),
        "amount":formatINR("{:.2f}".format(float(each_admin_balance_log.amount))),
        "comment":each_admin_balance_log.comment,
        "createdOn":each_admin_balance_log.createdOn.astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p")
        }
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return adminBalanceLogDict


@admin_reports.route("/admin_overall_balances_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_overall_balances_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    form = AdminOverallBalancesReportsForm(request.args)
    permissionsList = check_permissions(session.get("adminId"),"virtualAdminBalancePermissions")
    if "view" in permissionsList:
        try: 
            
            adminId = session.get("adminId")
            adminBalanceLogsList = []
            page = ""
            total_count = ""
            per_page = ""
            snoCount = 0

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            walletType = request.args.get("walletType","")
            transferType = request.args.get("transferType","") 
            print(startDate,endDate,walletType,transferType)

            page = request.args.get(get_page_parameter(), type=int, default=1)
            per_page = 20
            start = (page - 1) * per_page
            snoCount = start
            filters=Q(status = 1)


            date_format = "%d-%m-%Y"
            pagination = None
            try:
                
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate,date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            if form.validate():
                
                

                # if transferType:
                #     admin_log_balances_queryset = admin_log_balances_queryset.filter(transferType=transferType)

                # if walletType:
                #     admin_log_balances_queryset = admin_log_balances_queryset.filter(walletType=walletType)
                if startDate:
                    print("startDate", startDate)
                    filters &= Q(createdOn__gte=startDate) 

                if endDate:
                    print("endDate", endDate)
                    filters &= Q(createdOn__lte=endDate)  

                if transferType:
                    print("transferType", transferType)
                    filters &= Q(transferType__icontains=transferType)
                
                if walletType:
                    print("walletType", walletType)
                    filters &= Q(walletType__icontains=walletType)

                admin_log_balances_queryset = AdminLogBalances.objects(filters).only("id","transferType","walletType","previousBalance","currentBalance","amount","comment","createdOn").skip(start).limit(per_page)
                adminBalanceLogsList = list(admin_log_balances_queryset)

                total_count = admin_log_balances_queryset.count()
                
                snoCount = start
                # for each_admin_balance_log in total_admin_balance_logs:
                #     snoCount +=1
                #     adminBalanceLogDict = fetching_admin_balances_logs_details(each_admin_balance_log)
                #     adminBalanceLogDict["snoCount"]=snoCount
                #     adminBalanceLogsList.append(adminBalanceLogDict)
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")
                print(startDate,endDate,type(startDate), type(endDate))
            else:
                flash("Unable to fetched admin overall balances report data!!","danger")
                print("form errors", form.errors)



            return render_template("super_admin_templates/admin_overall_balances_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                pagination=pagination,
                adminBalanceLogsList=adminBalanceLogsList,
                walletType=walletType,
                transferType=transferType, 
                form = form,
                page = page, 
                snoCount = snoCount
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched admin overall balances report data!!"
            return render_template("super_admin_templates/admin_overall_balances_reports_list.html", 
                error=error,
                pagination=pagination,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                adminBalanceLogsList=adminBalanceLogsList,
                walletType=walletType,
                transferType=transferType,
                form = form,
                page = page, 
                snoCount = snoCount
                )
    else:
        flash("The staff member does not have permission to view Admin overall balances reports.", "danger")
        return redirect(url_for("admin.dashboard"))
        

@admin_reports.route("/generate_new_report",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def generate_new_report():
    data_status={"responseStatus":0,"result":""}
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    form=AdminGeneratedReportsForm(request.args)
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        permissionsList = check_permissions(adminId,"adminPayoutDownloadReportPermission")
        if "add" in permissionsList:
            if request.method == "POST":
                userId = request.form.get("userId","")
                reportType = request.form.get("reportType","")
                walletType = request.form.get("walletType","")
                startDate = request.form.get("startDate","")
                endDate = request.form.get("endDate","")

                datetime_format = "%d-%m-%Y"
                if form.validate_on_submit():
                    if reportType and walletType and startDate and endDate:
                        try:
                            generate_report_table = PayoutDownloadReports(
                                reportType=reportType,
                                dateRange="",
                                walletType=walletType,
                                userType="admin",
                                createdOn=datetime.datetime.now(),
                                status=0
                                )
                            save_table=generate_report_table.save()

                            print("startDate",startDate)
                            print("endDate",endDate)
                            print("userId",userId)
                            startDateObject = datetime.datetime.strptime(startDate, datetime_format)
                            endDateObject = datetime.datetime.strptime(endDate, datetime_format)
                            startDate = startDateObject  
                            endDate = endDateObject

                            if userId:
                                save_table.update(userId = ObjectId(userId))
                            save_table.update(startDate = startDate,endDate = endDate)

                            flash("Generate new report successfully!")
                            data_status['responseStatus']=1
                            return data_status
                        except Exception as e:
                            flash("Unable to generate new report details!!")
                            app.logger.error(traceback.format_exc())
                            data_status['responseStatus']=4
                            return data_status
                    else:
                        data_status['responseStatus']=2
                        data_status['result']="Required fields are missing!!"
                        return data_status
                else:
                    data_status['result']=form.errors
                    return data_status
            else:
                data_status['responseStatus']=4
                return data_status
        else:
            flash("Staff member does not have given create New report permissions!!")
            data_status['responseStatus']=4
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash("Unable to save master bank details.", "danger")
        data_status['responseStatus']=4
        return data_status

@admin_reports.route("/admin_payout_download_reports_list",methods=["POST","GET"])
@adminid_access_token_required
def admin_payout_download_reports_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    downloadReportsList = []
    merchantsList = []
    
    date_format = "%d-%m-%Y"
    snoCount=0
    pagination = None
    permissionsList = check_permissions(session.get("adminId"),"adminPayoutDownloadReportPermission")
    if "view" in permissionsList:
        try:
            merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName").order_by("-createdOn")
            # for each_merchant in merchants_queryset:
            #     merchantDict = fetching_user_details(each_merchant)
            #     merchantsList.append(merchantDict)
            merchantsList = list(merchants_queryset)

            generateReportPage = request.args.get(get_page_parameter("generateReportPage"), type=int, default=1)
            per_page = 20
            start = (generateReportPage - 1) * per_page

            total_count=0
            snoCount = start

            total_count = PayoutDownloadReports.objects().count()
            payout_download_reports_queryset = PayoutDownloadReports.objects(userType="admin").order_by("-createdOn").skip(start).limit(per_page)
            for each_report in payout_download_reports_queryset:
                downloadReportDict = fetching_payout_download_reports(each_report)
                downloadReportsList.append(downloadReportDict)
            # print("downloadReportsList",downloadReportsList)
            pagination = Pagination(generateReportPage=generateReportPage, total=total_count, per_page=per_page,page_parameter ="generateReportPage", alignment="right", record_name="generate_Report")
            return render_template("super_admin_templates/admin_generated_reports.html",downloadReportsList=downloadReportsList,merchantsList=merchantsList,snoCount=snoCount,pagination=pagination)
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch payout download reports!"
            return render_template("super_admin_templates/admin_generated_reports.html",error=error,downloadReportsList=downloadReportsList,merchantsList=merchantsList,snoCount=snoCount,pagination=pagination)
    else:
        flash("The staff member does not have permission to view Payout download reports", "danger")
        return redirect(url_for("admin.dashboard"))

@admin_reports.route("/admin_payout_download_report_status",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def admin_payout_download_report_status():
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    if not session.get("adminId"):
        return redirect("admin_login")
    permissionsList = check_permissions(session.get("adminId"),"adminPayoutDownloadReportPermission")
    if "edit" in permissionsList:
        payoutDownloadReportId = request.args.get("payoutDownloadReportId","")
        print("payoutDownloadReportId((((((((((payoutDownloadReportId))))))))))",payoutDownloadReportId)
        if payoutDownloadReportId:
            try:
                payout_download_report_queryset = PayoutDownloadReports.objects(id=payoutDownloadReportId).first()
                if payout_download_report_queryset:
                    if payout_download_report_queryset.status == 0:
                        if payout_download_report_queryset.walletType == "payout":
                            payout_csv_file,fileSize = download_payout_csv_report_data(payout_download_report_queryset)
                            downloadFile = payout_csv_file
                            fileSize = str(fileSize)
                        else:
                            payin_csv_file,fileSize = download_payin_csv_report_data(payout_download_report_queryset)
                            downloadFile = payin_csv_file
                            fileSize = str(fileSize)
                        payout_download_report_queryset.update(status=2,generatedOn=datetime.datetime.now(),downloadFile=downloadFile,fileSize=fileSize)

                        flash("Payout download report generated successfully!")
                    elif payout_download_report_queryset.status == 2:
                        payout_download_report_queryset.update(status=1)

                        flash("Payout download report approved successfully!")
                    return redirect(url_for("admin_reports.admin_payout_download_reports_list"))
                else:
                    flash("Invaild id!!")
                    return redirect(url_for("admin_reports.admin_payout_download_reports_list"))
            except Exception as e:
                app.logger.error(traceback.format_exc())
                return redirect(url_for("admin_reports.admin_payout_download_reports_list"))
        else:
            flash("Required field is missing!!")
            return redirect(url_for("admin_reports.admin_payout_download_reports_list"))
    else:
        flash("Staff member does not have given update status Payout download report permissions!!")
        return redirect(url_for("admin_reports.admin_payout_download_reports_list"))

@admin_reports.route("/update_admin_payout_download_report",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def update_admin_payout_download_report():
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    if not session.get("adminId"):
        return redirect("admin_login")
    payoutDownloadReportId = request.args.get("payoutDownloadReportId","")
    userId = request.form.get("userId","")
    reportType = request.form.get("reportType","")
    walletType = request.form.get("walletType","")
    startDate = request.form.get("startDate","")
    endDate = request.form.get("endDate","")

    datetime_format = "%d-%m-%Y"
    if payoutDownloadReportId:
        try:
            permissionsList = check_permissions(session.get("adminId"),"adminPayoutDownloadReportPermission")
            if "edit" in permissionsList:
                if form.validate():
                    payout_download_report_queryset = PayoutDownloadReports.objects(id=payoutDownloadReportId).first()
                    if payout_download_report_queryset:
                        payout_download_report_queryset.update(
                            userId=ObjectId(userId),
                            reportType=reportType,
                            walletType=walletType
                            )
                        startDateObject = datetime.datetime.strptime(startDate, datetime_format)
                        endDateObject = datetime.datetime.strptime(endDate, datetime_format)
                        startDate = startDateObject  
                        endDate = endDateObject

                        payout_download_report_queryset.update(startDate = startDate,endDate = endDate)

                        flash("Payout download report updated successfully!")
                        data_status["responseStatus"]=1
                        return data_status
                    else:
                        flash("Invaild id!!")
                        data_status["responseStatus"]=2
                        return data_status
                else:
                    data_status["result"]=form.errors
                    return data_status
            else:
                flash("Staff member does not have given update payout download report permissions!!")
                data_status["responseStatus"]=4
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            flash("Unable to update payout download report data!!")
            data_status["responseStatus"]=4
            return data_status
    else:
        flash("Required field is missing!!","danger")
        data_status["responseStatus"]=4
        return data_status
    

class ChargeBackReportsForm(FlaskForm):
    startDate = StringField('',validators=[Optional(),Regexp( r"^\d{2}-\d{2}-\d{4}$", message="Date must be in DD-MM-YYYY format")])
    endDate = StringField('', validators=[ Optional(), Regexp( r"^\d{2}-\d{2}-\d{4}$", message="Date must be in DD-MM-YYYY format")])
    rrn = StringField('', validators=[Optional(),Length(min=MIN_LENGTH_3, max=MAX_LENGTH_32,message="SearchId Must be between 6 and 35 characters"),Regexp(ALPHANUMERIC_WITHOUT_SPACE, message="SearchId accepts only AlphaNumeric Characters")])
    merchantId = SelectField('', choices=[],validate_choice=False , validators=[Optional()])

    def validate_merchantId(self, field):
        if field.data:
            if not ObjectId.is_valid(field.data): 
                raise ValidationError("Invalid Merchant Id.")
            merchant_queryset = Users.objects(id=field.data,status__nin=[2]).first()
            if not merchant_queryset:
                raise ValidationError("Please select a Valid Merchant Id")

    class Meta:
        csrf = False



@admin_reports.route("/charge_backs_reports",methods=["POST","GET"])
@adminid_access_token_required
def charge_backs_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    form = ChargeBackReportsForm(request.args)
    chargeBackList = []
    merchantsList = []
    page = 1
    snoCount = 0
    pagination = ""
    startDate = ""
    endDate = ""
    merchantId = ""
    rrn = ""


    permissionsList = check_permissions(session.get("adminId"),"chargeBacksReportPermissions")
    if "view" in permissionsList:
        try:
            adminId = session.get("adminId")

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            merchantId = request.args.get("merchantId","")
            rrn = request.args.get("rrn","")

            # Set default date format
            date_format = "%d-%m-%Y"
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            
            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20
                start = (page - 1) * per_page
                snoCount = int(start)

                total_count=0

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                merchantsList = list(merchants_queryset)   

                query = Q(createdOn__gte=startDate,createdOn__lte=endDate)   

                if rrn:
                    query &= Q(pgOrderId__icontains=rrn)

                if merchantId:
                    print("merchantId", merchantId)
                    query &= Q(userId__in=[merchantId])   

                chargebacks_reports_queryset = (
                    ChargeBacks.objects(query)
                    # .only("id","userId","adjustDate","walletTransactionId","referId","rrn","upiTxnId","pgOrderId","remitter","beneficiaryName","adjAmount","txnAmount","txnDate","payee","adjustType","createdOn","status")
                    .order_by("-createdOn")
                    .skip(start)
                    .limit(per_page)
                )     

                total_count = ChargeBacks.objects(query).count()
                
                chargeBackList = list(chargebacks_reports_queryset)

                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="chargebacks")
            else:
                # flash("Unable to fetched Charge Backs report data!!","danger")
                print("form errors", form.errors)
            # merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
            # for each_merchant in merchants_queryset:
            #     merchantDict = fetching_user_details(each_merchant)
            #     merchantsList.append(merchantDict)

            # chargebacks_reports_queryset = ChargeBacks.objects(createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()

            # if merchantId:
            #     chargebacks_reports_queryset = chargebacks_reports_queryset.filter(userId__in=[merchantId])

            # if rrn:
            #     chargebacks_reports_queryset = chargebacks_reports_queryset.filter(rrn__icontains=rrn)

            # # Get the current page from the query parameters
            # page = request.args.get(get_page_parameter(), type=int, default=1)

            # per_page = 20  # Number of items per page

            # # Query the database for the current page's data
            # total_count = chargebacks_reports_queryset.count()

            # start = (page - 1) * per_page

            # end = min(start + per_page, total_count)

            # total_charge_backs = chargebacks_reports_queryset[start:end]
            
            # snoCount = start
            # for each_charge_back in total_charge_backs:
            #     snoCount +=1
            #     chargebackDict = fetching_charge_backs_reports(each_charge_back)
            #     chargebackDict["snoCount"]=snoCount
            #     chargeBackList.append(chargebackDict)

            # # Pagination object for rendering pagination controls in the template
            # pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="chargebacks")

            return render_template("super_admin_templates/charge_backs_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                pagination=pagination,
                chargeBackList=chargeBackList,
                merchantsList=merchantsList,
                rrn=rrn,
                merchantId=merchantId,
                form = form,
                page=page,
                snoCount = snoCount
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched charge back reports data!!"
            return render_template("super_admin_templates/charge_backs_reports_list.html", 
                error=error,
                pagination=pagination,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                chargeBackList=chargeBackList,
                merchantsList=merchantsList,
                rrn=rrn,
                merchantId=merchantId,
                form = form,
                page=page,
                snoCount = snoCount
                )
    else:
        flash("The staff member does not have permission to view Charge back reports.", "danger")
        return redirect(url_for("admin.dashboard"))


def parse_date(date_str):
    """
    Parse date from string in format 'DD-MM-YYYY' or as an Excel serial date.
    """
    try:
        # Try to parse as 'DD-MM-YYYY'
        return datetime.datetime.strptime(date_str, '%d-%m-%Y')
    except ValueError:
        try:
            # If that fails, try to parse as Excel serial date
            excel_date = int(date_str)
            start_date = datetime.datetime(1899, 12, 30)  # Excel epoch date
            delta = datetime.timedelta(days=excel_date)
            return start_date + delta
        except ValueError:
            raise ValueError(f"Invalid date format: {date_str}")

def clean_numeric_string(num_str):
    """
    Remove commas and any non-numeric characters from the string.
    """
    try:
        # Remove commas and any non-numeric characters, then convert to float
        cleaned_str = num_str.replace(',', '').replace('₹', '').replace('$', '')
        return float(cleaned_str)
    except ValueError as e:
        raise ValueError(f"Invalid number format: {num_str}")
    
class ChargeBackUploadCsvData(FlaskForm):
    merchantId = SelectField('', choices=[],validate_choice=False,validators=[DataRequired(message="Merchant Name is required")])
    upload_csv_file = FileField('', validators=[FileRequired(message="Please upload a file."),FileAllowed(['csv'], message = "Invalid Format, Only .csv files are allowed.")])


    def validate_merchantId(self, field):
        if field.data:
            if not ObjectId.is_valid(field.data): 
                raise ValidationError("Invalid Merchant Id.")
            merchant_queryset = Users.objects(id=field.data,status__nin=[2]).first()
            if not merchant_queryset:
                raise ValidationError("Please select a Valid Merchant Id")

    class Meta:
        csrf = False



@admin_reports.route("/upload_csv_data", methods=["POST", "GET"])
@adminid_access_token_required
@csrf_protect
def upload_csv_data():
    data_status={"responseStatus":0,"result":""}
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    
    merchantId = request.form.get("merchantId", "")
    upload_csv_file = request.files.get("upload_csv_file") 

    # if not upload_csv_file or not merchantId:
    #     flash("Required fields are missing!!")
    #     return redirect(url_for("admin_reports.charge_backs_reports"))

    # if upload_csv_file and not is_allowed_file(upload_csv_file):
    #     flash("Invalid file type. Only CSV files are allowed.")
    #     return redirect(url_for('admin_reports.charge_backs_reports'))

    permissionsList = check_permissions(session.get("adminId"),"chargeBacksReportPermissions")
    if "add" in permissionsList:
        try:
            # Read the file content
            file_content = upload_csv_file.read().decode('utf-8')
            
            # Use StringIO to read the string as a file object
            csvfile = StringIO(file_content)
            csvreader = csv.DictReader(csvfile)

            form = ChargeBackUploadCsvData()

            if form.validate_on_submit():
                for row in csvreader:
                    try:
                        adjustDate = parse_date(row['Adj Date'])
                        txnDate = parse_date(row['Txn Date'])
                    except ValueError as e:
                        app.logger.error(traceback.format_exc())
                        data_status['responseStatus']=4
                        return data_status

                    adjustType = row['Adj Type']
                    remitter = row['Remitter']
                    beneficiaryName = row['Benefeciary']
                    reasonCode = row['Reason Code']
                    remarks = row['Remarks']
                    
                    # Convert RRN to string to avoid scientific notation
                    rrn = str(int(float(row['RRN'].replace(',', ''))))
                    
                    try:
                        txnAmount = clean_numeric_string(row['Txn Amount'])
                        adjAmount = clean_numeric_string(row['Adj Amount'])
                    except ValueError as e:
                        app.logger.error(traceback.format_exc())
                        data_status['responseStatus']=4
                        return data_status
                    
                    payee = row['Payee']
                    upiTxnId = row['UPI TXN ID']
                    referId = row['REF ID']
                    pgOrderId = row['PgOrder ID']

                    charge_back_queryset = ChargeBacks.objects(referId=referId).first()
                    if not charge_back_queryset:
                        wallet_transaction_queryset = WalletTransactions.objects(pgOrderId=pgOrderId).first()
                        if wallet_transaction_queryset:
                            walletTransactionId = str(wallet_transaction_queryset.id)
                        else:
                            walletTransactionId = None

                        
                        # Assuming ChargeBacks is your model and it has a save method
                        create_chargeback_table = ChargeBacks(
                            userId=merchantId,
                            adjustDate=adjustDate,
                            adjustType=adjustType,
                            remitter=remitter,
                            beneficiaryName=beneficiaryName,
                            reasonCode=reasonCode,
                            remarks=remarks,
                            rrn=rrn,
                            txnAmount=txnAmount,
                            adjAmount=adjAmount,
                            txnDate=txnDate,
                            payee=payee,
                            upiTxnId=upiTxnId,
                            referId=referId,
                            pgOrderId=pgOrderId,
                            walletTransactionId=walletTransactionId,
                            createdOn=datetime.datetime.now(),
                            status=1
                        ).save()

                flash("Charge back file uploaded successfully!")
                data_status['responseStatus']=1
                return data_status
            else:
                data_status['result']=form.errors
                return data_status

            # Iterate through the CSV rows and create records
            # for row in csvreader:
            #     try:
            #         adjustDate = parse_date(row['Adj Date'])
            #         txnDate = parse_date(row['Txn Date'])
            #     except ValueError as e:
            #         app.logger.error(traceback.format_exc())
            #         return redirect(url_for("admin_reports.charge_backs_reports"))

            #     adjustType = row['Adj Type']
            #     remitter = row['Remitter']
            #     beneficiaryName = row['Benefeciary']
            #     reasonCode = row['Reason Code']
            #     remarks = row['Remarks']
                
            #     # Convert RRN to string to avoid scientific notation
            #     rrn = str(int(float(row['RRN'].replace(',', ''))))
                
            #     try:
            #         txnAmount = clean_numeric_string(row['Txn Amount'])
            #         adjAmount = clean_numeric_string(row['Adj Amount'])
            #     except ValueError as e:
            #         app.logger.error(traceback.format_exc())
            #         return redirect(url_for("admin_reports.charge_backs_reports"))
                
            #     payee = row['Payee']
            #     upiTxnId = row['UPI TXN ID']
            #     referId = row['REF ID']
            #     pgOrderId = row['PgOrder ID']

            #     charge_back_queryset = ChargeBacks.objects(referId=referId).first()
            #     if not charge_back_queryset:
            #         wallet_transaction_queryset = WalletTransactions.objects(pgOrderId=pgOrderId).first()
            #         if wallet_transaction_queryset:
            #             walletTransactionId = str(wallet_transaction_queryset.id)
            #         else:
            #             walletTransactionId = None

                    
            #         # Assuming ChargeBacks is your model and it has a save method
            #         create_chargeback_table = ChargeBacks(
            #             userId=merchantId,
            #             adjustDate=adjustDate,
            #             adjustType=adjustType,
            #             remitter=remitter,
            #             beneficiaryName=beneficiaryName,
            #             reasonCode=reasonCode,
            #             remarks=remarks,
            #             rrn=rrn,
            #             txnAmount=txnAmount,
            #             adjAmount=adjAmount,
            #             txnDate=txnDate,
            #             payee=payee,
            #             upiTxnId=upiTxnId,
            #             referId=referId,
            #             pgOrderId=pgOrderId,
            #             walletTransactionId=walletTransactionId,
            #             createdOn=datetime.datetime.now(),
            #             status=1
            #         ).save()

            # flash("Charge back file uploaded successfully!")
            # return redirect(url_for("admin_reports.charge_backs_reports"))

        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to upload csv charge back data!!"
            flash(error)
            data_status['responseStatus']=4
            return data_status
    else:
        flash("Staff member does not have given view charge back reports permissions!!")
        data_status['responseStatus']=4
        return data_status


@admin_reports.route("/usdt_transactions_reports",methods=["POST","GET"])
@adminid_access_token_required
def usdt_transactions_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    # permissionsList = check_permissions(session.get("adminId"),"payoutLedgerReportPermissions")
    # if "view" in permissionsList:
    try:
        adminId = session.get("adminId")
        usdtTransactionsList = []
        merchantsList = []

        startDate = request.args.get("startDate","")
        endDate = request.args.get("endDate","")
        merchantId = request.args.get("merchantId","")

        # Set default date format
        date_format = "%d-%m-%Y"
        pagination = None
        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

        merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
        for each_merchant in merchants_queryset:
            merchantDict = fetching_user_details(each_merchant)
            merchantsList.append(merchantDict)

        usdt_transactions_queryset = UsdtTransactions.objects(createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()

        if merchantId:
            usdt_transactions_queryset = usdt_transactions_queryset.filter(userId__in=[merchantId])

        # Get the current page from the query parameters
        page = request.args.get(get_page_parameter(), type=int, default=1)

        per_page = 20  # Number of items per page

        # Query the database for the current page's data
        total_count = usdt_transactions_queryset.count()

        start = (page - 1) * per_page

        end = min(start + per_page, total_count)

        total_usdt_transactions = usdt_transactions_queryset[start:end]
        
        snoCount = start
        for each_usdt in total_usdt_transactions:
            snoCount +=1
            usdtDict = fetching_usdt_transactions(each_usdt)
            usdtDict["snoCount"]=snoCount
            usdtTransactionsList.append(usdtDict)

        # Pagination object for rendering pagination controls in the template
        pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="usdt")

        return render_template("super_admin_templates/usdt_reports_list.html",
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            pagination=pagination,
            usdtTransactionsList=usdtTransactionsList,
            merchantsList=merchantsList,
            merchantId=merchantId,
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched usdt reports data!!"
        return render_template("super_admin_templates/usdt_reports_list.html", 
            error=error,
            pagination=pagination,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            usdtTransactionsList=usdtTransactionsList,
            merchantsList=merchantsList,
            merchantId=merchantId
            )
    # else:
    #     flash("Staff member does not have given view payout ledger reports permissions!!")
    #     return render_template("super_admin_templates/charge_backs_reports_list.html")

################################################# This code is used for CSV file upload to database records #################################################
def generate_random_name(length):
    first_letter = random.choice(string.ascii_uppercase)
    other_letters = ''.join(random.choice(string.ascii_lowercase) for _ in range(length - 1))
    return first_letter + other_letters



def generate_random_merchant_referance_string(length):
    characters = string.ascii_letters + string.digits.replace('0', '')  # Remove '0' to only include '1-9'
    random_string = ''.join(random.choice(characters) for _ in range(length))
    return random_string


def fundtransfer_parse_date(date_str):
    """
    Parse date from string in format 'DD-MM-YYYY' or as an Excel serial date.
    """
    try:
        # Try to parse as 'DD-MM-YYYY'
        parsed_date = datetime.datetime.strptime(date_str, '%d-%m-%Y %H:%M')
        return parsed_date
    except ValueError as e:
        app.logger.error(f"Failed to parse date '{date_str}' as 'DD-MM-YYYY': {e}")
        try:
            # Try to parse as Excel serial date
            excel_date = int(date_str)
            start_date = datetime.datetime(1899, 12, 30)  # Excel epoch date
            delta = datetime.timedelta(days=excel_date)
            parsed_date = start_date + delta
            return parsed_date
        except ValueError as e:
            app.logger.error(f"Failed to parse date '{date_str}' as Excel serial date: {e}")
            pass

@admin_reports.route("/upload_fundtransfer_csv_data", methods=["POST", "GET"])
@adminid_access_token_required
def upload_fundtransfer_csv_data():
    upload_csv_file = request.files.get("upload_csv_file")
    merchantsList = []

    # if not upload_csv_file or not merchantId:
    #     flash("Required fields are missing!!")
    #     return redirect(url_for("admin_reports.charge_backs_reports"))

    try:
        merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
        for each_merchant in merchants_queryset:
            merchantDict = fetching_user_details(each_merchant)
            merchantsList.append(merchantDict)

        userId = "667d13c17ebce740151a9437"

        if request.method == "GET":
            return render_template("super_admin_templates/fundtransfer_csv_upload_list.html",merchantsList=merchantsList)
        
        if request.method == "POST":

            # Read the file content
            file_content = upload_csv_file.read().decode('utf-8')
            
            # Use StringIO to read the string as a file object
            csvfile = StringIO(file_content)
            csvreader = csv.DictReader(csvfile)

            banksList=["Karur Vysya Bank Ltd","IDBI Bank Ltd","YES Bank Ltd","RBL Bank Ltd","South Indian Bank Ltd"]

            beneficiaryNameList=["Arshad Alam","jahidulali","AshokKumarGupta","sanjura","MANOJLADKYATHAKARE","VikramPancholi","sikenb","HarishKumarlaxmanbhai","RUBIDEVI","SHRIGANESHNAYAK","OmirulHoque","anil","KUSUM DEVI","Bincy Raja Sebastian","Mahjabi","Sunita","Jagdev kumar"]

            ifsccode=""
            checkType = ""
            transactionData = []

            count = 0
            # Iterate through the CSV rows and create records
            for row in csvreader:
                count = count+1
                print(count,"COUNT")
                checkType = row['Dommy']

                txnDate = fundtransfer_parse_date(row['Txn Date'])

                # transactionDateExcel = row['Txn Date']
                # transactionDate = datetime.datetime.strptime(transactionDateExcel, "%d-%m-%Y %H:%M")

                merchantPGId = "6683b2d004e5ed3dcbda059e"

                accountNumber = str(random_digit_generate(12))

                transactionUniqueId=str(random_digit_generate(16))

                userTransactionUniqueId=str(random_digit_generate(9))

                paymentModeId = "668255a485e1ca83c771159d"
                subPaymentModeId = "6682584685e1ca83c77115a0"
                patternId = "668258b585e1ca83c77115a4"
                transactionAPIId = merchantPGId

                try:
                    amount = clean_numeric_string(row['Amount'])
                    grandTotal = clean_numeric_string(row['Grand Total'])
                    openingBalance = clean_numeric_string(row['Op'])
                    closingBalance = clean_numeric_string(row['Cl'])
                except ValueError as e:
                    app.logger.error(traceback.format_exc())
                    return redirect(url_for("admin_reports.charge_backs_reports"))

                merchantReferenceNumber = str(generate_random_merchant_referance_string(16))

                # check_merchant_ref = FundTransfers.objects(merchantReferenceNumber=merchantReferenceNumber,userId=userId).first()
                # if check_merchant_ref:
                #     merchantReferenceNumber = merchantReferenceNumber+str(generate_random_merchant_referance_string(2))

                # check_transaction_exist = "ENAN10001"+str(userTransactionUniqueId)
                
                # check_transaction = FundTransfers.objects(transactionUniqueId=check_transaction_exist,userId=userId).first()
                # if check_transaction:
                #     userTransactionUniqueId = userTransactionUniqueId+str(random_digit_generate(2))

                if checkType == "New Entry":
                    beneficiaryName=random.choice(beneficiaryNameList)

                    bankName=random.choice(banksList)
                    if bankName=="Karur Vysya Bank Ltd":
                        ifsccode="KVBL0002118"
                    elif bankName=="IDBI Bank Ltd":
                        ifsccode="IBKL0000598"
                    elif bankName=="YES Bank Ltd":
                        ifsccode="YESB0MNSB01"
                    elif bankName=="RBL Bank Ltd":
                        ifsccode="RATN0000134"
                    elif bankName=="South Indian Bank Ltd":
                        ifsccode="SIBL0000028"
                    else:
                        ifsccode="IFSC0001045"


                    orderId = str(random_digit_generate(9))

                    bankReferenceNumber = str(random_digit_generate(12))

                    commissionCharges = slab_calculation_for_payout(amount,paymentModeId,subPaymentModeId,patternId,transactionAPIId)

                    if commissionCharges.get("slabId") == None:
                        slabId = None
                    else:
                        slabId = commissionCharges.get("slabId")

                    transactionData = [
                    {
                    "statusCode" : 1,
                    "message" : "Accepted.",
                    "clientOrderId" : "M00000037-"+str(merchantReferenceNumber),
                    "orderId" : "ENAN10001"+str(orderId),
                    "beneficiaryName" : beneficiaryName,
                    "utr" : "null",
                    "status" : 2,
                    "addBene" : False,
                    "amount" : str(amount)
                    }
                    ]

                    fund_transfer_table = FundTransfers(
                        userId=userId,
                        transactionAPIId=merchantPGId,
                        bankId=None,
                        bankName=bankName,
                        merchantReferenceNumber=str(merchantReferenceNumber),
                        pgOrderId='',
                        fundTransferType="instant",
                        accountType="bank",
                        apiType="api",
                        slabId=slabId,
                        transferType="Debit",
                        bankBranch="",
                        accountNumber=accountNumber,
                        accountIFSCCode=ifsccode,
                        beneficiaryName=beneficiaryName,
                        uniqueRequestNumber=None,
                        amount=float(amount),
                        grandTotal=float(grandTotal),
                        previousBalance = float(openingBalance),
                        currentBalance = float(closingBalance),
                        beneficiaryMail="test@gmail.com",
                        beneficiaryPhone="7891595413",
                        paymentMode="IMPS",
                        narration="payout",
                        createdOn=txnDate,
                        bankReferenceNumber=bankReferenceNumber,
                        userType="user",
                        transactionUniqueId="ENAN10001"+str(userTransactionUniqueId),
                        transactionData=transactionData,
                        status=1,
                        csvFileUpload="manual",
                        commissionCharges=commissionCharges
                        )
                    save_table = fund_transfer_table.save()

                elif checkType == "Duplicate":
                    duplicateFundTransferId = row['Reference Id']

                    delete_queryset = FundTransfers.objects(id=str(duplicateFundTransferId)).first()
                    if delete_queryset:
                        delete_queryset.update(status=11)

                elif checkType == "Closing Adjustment":
                    fund_transfer_adjust_table = FundTransfers(
                        userId=userId,
                        transactionAPIId=merchantPGId,
                        bankId=None,
                        bankName="",
                        merchantReferenceNumber=str(merchantReferenceNumber),
                        pgOrderId='',
                        fundTransferType="admin",
                        accountType="",
                        apiType="web",
                        slabId=None,
                        transferType="Credit",
                        bankBranch="",
                        accountNumber="",
                        accountIFSCCode="",
                        beneficiaryName="admin",
                        uniqueRequestNumber=None,
                        amount=float(amount),
                        grandTotal=float(grandTotal),
                        previousBalance = float(openingBalance),
                        currentBalance = float(closingBalance),
                        beneficiaryMail="admin@apexpay.tech",
                        beneficiaryPhone="",
                        paymentMode="wallet",
                        narration="Credit",
                        createdOn=txnDate,
                        userType="admin",
                        transactionUniqueId=transactionUniqueId,
                        transactionData=[],
                        status=1,
                        csvFileUpload="manual",
                        commissionCharges={}
                        )
                    save_table = fund_transfer_adjust_table.save()

                else:
                    updateFundTransferId = row['Reference Id']

                    commissionCharges = slab_calculation_for_payout(amount,paymentModeId,subPaymentModeId,patternId,transactionAPIId)

                    if commissionCharges.get("slabId") == None:
                        slabId = None
                    else:
                        slabId = commissionCharges.get("slabId")

                    update_fundtransfer_queryset = FundTransfers.objects(id=str(updateFundTransferId)).first()
                    if update_fundtransfer_queryset:
                        update_fundtransfer_queryset.update(
                            amount=float(amount),
                            grandTotal=float(grandTotal),
                            previousBalance=float(openingBalance),
                            currentBalance=float(closingBalance),
                            commissionCharges=commissionCharges,
                            )
                        if slabId:
                            update_fundtransfer_queryset.update(slabId=ObjectId(slabId))

            flash("Fundtransfer file uploaded successfully!")
            return render_template("super_admin_templates/fundtransfer_csv_upload_list.html")

    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to upload csv charge back data!!"
        return render_template("super_admin_templates/fundtransfer_csv_upload_list.html", error=error)



def fetch_transaction_reports_details(txn_queryset):
    txn_dict = {}
    try:
        txn_dict = {
        "id":str(txn_queryset.id),
        "userId":str(txn_queryset.userId.id),
        "userName":txn_queryset.userId.fullName,
        "txnID":txn_queryset.transactionId,
        "number":txn_queryset.mobileNumber,
        "amount":txn_queryset.amount,
        "totalAmount":txn_queryset.amount,
        "status":txn_queryset.status,
        "paymentStatus":txn_queryset.paymentStatus,
        "charge":"",
        "margin":"",
        "channel":"",
        "requestedDate":"",
        "updatedDate":"",
        }

        if txn_queryset.paymentStatus == 1:
            txn_dict["paymentStatus"] = "Success"
        elif txn_queryset.paymentStatus == 2:
            txn_dict["paymentStatus"] = "Processing"
        elif txn_queryset.paymentStatus == 0:
            txn_dict["paymentStatus"] = "Failed"
        else:
            txn_dict["paymentStatus"] = ""

        if txn_queryset.bbpsPaymentStatus == 1:
            txn_dict["bbpsPaymentStatus"] = "Success"
        elif txn_queryset.bbpsPaymentStatus == 2:
            txn_dict["bbpsPaymentStatus"] = "Processing"
        elif txn_queryset.bbpsPaymentStatus == 0:
            txn_dict["bbpsPaymentStatus"] = "Failed"
        else:
            txn_dict["bbpsPaymentStatus"] = ""
        
        if txn_queryset.refundStatus == 1:
            txn_dict["refundStatus"] = "Success"
        elif txn_queryset.refundStatus == 2:
            txn_dict["refundStatus"] = "Processing"
        elif txn_queryset.refundStatus == 0:
            txn_dict["refundStatus"] = "Refund Status"
        elif txn_queryset.refundStatus == 5:
            txn_dict["refundStatus"] = "Successful Refund"
        else:
            txn_dict["refundStatus"] = ""
        


        if txn_queryset.status == 1:
            txn_dict["status"] = "Success"
        elif txn_queryset.status == 0:
            txn_dict["status"] = "Failed"
        else:
            txn_dict["status"] = "Pending"
 
        try:
            if txn_queryset.categoryId:
                txn_dict["categoryId"] = str(txn_queryset.categoryId.id)
                txn_dict["categoryName"] = txn_queryset.categoryId.categoryName
            else:
                txn_dict["categoryId"] = ""
                txn_dict["categoryName"] = ""
        except:
            txn_dict["categoryId"] = ""
            txn_dict["categoryName"] = ""
 
        try:
            if txn_queryset.serviceId:
                txn_dict["serviceId"] = str(txn_queryset.serviceId.id)
                txn_dict["serviceName"] = txn_queryset.serviceId.serviceName
            else:
                txn_dict["serviceId"] = ""
                txn_dict["serviceName"] = ""
        except:
            txn_dict["serviceId"] = ""
            txn_dict["serviceName"] = ""
 
        try:
            if txn_queryset.operatorId:
                txn_dict["operatorId"] = str(txn_queryset.operatorId.id)
                txn_dict["operatorName"] = txn_queryset.operatorId.operatorName
            else:
                txn_dict["operatorId"] = ""
                txn_dict["operatorName"] = ""
        except:
            txn_dict["operatorId"] = ""
            txn_dict["operatorName"] = ""
 
        if txn_queryset.createdOn:
            txn_dict["createdOn"] = txn_queryset.createdOn.strftime("%d-%m-%Y %I:%M %p")
        else:
            txn_dict["createdOn"] = ""
 
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return txn_dict

@admin_reports.route("/utility_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def utility_transaction_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    status = []
    merchantsList = []
    utilityList = []
    page = ""
    total_count = ""
    per_page = ""
    snoCount = 0
    pagination = ""



    form = UtilityTransactionReport(request.args)
    permissionsList = check_permissions(session.get("adminId"),"utilityTransactionReportPermissions")
        
    if "view" in permissionsList:
        try:
            
            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            selectStatus = request.args.get("selectStatus","")
            merchantId = request.args.get("merchantId","")



            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)


            merchants_queryset = Users.objects(status__nin=[2]).only("id","phoneNumber","fullName")
            merchantsList = list(merchants_queryset)


            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20
                start = (page - 1) * per_page
                snoCount = start

                if selectStatus == "All" or selectStatus == "":
                    status = [0,1,2]
                elif selectStatus == "Success":
                    status = [1]
                elif selectStatus == "Processing":
                    status = [2]
                else:
                    status = [0]

                filters = Q(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status)
    
                    
                if merchantId:
                    filters &= Q(userId=merchantId)
        

                total_count = Transactions.objects(filters).count()

                transactions_reports_queryset = (Transactions.objects(filters)
                                                 .skip(start)
                                                 .limit(per_page)
                                                 .select_related())
                # utilityList = list(transactions_reports_queryset)
                # print(utilityList)
                for each_utility in transactions_reports_queryset:
                    snoCount +=1
                    utilityDict = fetch_transaction_reports_details(each_utility)
                    utilityDict["snoCount"]=snoCount
                    utilityList.append(utilityDict)
                snoCount = start
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")

            else:
                print("form errors", form.errors)


            # if merchantName:
            #     merchantIds = []
            #     merchants_queryset = Users.objects(fullName__icontains=merchantName)
            #     merchantIds = [str(each_merchant.id) for each_merchant in merchants_queryset]

            #     transactions_reports_queryset = transactions_reports_queryset.filter(userId__in=merchantIds)

            # if merchantId:
            #     transactions_reports_queryset = transactions_reports_queryset.filter(userId__in=[merchantId])



            # Query the database for the current page's data


            # end = min(start + per_page, total_count)

            # total_utility_transactions = transactions_reports_queryset[start:end]
            
          

            # Pagination object for rendering pagination controls in the template

            return render_template("super_admin_templates/utility_transaction_reports_list.html",
                pagination=pagination,
                utilityList=utilityList,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                selectStatus=selectStatus,
                merchantId=merchantId,
                merchantsList=merchantsList,
                form = form,
                page = page,
                snoCount = snoCount,
               
                )
        
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched payout transaction data!!"
            return render_template("super_admin_templates/utility_transaction_reports_list.html", 
                error=error,
                pagination=pagination,
                utilityList=utilityList,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                selectStatus=selectStatus,
                merchantId=merchantId,
                merchantsList=merchantsList,
                form = form,
                page = page,
                snoCount = snoCount,

                )
    else:
        flash("The staff member does not have permission to view Utility transactions report", "danger")
        return redirect(url_for("admin.dashboard"))
        

def fetching_user_settlement_details(each_payin_settlement_user):
    settlementDict = {}
    try:
        settlementDict = {
        "id":str(each_payin_settlement_user.id),
        "merchantId":str(each_payin_settlement_user.userId.id),
        "merchantName":each_payin_settlement_user.userId.fullName,
        "amount":"8"
        }
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return settlementDict


# def get_yesterday_datetime(noOfminutes):
#     target_time = ""
#     try:
#         # Get the current date and time
#         now = datetime.datetime.now()
#         print(now,"(((((((((NOW TIME)))))))))")
#         # Subtract one day to get yesterday's date and time
#         yesterday = now - timedelta(days=1)

#         # Subtract the specified minutes from the current time
#         target_time = yesterday - timedelta(minutes=int(noOfminutes))
#         return target_time
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#     return target_time

def get_yesterday_datetime(noOfminutes):
    target_time = ""
    try:
        # Convert the input minutes into hours and minutes
        hours = int(noOfminutes) // 60
        minutes = int(noOfminutes) % 60
        
        # Get the current date and time
        now = datetime.datetime.now()

        # Get yesterday's date at the specified time
        yesterday = now - timedelta(days=1)
        target_time = datetime.datetime(yesterday.year, yesterday.month, yesterday.day, hours, minutes)
        return target_time
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return target_time

# from flask_wtf import FlaskForm
# from wtforms.validators import DataRequired, Optional, ValidationError

# class PayinSettlementSearchForm(FlaskForm):
#     startDate = StringField('',validators=[ Optional(), Regexp(r"^\d{2}-\d{2}-\d{4}( \d{2}:\d{2})?$", message="Date must be in DD-MM-YYYY format")])
#     endDate = StringField('', validators=[ Optional(), Regexp( r"^\d{2}-\d{2}-\d{4}( \d{2}:\d{2})?$", message="Date must be in DD-MM-YYYY format")]) #  date and time format 
#     paymentGatewayId = SelectField('', choices=[],validate_choice=False,validators=[Optional()]) 

#     def validate_paymentGatewayId(self, field):
#         if field.data:
#             if not ObjectId.is_valid(field.data):
#                 raise ValidationError("Invalid PG Id.")
#             pg_queryset = TransactionAPI.objects(id=field.data,status=1,transactionType="PaymentGateway").first()
#             if not pg_queryset:
#                 raise ValidationError("Please select a valid PG Id.")

@admin_reports.route("/payin_settlement",methods=["POST","GET"])
@adminid_access_token_required
def payin_settlement():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    
    csrf_token = request.form.get("csrf_token")
    
    payinSettlementMerchantsList = []
    error=""
    permissionsList = check_permissions(session.get("adminId"),"settlementPermissions")
    form = PayinSettlementSearchForm(request.form)
    if "view" in permissionsList:
        try:
            adminId = session.get("adminId")
            startDate = request.form.get("startDate","")
            endDate = request.form.get("endDate","")
            paymentGatewayId = request.form.get("paymentGatewayId","")
            settlementTime = request.form.get("settlementTime","")
            paymentgateway_queryset = TransactionAPI.objects(status=1,transactionType="PaymentGateway").order_by("id")
            # date_format = "%d-%m-%Y %H:%M"
            total_amount = 0
            date_format = "%d-%m-%Y"
            pagination = None
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            

            if request.method == "GET":
                return render_template("super_admin_templates/payin_settlement_list.html",
                    payinSettlementMerchantsList=payinSettlementMerchantsList,
                    error=error,
                    total_amount=total_amount,
                    startDate=startDate.strftime(date_format),
                    endDate=endDate.strftime(date_format),
                    paymentGatewayId=str(paymentGatewayId),
                    paymentgatewayList=paymentgateway_queryset,
                    form=form
                    )

            if request.method == "POST":
                action = request.form.get("action", "").strip()
                data = request.form.to_dict()
                
                # otp_check_id = request.form.get("otpCheckId", "")

                # otpcheck_queryset = OtpChecks.objects(adminId=adminId, id=str(otp_check_id), status=1).first()
                
                # if not otpcheck_queryset:
                # 	return jsonify({"responseStatus": 0, "result": "Invalid Request."})
                # # Update OTP status to 2 after verification
                # otpcheck_queryset.update(status=2)

                    # if not otp_record:
                    #     return jsonify({"responseStatus": 0, "result": "OTP not verified. Please verify OTP first!"})
                if form.validate_on_submit():
                    if startDate=="" or endDate=="" or paymentGatewayId=="":
                        error = "Required Fields are missing."
                        return render_template("super_admin_templates/payin_settlement_list.html", 
                            error=error,
                            payinSettlementMerchantsList=payinSettlementMerchantsList,
                            startDate=startDate.strftime("%d-%m-%Y"),
                            total_amount=total_amount,
                            endDate=endDate.strftime("%d-%m-%Y"),
                            paymentGatewayId="",
                            paymentgatewayList=paymentgateway_queryset,
                            form=form
                            # yesterday_datetime=yesterday_datetime
                            )
                    # print("required false1")
                    # print("Starttimetype",type(datetime.datetime.strptime(startDate, date_format)))
                    # print("Starttime",datetime.datetime.strptime(startDate, date_format))
                    # print("endtime",datetime.datetime.strptime(endDate, date_format))
                    # print("endtimetype",type(datetime.datetime.strptime(endDate, date_format)))
                    pipeline = [
                        {"$lookup": {
                            "from": "users",
                            "localField": "userId",
                            "foreignField": "_id",
                            "as": "userDetails"
                        }},
                        {"$match": {
                            "creditType": "Credit",
                            "status": 1,
                            "settlementStatus": 1,
                            "paymentGatewayId":ObjectId(paymentGatewayId),
                            "userType":"user",
                            "createdOn": {
                                "$gte": startDate,
                                "$lte": endDate
                            }
                        }},
                        {"$unwind": "$userDetails"},
                        {"$group": {"_id": {"userId": "$userId"},"totalAmount": {"$sum": "$grandTotal"}}},
                        {"$sort": {"totalAmount": -1}}
                    ]
                    # Execute the aggregation pipeline
                    payins_settlement_merchants = list(WalletTransactions.objects.aggregate(*pipeline))
                    print(payins_settlement_merchants,"**********payins_settlement_merchants***********")
                    print(len(payins_settlement_merchants),"**********payins_settlement_merchants Length***********")

                    total_amount = payins_settlement_merchants[0]["totalAmount"] if payins_settlement_merchants else 0.0


                    payinSettlementMerchantsList = []
                    totalSettlementAmount = 0
                    get_paymentgateway_queryset = TransactionAPI.objects(id=str(paymentGatewayId)).first()
                    for each_merchant in payins_settlement_merchants:
                        merchant_queryset = Users.objects(id=each_merchant.get("_id").get("userId"),status=1).first()
                        if not merchant_queryset:
                            continue
                        totalSettlementAmount += float(each_merchant.get("totalAmount"))
                        settlementDict = {
                        "merchantId":str(merchant_queryset.id),
                        "merchantName":merchant_queryset.fullName,
                        "phoneNumber":merchant_queryset.phoneNumber,
                        "paymentGatewayName":get_paymentgateway_queryset.apiName,
                        "totalMerchantAmount":formatINR("{:.2f}".format(float(each_merchant.get("totalAmount"))))
                        }
                        payinSettlementMerchantsList.append(settlementDict)
                    
                    print("(((((((((((((payinSettlementMerchantsList)))))))))))))",payinSettlementMerchantsList)
                    return render_template("super_admin_templates/payin_settlement_list.html",
                    payinSettlementMerchantsList=payinSettlementMerchantsList,
                    total_amount=formatINR("{:.2f}".format(float(total_amount))),
                    error=error,
                    startDate=startDate.strftime("%d-%m-%Y"),
                    paymentGatewayId=ObjectId(paymentGatewayId),
                    endDate=endDate.strftime("%d-%m-%Y"),
                    paymentgatewayList=paymentgateway_queryset,
                    form=form
                    # yesterday_datetime=yesterday_datetime
                    )
                else:
                    print("payin_settlement form errros", form.errors )
                return render_template("super_admin_templates/payin_settlement_list.html",
                    payinSettlementMerchantsList=payinSettlementMerchantsList,
                    total_amount=formatINR("{:.2f}".format(float(total_amount))),
                    error=error,
                    startDate=startDate.strftime("%d-%m-%Y"),
                    endDate=endDate.strftime("%d-%m-%Y"),
                    paymentgatewayList=paymentgateway_queryset,
                    form=form
                    # yesterday_datetime=yesterday_datetime
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched settlement data!!"
            return render_template("super_admin_templates/payin_settlement_list.html", 
                error=error,
                total_amount=round(total_amount,2),
                payinSettlementMerchantsList=payinSettlementMerchantsList,
                startDate=startDate.strftime("%d-%m-%Y"),
                endDate=endDate.strftime("%d-%m-%Y"),
                paymentGatewayId=str(paymentGatewayId),
                paymentgatewayList=paymentgateway_queryset,
                form=form
                # yesterday_datetime=yesterday_datetime
                )
    else:
        flash("The staff member does not have permission to view settlement.", "danger")
        return redirect(url_for("admin.dashboard"))
        




@admin_reports.route("/payin_merchant_settlement",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def payin_merchant_settlement():
    data_status={"responseStatus":0,"result":""}
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")

    latitude = request.form.get("latitude", "")
    longitude = request.form.get("longitude", "")
    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    client_ip=0
    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"): 
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    actionDate=datetime.datetime.now()
    
    date_format = "%d-%m-%Y"
    payinSettlementMerchantsList = []
    form = SettlementForm()
    try:
        adminId = session.get("adminId")

        # yesterday_datetime = datetime.datetime.now()
        settlement_endDate = request.form.get("settlement_endDate")
        settlement_startDate = request.form.get("settlement_startDate")
        settlementedRemark = request.form.get("settlementedRemark")
        merchantIdList = request.form.getlist("merchantId[]")
        payInPaymentGatewayId = request.form.get("settlement_paymentGatewayId")
        paymentGatewayName = request.form.getlist("paymentGatewayName")
        indexval=0
        jsonData = request.form.to_dict(flat=True)
        requestData = [jsonData]
        updatedrequestData = [jsonData]
        try:
            if settlement_startDate:
                settlement_startDate = datetime.datetime.strptime(settlement_startDate, date_format)
            else:
                settlement_startDate =""
        except Exception as ve:
            app.logger.error(traceback.format_exc())
            settlement_startDate = ""

        try:
            if settlement_endDate:
                settlement_endDate = datetime.datetime.strptime(settlement_endDate, date_format)
            else:
                settlement_endDate =""

        except Exception as ve:
            app.logger.error(traceback.format_exc())
            settlement_endDate = ""

        # if not settlement_endDate and not settlement_startDate and not payInPaymentGatewayId and not merchantIdList :
        # 	flash("Invalid request!!")

        # 	return redirect(url_for("admin_reports.payin_settlement"))

        if form.validate_on_submit():
            for each_merchant in merchantIdList:
                userId=each_merchant
                payins_settlement_merchant = WalletTransactions.objects(creditType="Credit",status=1,settlementStatus=1,paymentGatewayId=payInPaymentGatewayId,userType="user",createdOn__gte=settlement_startDate,createdOn__lte=settlement_endDate,userId=userId)

                grandtotal=0
                if payins_settlement_merchant:
                    grandtotal=payins_settlement_merchant.sum('grandTotal')
                if float(grandtotal)<=0:
                    continue
                merchant_queryset = Users.objects(id=userId,status=1).first()
                admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
                if admin_queryset:
                    message=admin_queryset.userName+" "+merchant_queryset.fullName+" Merchant payin settlement successfully!!"
                    save_admin_log_table = save_admin_logs_data(adminId,None,None,"payin_merchant_settlement","create",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude) 
                if not merchant_queryset.patternId.payoutPaymentGatewayId:
                    print("Merchant PAYOUT PG")
                    continue
                amount = round(float(grandtotal),2)
                patternId = str(merchant_queryset.patternId.id)
                siteTitle = str(merchant_queryset.siteTitle)
                payOutPaymentGatewayId = str(merchant_queryset.patternId.payoutPaymentGatewayId.id)


                check_wallet_balance = round(float(merchant_queryset.walletBalance),2)

                if check_wallet_balance < amount:
                    continue

                # Settlement Functionality For Payin
                balanceResult=user_payin_balance_update(userId,amount,"Debit",payInPaymentGatewayId)
                
                if settlementedRemark and not is_valid_alphanumeric(settlementedRemark):
                    flash("settlementedRemark must contain only alphanumeric characters, spaces, and specific special characters: @#$()+_-/")
                    return redirect(url_for("admin_reports.payin_merchant_settlement"))
                
                if balanceResult.get('responseStatus')==0:
                    continue

                stringAmount = formatINR("{:.2f}".format(float(amount)))
                orderId = random_digit_generate(15)
                transactionUniqueId = random_digit_generate(15)
                commenttext="settlement amount "+stringAmount+" added for "+str(paymentGatewayName)+" payment gateway from "+str(settlement_startDate)+" to " +str(settlement_endDate)
                
                try:
                    get_paymentgateway_queryset = TransactionAPI.objects(id=payInPaymentGatewayId,status=1).first()
                    if get_paymentgateway_queryset:
                        apiName = get_paymentgateway_queryset.apiName
                    else:
                        apiName = ""
                    admin_queryset = SuperAdmin.objects(id=adminId,status=1).first()
                    merchant_queryset = Users.objects(id=userId,status=1).first()
                    

                    sender_mail_query = SenderMails.objects(status=1,mailType="Settlement Mail").first()
                    sendermailsList = sender_mail_query.mailsList
                    mail_subject = "Settlement"
                    recipients_list = sendermailsList # Replace 'email' with the recipient's email
                    template_name = "emails/payin_settlement_mail.html"
                    createdOn = datetime.datetime.now().astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p")
                    merchantUniqueNumber=str(merchant_queryset.merchantUniqueNumber)
                    mid_extracted = merchantUniqueNumber[1:].lstrip("0")
                    pgOrderId=str(transaction_id_prefix)+str(mid_extracted)+str(orderId)
                    # Prepare the mail data with today's totals
                    mail_data = {
                        "adminName":admin_queryset.userName,
                        "merchantName":merchant_queryset.fullName,
                        "startDate": settlement_startDate,
                        "endDate": settlement_endDate,
                        "paymentGatewayName":apiName,
                        "total_amount":amount,
                        "settlementedRemark":settlementedRemark
                    }
                    send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                    print(mail_data, "((((((((((mail_data))))))))))")
                except Exception as e:
                    app.logger.error(traceback.format_exc())
                    pass 

                payinbalancelogs_queryset=PayinBalanceLogs(
                    transactionAPIId=str(payInPaymentGatewayId),
                    userId=str(userId),
                    previousBalance=balanceResult.get('transactionPreviousBalance'),
                    currentBalance=balanceResult.get('transactionCurrentBalance'),
                    orderId=orderId,
                    amount=round(float(amount),2),
                    grandTotal=round(float(amount),2),
                    transferType="Debit",
                    userType="admin",
                    transactionId=transactionUniqueId,
                    createdOn=datetime.datetime.now(),
                    status=1
                    ).save()

                wallet_credit_table = WalletTransactions(
                    createdBy=adminId,
                    userId = str(userId),
                    amount = round(float(amount),2),
                    grandTotal = round(float(amount),2),
                    patternId = patternId,
                    creditType = "Debit",
                    userType = "admin",
                    comment = commenttext,
                    transactionId = transactionUniqueId,
                    paymentGatewayId = str(payInPaymentGatewayId),
                    paymentType = "wallet",
                    createdOn = datetime.datetime.now(),
                    previousBalance=balanceResult.get('userPreviousBalance'),
                    currentBalance=balanceResult.get('userCurrentBalance'),
                    remarks = "",
                    orderId = orderId,
                    customerName = merchant_queryset.fullName,
                    customerEmail = merchant_queryset.email,
                    customerPhonenumber = merchant_queryset.phoneNumber,
                    agent = "",
                    location = "",
                    platform = "",
                    paymentLink = "",
                    errorMessage = "settlement done for "+str(paymentGatewayName)+" payment gateway from "+str(settlement_startDate)+" to " +str(settlement_endDate),
                    paymentChannel = str(paymentGatewayName),
                    bankRefId = "",
                    cardmasked = "",
                    customerVpa = "",
                    siteTitle = siteTitle,
                    pgOrderId = pgOrderId,
                    commissionCharges = {},
                    status = 1
                    )
                save_table = wallet_credit_table.save()

                # settlementStatus_queryset = WalletTransactions.objects(paymentGatewayId = str(payInPaymentGatewayId),userId=str(userId),settlementStatus=1).first()
                # if not settlementStatus_queryset:
                #   continue
                
                payins_settlement_merchant.update(settlementStatus=2,settlementedBy=ObjectId(adminId),settlementedTime=datetime.datetime.now(),settlementedRemark=settlementedRemark)

                # Settlement Functionality For Payout
                # balanceResult=user_payout_balance_update(str(userId),float(amount),"Credit",str(payOutPaymentGatewayId))

                userbalance_queryset = Users.objects(id=str(userId)).modify(inc__payoutBalance=float(amount),new=True)
                userCurrentBalance = userbalance_queryset.payoutBalance
                userPreviousBalance = float(userCurrentBalance)-float(amount)
                # if balanceResult.get('responseStatus')==0:
                #     flash("Unable to connect with server. Please Try again.")
                #     return redirect(url_for("admin_reports.payin_settlement"))

                fund_transfer_table = FundTransfers(
                    createdBy=adminId,
                    userId = userId,
                    amount = round(float(amount),2),
                    grandTotal = round(float(amount),2),
                    transactionAPIId = payOutPaymentGatewayId,
                    transferType = "Credit",
                    userType = "admin",
                    narration = commenttext,
                    transactionUniqueId = transactionUniqueId,
                    createdOn = datetime.datetime.now(),
                    previousBalance=float(userPreviousBalance),
                    currentBalance=float(userCurrentBalance),
                    uniqueRequestNumber = "",
                    beneficiaryName = merchant_queryset.fullName,
                    beneficiaryMail = merchant_queryset.email,
                    beneficiaryPhone = "",
                    accountIFSCCode = "",
                    fundTransferType = "admin",
                    accountType = "",
                    accountNumber = "",
                    paymentMode = "wallet",
                    bankBranch = "",
                    bankName = "",
                    errorMessage = commenttext,
                    internalId = "",
                    pgOrderId = pgOrderId,
                    siteTitle = siteTitle,
                    apiType = "web",
                    merchantReferenceNumber = orderId,
                    commissionCharges = {},
                    status = 1
                    )
                save_table = fund_transfer_table.save()
                    
                # payoutbalancelog_queryset=PayoutBalanceLogs(
                #     userId =str(userId),
                #     transactionAPIId =str(payOutPaymentGatewayId),
                #     previousBalance = round(float(balanceResult.get('transactionPreviousBalance')),2),
                #     currentBalance = round(float(balanceResult.get('transactionCurrentBalance')),2),
                #     amount=round(float(amount),2),
                #     grandTotal=round(float(amount),2),
                #     orderId=orderId,
                #     transferType = "Credit",
                #     userType = "admin",
                #     transactionId = transactionUniqueId,
                #     createdOn = datetime.datetime.now(),
                #     status = 1
                #     ).save()
            flash("Merchant payin settlement successfully!!")
            data_status['responseStatus']=1
            return data_status
        else:
            print("payinfjgjhgfjhvhj_settlement form errros", form.errors )
            data_status['result']=form.errors
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to settlement merchant!!"
        data_status['responseStatus']=4
        return data_status



@admin_reports.route("/commission_reports_list",methods=["POST","GET"])
@adminid_access_token_required
def commission_reports_list():
    snoCount=0
    pagination=None
    commissionsList=[]
    merchantsList=[]
    merchantId=""
    
    form=CommissionSearchForm(request.args)
    permissionsList = check_permissions(session.get("adminId"),"commissionReportsPermissions")
    if "view" in permissionsList:
        try:
            if not session.get("adminId"):
                return redirect("admin_login")
            adminId = session.get("adminId")
            
            commissionsList = []
            merchantsList = []

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            merchantId = request.args.get("merchantId","")

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            if form.validate():
                # Get the current page from the query parameters
                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName").order_by("-createdOn")
                # for each_merchant in merchants_queryset:
                #     merchantDict = fetching_user_details(each_merchant)
                #     merchantsList.append(merchantDict)
                merchantsList = list(merchants_queryset)


                # if orderId:
                #   commission_transactions_queryset = commission_transactions_queryset.filter(merchantReferenceNumber=orderId)
                query = Q(createdOn__gte=startDate,createdOn__lte=endDate)
                if merchantId:
                    # commission_transactions_queryset = commission_transactions_queryset.filter(userId__in=[merchantId])
                    query  &= Q(userId__in=[merchantId])

                # commission_transactions_queryset = UserCommissions.objects(createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()
                commission_transactions_queryset = UserCommissions.objects(query).order_by("-createdOn").limit(per_page).skip(start)

                # Query the database for the current page's data
                total_count = UserCommissions.objects(query).count()
                

                # for each_commission in commission_transactions_queryset:
                #     snoCount +=1
                #     commissionDict = fetching_commission_transaction_details(each_commission)
                #     commissionDict["snoCount"]=snoCount
                #     commissionsList.append(commissionDict)
                commissionsList=list(commission_transactions_queryset)

                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="commissions")

            return render_template("super_admin_templates/commission_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                pagination=pagination,
                commissionsList=commissionsList,
                merchantsList=merchantsList,
                merchantId=merchantId,
                snoCount=snoCount,
                form=form
                )
            
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetched commissions settlement report data!!"
            return render_template("super_admin_templates/commission_reports_list.html", 
                error=error,
                pagination=pagination,
                commissionsList=commissionsList,
                merchantsList=merchantsList,
                merchantId=merchantId,
                snoCount=snoCount,
                form=form
                )
    else:
        flash("The staff member does not have permission to view Commissions settlement reports.", "danger")
        return redirect(url_for("admin.dashboard"))
       

@admin_reports.route("/admin_download_payin_settlement_csv_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_payin_settlement_csv_reports():
    data_status={"responseStatus":0,"result":""}
    startDate = request.args.get("startDate","")
    endDate = request.args.get("endDate","")
    orderId = request.args.get("orderId","")
    merchantId = request.args.get("merchantId","")
    # print("orderId",orderId,"getttt",request.args.get("orderId",""))
    try:
        # Set default date format
        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

        # merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
        # for each_merchant in merchants_queryset:
        #   merchantDict = fetching_user_details(each_merchant)
        #   merchantsList.append(merchantDict)

        query = Q(createdOn__gte=startDate,createdOn__lte=endDate)

        if orderId:
            query &= Q(orderId=orderId)

        if merchantId:
            query &= Q(userId__in=[merchantId])
       
        payins_queryset = WalletTransactions.objects(query).order_by("-createdOn")
        

        reportData = admin_download_payin_settlement_csv_reports_data(startDate,endDate,payins_queryset)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download success payin report data!!"
        return data_status

############################################ COMMISSION SETTLEMENT TABS CODE HERE START ############################################################################
@admin_reports.route("/commission_settlements",methods=["POST","GET"])
@adminid_access_token_required
def commission_settlements():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        redirectTo = request.args.get("redirectTo","UnsettlementCommission")
        if redirectTo:
            redirectval = redirectTo
        else:
            redirectval = "UnsettlementCommission"
        commissionsList = []
        merchantsList = []
        pagination = None
        startMonthYear = None
        selectYear = None
        selectMonth = None
        current_year = None
        last_year = None
        tdsChargePer=0
        tdsLimitAmount=0
        form = CommissionSettleSearchForm(request.args)
        permissionsList = check_permissions(session.get("adminId"),"unSettlementCommissionPermissions")
        if "view" in permissionsList:
            if form.validate():
                selectYear = request.args.get("selectYear", default=str(datetime.datetime.now().year))
                selectMonth = request.args.get("selectMonth", default=datetime.datetime.now().strftime("%B"))
                gstValue = request.form.get("gstValue",0)
                tdsValue = request.form.get("tdsValue",0)

                print(selectYear,"(((((((((selectYear)))))))))")
                print(selectMonth,"(((((((((selectMonth)))))))))")

                tdsStartDate, tdsEndDate  = get_financial_year_dates(selectMonth, int(selectYear))
                # print(merchantId,"(((((((((merchantId)))))))))")
                # print(gstValue,"(((((((((gstValue)))))))))")
                # print(type(gstValue),"((((((((( TYpe gstValue)))))))))")
                # print(tdsValue,"(((((((((tdsValue)))))))))")

                print(tdsEndDate,"(((((((((tdsEndDate)))))))))")
                print(tdsStartDate,"(((((((((tdsStartDate)))))))))")


                # Get the month number from the month name
                month_number = datetime.datetime.strptime(selectMonth, "%B").month

                current_year = datetime.datetime.now().year
                last_year = current_year - 1

                # print(current_year,"((((((current_year))))))")
                # print(last_year,"((((((last_year))))))")
                # print(month_number,"((((((Month Number))))))")

                # Construct startMonthYear and endMonthYear
                startMonthYear = datetime.datetime(int(selectYear), month_number, 1)
                endMonthYear = datetime.datetime(int(selectYear), month_number, monthrange(int(selectYear), month_number)[1])

                # print(startMonthYear,"((((((((((startMonthYear))))))))))")
                # print(endMonthYear,"((((((((((endMonthYear))))))))))")

                if startMonthYear and endMonthYear:
                    startMonthYear = startMonthYear.replace(hour=0, minute=0, second=0, microsecond=0)
                    endMonthYear = endMonthYear.replace(hour=23, minute=59, second=59, microsecond=999999)

                    # print(startMonthYear,"((((((((((startMonthYear With TIme))))))))))")
                    # print(endMonthYear,"((((((((((endMonthYear With TIme))))))))))")


                # check_generated_queryset = GeneratedCommissions.objects(year=selectYear,month=month_number).order_by("-id")
                # listOfCheckGeneratedUserIds = [ObjectId(each_generated_id.userId.id) for each_generated_id in check_generated_queryset]
                # print(listOfCheckGeneratedUserIds,"(((((((((((listOfCheckGeneratedUserIds)))))))))))")


                pipeline = [
                    {
                        "$lookup": {
                            "from": "users",
                            "localField": "userId",
                            "foreignField": "_id",
                            "as": "userDetails"
                        }
                    },
                    {
                        "$match": {
                            "createdOn": {
                                "$gte": startMonthYear,
                                "$lte": endMonthYear
                            },
                            "settlementStatus": 1
                        }
                    },
                    {
                        "$unwind": "$userDetails"
                    },
                    {
                        "$group": {
                            "_id": {"userId": "$userId"},
                            "totalUserParentCommissionAmount": {"$sum": "$parrentCommissionAmount"},
                            "totalUserParentGstAmount": {"$sum": "$parrentGstAmount"},
                            "totalUserParentGstAmount": {"$sum": "$parrentGstAmount"},
                            "totalUserParentTdsAmount": {"$sum": "$parrentTdsAmount"},
                            "usertotalAmount": {"$sum": "$totalAmount"}
                        }
                    }
                ]


                # Execute the aggregation pipeline
                merchant_wise_commission_transactions = list(UserCommissions.objects.aggregate(*pipeline))
                # print(merchant_wise_commission_transactions, "**********merchant_wise_commission_transactions***********")

                # Get the current page from the query parameters
                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page

                # Get total count and slice the list for pagination
                total_count = len(merchant_wise_commission_transactions)

                start = (page - 1) * per_page
                end = min(start + per_page, total_count)

                # Slice the list for the current page
                total_commissions = merchant_wise_commission_transactions[start:end]

                commission_tds_setup_queryset = CommissionTdsSetup.objects(status=1).first()
                if commission_tds_setup_queryset:
                    tdsLimitAmount = commission_tds_setup_queryset.tdsLimitAmount
                    tdsChargePercent = commission_tds_setup_queryset.tdsChargePer
                else:
                    flash("No Commission TDS charges are set")
                    

                snoCount = start
                for each_commission in total_commissions:
                    tdsValue=0
                    tdsTotal=0
                    netCommissionAmount=0
                    diffCommissionAmount=0
                    temp_end_date = tdsEndDate
                    # print(each_commission, "(((((((((((each_commission)))))))))))")
                    
                    netCommissionAmount = float(each_commission.get("totalUserParentCommissionAmount"))
                    totalUserParentGstAmount = float(each_commission.get("totalUserParentGstAmount"))
                    totalUserParentTdsAmount = float(each_commission.get("totalUserParentTdsAmount"))
                    usertotalAmount = float(each_commission.get("usertotalAmount"))
                    CommissionAmount=netCommissionAmount
                    # netCommissionAmount = float(totalUserParentGstAmount+totalUserParentTdsAmount+netCommissionAmount)
                    # print(netCommissionAmount,"netCommissionAmount")
                    # print(gstAmount,"gstAmount")
                    # print(tdsAmount,"tdsAmount")
                    # print(commissionAmount,"commissionAmount")tdsStartDate, tdsEndDate

                    commission_transaction_queryset = UserCommissions.objects(userId=each_commission.get("_id").get("userId")).first()
                    totalOverallCommission = UserCommissions.objects(userId=each_commission.get("_id").get("userId"),createdOn__gte=tdsStartDate,createdOn__lte=tdsEndDate).sum("parrentCommissionAmount")

                    # print("totalOverallCommission >= tdsLimitAmount", totalOverallCommission >= tdsLimitAmount, totalOverallCommission, tdsLimitAmount)
                    
                    if totalOverallCommission >= tdsLimitAmount:
                        ### to check if it crosssed this month or prev month change date to 1 month before
                        if temp_end_date.month !=4:
                            temp_end_date = temp_end_date - relativedelta(months=1)
                            totalOverallCommissionPreviousMonth = UserCommissions.objects(userId=each_commission.get("_id").get("userId"),createdOn__gte=tdsStartDate,createdOn__lte=temp_end_date).sum("parrentCommissionAmount")
                            ###### if it crossed prev month only cal tds for current month diff
                            if totalOverallCommissionPreviousMonth >= tdsLimitAmount:
                                print("prev month tds eligible for ",commission_transaction_queryset.userId.fullName)
                                tdsValue = tdsChargePercent
                                diffCommissionAmount = totalOverallCommission - totalOverallCommissionPreviousMonth
                                tdsTotal = round(float((netCommissionAmount / 100) * tdsChargePercent),2) ### tds amount calculated
                                CommissionAmount = netCommissionAmount -   tdsTotal #### doubt
                            else:
                                print("curr month tds eligible for ",commission_transaction_queryset.userId.fullName)
                                tdsValue = tdsChargePercent
                                tdsTotal = round(float((totalOverallCommission / 100) * tdsChargePercent),2)   ### tds amount calculated 
                                CommissionAmount = netCommissionAmount -   tdsTotal

                    commissionDict = {
                        "id": str(commission_transaction_queryset.id),
                        "merchantId": str(commission_transaction_queryset.userId.id),
                        "merchantName": commission_transaction_queryset.userId.fullName,
                        "merchantType": commission_transaction_queryset.userId.merchantType,
                        "totalAmount": round(usertotalAmount,2),
                        "totalUserParentCommissionAmount": round(netCommissionAmount,2),
                        "commissionAmount": round(CommissionAmount,2),
                        "totalOverallCommission": round(totalOverallCommission,2),
                        "tdsValue": round(tdsValue,2),
                        "tdsTotal": round(tdsTotal,2)
                    }
                    commissionsList.append(commissionDict)

                # print(commissionsList,"((((((commissionsList))))))")


                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="commissions")

                return render_template("super_admin_templates/commission_settlements_new.html",
                    selectYear=selectYear,
                    selectMonth=selectMonth,
                    startMonthYear=startMonthYear,
                    endMonthYear=endMonthYear,
                    current_year=current_year,
                    last_year=last_year,
                    pagination=pagination,
                    commissionsList=commissionsList,
                    redirectval=redirectval,
                    form=form
                    )
            print("form error",form.errors)
        else:
            flash("The staff member does not have permission to view Commissions settlement reports.", "danger")
            return redirect(url_for("admin.dashboard"))
            
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched commissions settlement report data!!"
        return render_template("super_admin_templates/commission_settlements_new.html", 
            error=error,
            pagination=pagination,
            selectYear=selectYear,
            selectMonth=selectMonth,
            current_year=current_year,
            last_year=last_year,
            startMonthYear=startMonthYear,
            endMonthYear=endMonthYear,
            commissionsList=commissionsList,
            redirectval=redirectval,
            form=form
            )


@admin_reports.route("/generate_new_commission",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def generate_new_commission():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    
    try:
        netCommissionAmount = 0
        totalTxnAmount = 0
        merchantIdList = request.form.getlist("merchantIds")
        # gstValuesList = request.form.getlist("gstValue")
        # tdsValueList = request.form.getlist("tdsValue")
        tdsChargePercent=0
        tdsLimitAmount=0

        # print(gstValuesList,"gstValuesList")
        # print(tdsValueList,"tdsValueList")
        print(merchantIdList,"merchantIdList")

        selectYear = request.form.get("selectYear")
        selectMonth = request.form.get("selectMonth")

        tdsStartDate, tdsEndDate  = get_financial_year_dates(selectMonth, int(selectYear))

        print(selectYear,"(((((((selectYear)))))))")
        print(selectMonth,"(((((((selectMonth)))))))")
        # Get the month number from the month name
        month_number = datetime.datetime.strptime(selectMonth, "%B").month
        print(month_number,"(((((((month_number)))))))")

        startDateMonth = datetime.datetime(int(selectYear), month_number, 1)
        endDateMonth = datetime.datetime(int(selectYear), month_number, monthrange(int(selectYear), month_number)[1])

        if startDateMonth and endDateMonth:
            startDateMonth = startDateMonth.replace(hour=0, minute=0, second=0, microsecond=0)
            endDateMonth = endDateMonth.replace(hour=23, minute=59, second=59, microsecond=999999)

            print(startDateMonth,"(((((((startDateMonth)))))))")
            print(endDateMonth,"(((((((endDateMonth)))))))")
        commission_tds_setup_queryset = CommissionTdsSetup.objects(status=1).first()
        if commission_tds_setup_queryset:
            tdsLimitAmount = commission_tds_setup_queryset.tdsLimitAmount
            tdsChargePercent = commission_tds_setup_queryset.tdsChargePer
            
        for each_merchant in merchantIdList:
            merchantids = each_merchant.split("-")
            print(merchantids,"merchantids")
            merchantid = merchantids[0]
            indexvalue=int(merchantids[1])-1
            # gstValue=gstValuesList[indexvalue]
            # tdsValue=tdsValueList[indexvalue]
            # print(gstValue,"gstValue")
            # print(tdsValue,"tdsValue")
            tdsValue=0
            tdsTotal=0
            netCommissionAmount=0
            diffCommissionAmount=0
            temp_end_date = tdsEndDate
                
            user_commissions_queryset = UserCommissions.objects(userId=str(merchantid),createdOn__gte=startDateMonth,createdOn__lte=endDateMonth,settlementStatus=1).order_by("-id")
            netCommissionAmount = user_commissions_queryset.sum("parrentCommissionAmount")
            totalTxnAmount = user_commissions_queryset.sum("totalAmount")
            CommissionAmount=netCommissionAmount
            totalOverallCommission = UserCommissions.objects(userId=str(merchantid),createdOn__gte=tdsStartDate,createdOn__lte=tdsEndDate).sum("parrentCommissionAmount")


            if totalOverallCommission >= tdsLimitAmount:
                ### to check if it crosssed this month or prev month change date to 1 month before
                if temp_end_date.month !=4:
                    temp_end_date = temp_end_date - relativedelta(months=1)
                    totalOverallCommissionPreviousMonth = UserCommissions.objects(userId=str(merchantid),createdOn__gte=tdsStartDate,createdOn__lte=temp_end_date).sum("parrentCommissionAmount")
                    ###### if it crossed prev month only cal tds for current month diff
                    if totalOverallCommissionPreviousMonth >= tdsLimitAmount:
                        tdsValue = tdsChargePercent
                        diffCommissionAmount = totalOverallCommission - totalOverallCommissionPreviousMonth
                        tdsTotal = round(float((netCommissionAmount / 100) * tdsChargePercent),2) ### tds amount calculated
                        CommissionAmount = netCommissionAmount -   tdsTotal #### doubt
                    else:
                        tdsValue = tdsChargePercent
                        tdsTotal = round(float((totalOverallCommission / 100) * tdsChargePercent),2)   ### tds amount calculated 
                        CommissionAmount = netCommissionAmount -   tdsTotal


            user_commissions_queryset.update(settlementStatus=2)

            # gstAmount = netCommissionAmount*(int(gstValue)/100)
            # tdsAmount = netCommissionAmount*(int(tdsValue)/100)
            # commissionAmount = netCommissionAmount-(gstAmount+tdsAmount)

            generated_commission_table = GeneratedCommissions(
                userId=str(merchantid),
                month=month_number,
                year=selectYear,
                totalTxnAmount=round(float(totalTxnAmount),2),
                netCommissionAmount=round(float(netCommissionAmount),2),
                gstAmount=0,
                gstValue=0,
                tdsAmount=round(float(tdsTotal),2),
                tdsValue=tdsValue,
                commissionAmount=round(float(CommissionAmount),2),
                createdOn=datetime.datetime.now(),
                status=1
                ).save()
        flash("Generate new commission!")
        return redirect(url_for("admin_reports.commission_settlements"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to generate new commission data!!"
        return render_template("super_admin_templates/commission_settlements_new.html")


def fetching_generated_commission_details(each_generated_commission):
    generatedCommissionDict = {}
    try:
        generatedCommissionDict = {
        "id":str(each_generated_commission.id),
        "userId":str(each_generated_commission.userId.id),
        "userName":each_generated_commission.userId.fullName,
        "merchantType":each_generated_commission.userId.merchantType,
        "totalTxnAmount":each_generated_commission.totalTxnAmount,
        "netCommissionAmount":each_generated_commission.netCommissionAmount,
        "gstAmount":each_generated_commission.gstAmount,
        "gstValue":each_generated_commission.gstValue,
        "tdsAmount":each_generated_commission.tdsAmount,
        "tdsValue":each_generated_commission.tdsValue,
        "commissionAmount":each_generated_commission.commissionAmount,
        "year":each_generated_commission.year,
        "month": datetime.datetime(year=each_generated_commission.year, month=each_generated_commission.month, day=1).strftime("%B"),
        "createdOn":each_generated_commission.createdOn.strftime("%d-%m-%Y %H:%M:%S %p")
        }
        if each_generated_commission.status == 1:
            generatedCommissionDict["generatedStatus"]="Generated"
        else:
            generatedCommissionDict["generatedStatus"]="Settled"
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return generatedCommissionDict

@admin_reports.route("/generate_commissions_list",methods=["POST","GET"])
@adminid_access_token_required
def generate_commissions_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    pagination = None
    startMonthYear = None
    endMonthYear = None
    selectYear = None
    selectMonth = None
    current_year = None
    last_year = None
    page=""
    snoCount=0
    generatedCommissionsList = []
    form = GenerateCommissionSearchForm(request.args)
    permissionsList = check_permissions(session.get("adminId"),"generateSettlementCommissionPermissions")
    if "view" in permissionsList:
        try:
            redirectTo = request.args.get("redirectTo","GenerateCommission")
            if redirectTo:
                redirectval = redirectTo
            else:
                redirectval = "GenerateCommission"

            selectYear = request.args.get("selectYear", default=str(datetime.datetime.now().year))
            selectMonth = request.args.get("selectMonth", default=datetime.datetime.now().strftime("%B"))
            gstValue = request.form.get("gstValue",0)
            tdsValue = request.form.get("tdsValue",0)

            # Get the month number from the month name
            month_number = datetime.datetime.strptime(selectMonth, "%B").month

            current_year = datetime.datetime.now().year
            last_year = current_year - 1

            # Construct startMonthYear and endMonthYear
            startMonthYear = datetime.datetime(int(selectYear), month_number, 1)
            endMonthYear = datetime.datetime(int(selectYear), month_number, monthrange(int(selectYear), month_number)[1])

            # if startMonthYear and endMonthYear:
            startMonthYear = startMonthYear.replace(hour=0, minute=0, second=0, microsecond=0)
            endMonthYear = endMonthYear.replace(hour=23, minute=59, second=59, microsecond=999999)
            
            # generated_commissions_queryset = GeneratedCommissions.objects(status=1,createdOn__gte=startMonthYear,createdOn__lte=endMonthYear).order_by("-createdOn")
            # Slice the list for the current page
            # total_commissions = generated_commissions_queryset[start:end]

            # snoCount = start
            # for each_generated_commission in total_commissions:
            #   print(each_generated_commission,"((((((((each_generated_commission))))))))")
            #   snoCount += 1
            #   generatedCommissionDict = fetching_generated_commission_details(each_generated_commission)
            #   generatedCommissionDict["snoCount"]=snoCount
            #   generatedCommissionsList.append(generatedCommissionDict)
            
            Page = request.args.get(get_page_parameter(), type=int, default=1)
            per_page = 20 
            total_count = 0
            start = (Page - 1) * per_page
            
            filters = Q(status=1) 
            if form.validate():
                filters &= Q(createdOn__gte=startMonthYear, createdOn__lte=endMonthYear)

                total_count = GeneratedCommissions.objects(filters).count()

                generated_commissions_queryset = (
                    GeneratedCommissions.objects(filters)
                    .only("id", "userId","year" ,"month","totalTxnAmount","netCommissionAmount","gstValue","tdsValue","gstAmount","tdsAmount","commissionAmount","status","createdOn")
                    .order_by("-id")
                    .skip(start)
                    .limit(per_page)
                )
                generatedCommissionsList=list(generated_commissions_queryset)
            else:
                generatedCommissionsList=[]
                
            
            snoCount = start
            # Pagination object for rendering pagination controls in the template
            
            pagination = Pagination(Page=Page, total=total_count, per_page=per_page,page_parameter ="Page", alignment="right", record_name="gstandtds",href=f"?selectYear={selectYear}&selectMonth={selectMonth}&Page={{0}}")
            

            return render_template("super_admin_templates/commission_settlements_new.html",
                generatedCommissionsList=generatedCommissionsList,
                redirectval=redirectval,
                selectYear=selectYear,
                selectMonth=selectMonth,
                startMonthYear=startMonthYear,
                endMonthYear=endMonthYear,
                current_year=current_year,
                last_year=last_year,
                pagination=pagination,
                snoCount=snoCount,
                form=form,
                page=page,
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch generate commissions data!!"
            return render_template("super_admin_templates/commission_settlements_new.html",
                error=error,
                generatedCommissionsList=generatedCommissionsList,
                redirectval=redirectval,
                selectYear=selectYear,
                selectMonth=selectMonth,
                startMonthYear=startMonthYear,
                endMonthYear=endMonthYear,
                current_year=current_year,
                last_year=last_year,
                pagination=pagination,
                snoCount=snoCount,
                form=form,
                page=page,

                )
    else:
        flash("The staff member does not have permission to view Generate commissions.", "danger")
        return redirect(url_for("admin.dashboard"))



@admin_reports.route("/update_generated_commission",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def update_generated_commission():
    data_status={"responseStatus":0,"result":""}
    if not session.get("adminId"):
        flash("Session expired. Please log in again.", "danger")
        data_status["responseStatus"]=4
        return data_status
        
    adminId = session.get("adminId")
    
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    latitude = request.form.get("latitude", "")
    longitude = request.form.get("longitude", "")
    loginBrowser = request.headers.get("Sec-Ch-Ua")
    if loginBrowser:
        loginBrowseData = loginBrowser.split(";")
        browser = loginBrowseData[0]
    else:
        loginBrowseData = request.headers.get('User-Agent').split(";")
        browser = loginBrowseData[0]

    existing_record = ""
    client_ip=0
    # Extracting client IP address
    if request.headers.getlist("X-Forwarded-For"): 
        client_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        client_ip = request.remote_addr

    actionDate=datetime.datetime.now()
    try:
        generatedCommissionId = request.args.get("generatedCommissionId","")
        gstValue = request.form.get("gstValue")
        tdsValue = request.form.get("tdsValue")
        jsonData = request.form.to_dict(flat=True)

        print(generatedCommissionId,"((((((generatedCommissionId))))))")
        print(type(gstValue),"((((((gstValue))))))")
        print(gstValue,"((((((gstValue))))))")
        print(tdsValue,"((((((tdsValue))))))")
        form = UpdateGeneratedCommisionForm(request.form, current_id=generatedCommissionId)
        if form.validate_on_submit():
            if generatedCommissionId and gstValue and tdsValue:
                generated_commission_queryset = GeneratedCommissions.objects(id=generatedCommissionId,status=1).first()
                existing_record = generated_commission_queryset.to_json()
                message=generated_commission_queryset.adminId.userName+ " Generate commission updated successfully!"
                requestData=[generated_commission_queryset]
                updatedrequestData=[jsonData]
                save_admin_log_table = save_admin_logs_data(adminId,None,None,"update_generated_commission","update",actionDate,client_ip,browser,message,requestData,updatedrequestData,latitude,longitude) 
                if not generated_commission_queryset:
                    flash("Invaild Generate Commission Id!!")
                    data_status["responseStatus"]=4
                    return data_status
                   

                netCommissionAmount = generated_commission_queryset.netCommissionAmount
                gstAmount = netCommissionAmount * (float(gstValue) / 100)
                tdsAmount = netCommissionAmount*(float(tdsValue)/100)
                commissionAmount = netCommissionAmount-(gstAmount+tdsAmount)

                generated_commission_queryset.update(
                    netCommissionAmount=netCommissionAmount,
                    gstAmount=gstAmount,tdsAmount=tdsAmount,
                    gstValue=gstValue,tdsValue=tdsValue,
                    commissionAmount=commissionAmount
                    )
                flash("Generate commission updated successfully!", "success")
                data_status["responseStatus"]=1
                return data_status
               
            else:
                data_status["responseStatus"]=2
                data_status["result"]="Required fields are missing."
                return data_status      
        else:
            data_status["result"]=form.errors
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        flash("Unable to update generate commission data!!", "danger")
        data_status["responseStatus"]=4
        return data_status
        

@admin_reports.route("/settlement_commissions_list",methods=["POST","GET"])
@adminid_access_token_required
def settlement_commissions_list():
   
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    pagination = None
    startMonthYear = None
    endMonthYear = None
    selectYear = None
    selectMonth = None
    current_year = None
    last_year = None
    page=""
    snoCount=0
    settlementCommissionsList = []
    form = GenerateCommissionSearchForm(request.args)
    permissionsList = check_permissions(session.get("adminId"),"settlementCommissionPermissions")
    if "view" in permissionsList:
        try:
            redirectTo = request.args.get("redirectTo","SettlementCommission")
            if redirectTo:
                redirectval = redirectTo
            else:
                redirectval = "SettlementCommission"

            selectYear = request.args.get("selectYear", default=str(datetime.datetime.now().year))
            selectMonth = request.args.get("selectMonth", default=datetime.datetime.now().strftime("%B"))
            gstValue = request.form.get("gstValue",0)
            tdsValue = request.form.get("tdsValue",0)

            # Get the month number from the month name
            month_number = datetime.datetime.strptime(selectMonth, "%B").month

            current_year = datetime.datetime.now().year
            last_year = current_year - 1

            # Construct startMonthYear and endMonthYear
            startMonthYear = datetime.datetime(int(selectYear), month_number, 1)
            endMonthYear = datetime.datetime(int(selectYear), month_number, monthrange(int(selectYear), month_number)[1])

            if startMonthYear and endMonthYear:
                startMonthYear = startMonthYear.replace(hour=0, minute=0, second=0, microsecond=0)
                endMonthYear = endMonthYear.replace(hour=23, minute=59, second=59, microsecond=999999)
            
            # settlement_commissions_queryset = GeneratedCommissions.objects(status=2,createdOn__gte=startMonthYear,createdOn__lte=endMonthYear).order_by("-createdOn")
            # # Slice the list for the current page
            # total_settlement_commissions = settlement_commissions_queryset[start:end]

            # snoCount = start
            # for each_settlement_commission in total_settlement_commissions:
            #   snoCount += 1
            #   settlementCommissionDict = fetching_generated_commission_details(each_settlement_commission)
            #   settlementCommissionDict["snoCount"]=snoCount
            #   settlementCommissionsList.append(settlementCommissionDict)

            # Pagination object for rendering pagination controls in the template
            # pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="settlementCommissions")
            
            Page = request.args.get(get_page_parameter(), type=int, default=1)
            per_page = 20 
            total_count = 0
            start = (Page - 1) * per_page

            
            filters = Q(status=2) 
            if form.validate():
                filters &= Q(createdOn__gte=startMonthYear, createdOn__lte=endMonthYear)

                total_count = GeneratedCommissions.objects(filters).count()

                settlement_commissions_queryset = (
                    GeneratedCommissions.objects(filters)
                    .only("id", "userId","year" ,"month","totalTxnAmount","netCommissionAmount","gstAmount","tdsAmount","commissionAmount","status","createdOn")
                    .order_by("-id")
                    .skip(start)
                    .limit(per_page)
                )
                settlementCommissionsList=list(settlement_commissions_queryset)
            else:
                settlementCommissionsList=[]

            snoCount = start
            # Pagination object for rendering pagination controls in the template
            
            pagination = Pagination(Page=Page, total=total_count, per_page=per_page,page_parameter ="Page", alignment="right", record_name="commisionlist",href=f"?selectYear={selectYear}&selectMonth={selectMonth}&Page={{0}}")

            return render_template("super_admin_templates/commission_settlements_new.html",
                settlementCommissionsList=settlementCommissionsList,
                redirectval=redirectval,
                selectYear=selectYear,
                selectMonth=selectMonth,
                startMonthYear=startMonthYear,
                endMonthYear=endMonthYear,
                current_year=current_year,
                last_year=last_year,
                pagination=pagination,
                snoCount=snoCount,
                form=form,
                page=page,
                )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch settlement commissions data!!"
            return render_template("super_admin_templates/commission_settlements_new.html",
                error=error,
                settlementCommissionsList=settlementCommissionsList,
                redirectval=redirectval,
                selectYear=selectYear,
                selectMonth=selectMonth,
                startMonthYear=startMonthYear,
                endMonthYear=endMonthYear,
                current_year=current_year,
                last_year=last_year,
                pagination=pagination,
                snoCount=snoCount,
                form=form,
                page=page,
                )
    else:
        flash("The staff member does not have permission to view Settlement commissions", "danger")
        return redirect(url_for("admin.dashboard"))

@admin_reports.route("/merchant_settlement",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def merchant_settlement():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    
    try:
        generatedCommissionIdsList = request.form.getlist("generatedCommissionIdsList[]")

        print(generatedCommissionIdsList,"((((((generatedCommissionIdsList))))))")
        transactionUniqueId = random_digit_generate(16)

        if generatedCommissionIdsList:
            for each_generated_commission_id in generatedCommissionIdsList:
                generated_commission_queryset = GeneratedCommissions.objects(id=str(each_generated_commission_id),status=1).first()
                if not generated_commission_queryset:
                    continue

                if generated_commission_queryset:
                    orderId = random_digit_generate(16)

                    userId = str(generated_commission_queryset.userId.id)
                    comment=""

                    print(userId,"(((((((((((Merchant Id)))))))))))-000000000000000")

                    netCommissionAmount = float(generated_commission_queryset.netCommissionAmount)
                    commissionAmount = float(generated_commission_queryset.commissionAmount)
                    tdsValue = float(generated_commission_queryset.tdsValue)
                    tdsAmount = float(generated_commission_queryset.tdsAmount)
                    user_queryset = Users.objects(id=userId,status=1).first()

                    if user_queryset:
                        updateCommissionBalance = float(user_queryset.commissionBalance) - float(netCommissionAmount)
                        print(updateCommissionBalance,"((((((((updateCommissionBalance))))))))")
                        print(userId,"(((((((((((Merchant Id)))))))))))11111111111111111")

                        payOutPaymentGatewayId=None
                        merchantUniqueNumber=str(user_queryset.merchantUniqueNumber)
                        mid_extracted = merchantUniqueNumber[1:].lstrip("0")
        
                        pgOrderId= str(transaction_id_prefix)+str(mid_extracted) + str(orderId) 
                        try:
                            if user_queryset.patternId.payoutPaymentGatewayId:
                                payOutPaymentGatewayId = str(user_queryset.patternId.payoutPaymentGatewayId.id)
                        except Exception as e:
                            print("(((((((((((((((((in exception)))))))))))))))))")
                            pass

                        userbalance_queryset = Users.objects(id=str(userId)).modify(inc__payoutBalance=float(commissionAmount),new=True)
                        userCurrentBalance = userbalance_queryset.payoutBalance
                        userPreviousBalance = float(userCurrentBalance)-float(commissionAmount)
                        siteTitle = userbalance_queryset.siteTitle
                        
                        commissionCharges = {
                            "aggregatorType":"",
                            "aggregatorAmount":round(float(0),2),
                            "commissionType":"",
                            "commissionAmount":0,
                            "chargeType":"",
                            "chargeValue":0,
                            "gstValue":0,
                            "tdsValue":tdsValue,
                            "aggregatorValue":0,
                            "commissionValue":0,
                            "chargeAmount":round(float(0),2),
                            "transactionAmount":round(float(commissionAmount),2),
                            "gstInclude":0,
                            "gstAmount":round(float(0),2),
                            "tdsInclude":0,
                            "tdsAmount":round(float(tdsAmount),2),
                            "priceType":"",
                            "slabId":None
                            }



                        fund_transfer_table = FundTransfers(
                                createdBy=adminId,
                                userId = userId,
                                amount = netCommissionAmount,
                                grandTotal = commissionAmount,
                                # transactionAPIId = payOutPaymentGatewayId,
                                transferType = "Credit",
                                userType = "admin",
                                narration = "Settlement done on "+str(datetime.datetime.now().strftime("%d-%m-%Y %I:%M:%S %p")),
                                transactionUniqueId = transactionUniqueId,
                                createdOn = datetime.datetime.now(),
                                previousBalance=userPreviousBalance,
                                currentBalance=userCurrentBalance,
                                uniqueRequestNumber = "",
                                beneficiaryName = user_queryset.fullName, 
                                beneficiaryMail = user_queryset.email, 
                                beneficiaryPhone = "",
                                accountIFSCCode = "",
                                fundTransferType = "settlement",
                                accountType = "",
                                accountNumber = "",
                                paymentMode = "wallet",
                                bankBranch = "",
                                bankName = "",
                                errorMessage = "",
                                internalId = "",
                                pgOrderId = pgOrderId,
                                siteTitle = siteTitle,
                                apiType = "web",
                                merchantReferenceNumber = orderId,
                                commissionCharges = commissionCharges,
                                status = 1
                                )
                        save_table = fund_transfer_table.save()
                        print("((((((((((((((( fundtransfer Settlement Id))))))))))))))) ",fund_transfer_table.id)
                        if payOutPaymentGatewayId:
                            save_table.update(transactionAPIId = ObjectId(payOutPaymentGatewayId))
                        else:
                            save_table.update(transactionAPIId = None)
                          
                        generated_commission_queryset.update(status=2,settlementedOn=datetime.datetime.now())
                        user_queryset.update(commissionBalance=updateCommissionBalance)

                        settled_commission_queryset = UserCommissions.objects(userId=str(user_queryset.id),settlementStatus=2).first()
                        settled_commission_queryset.update(settlementStatus=2)

                        user_commission_table = UserCommissions(
                            adminId=adminId,
                            userId = userId,
                            totalAmount = netCommissionAmount,
                            transferType = "Debit",
                            comment = "Settlement done on "+str(datetime.datetime.now().strftime("%d-%m-%Y %I:%M:%S %p")),
                            transactionId = transactionUniqueId,
                            createdOn = datetime.datetime.now(),
                            previousBalance=float(user_queryset.commissionBalance),
                            currentBalance=float(updateCommissionBalance),
                            status = 1
                            ).save()
                flash("Merchant commission settlement successfully!")
                return redirect(url_for("admin_reports.generate_commissions_list"))
        else:
            flash("Required fields are missing!!")
            return redirect(url_for("admin_reports.generate_commissions_list"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to settle merchant commission!!"
        return redirect(url_for("admin_reports.generate_commissions_list"))

################################################################# COMMISSION SETTLEMENT CODE END ###################################################################

# @admin_reports.route("/reconciliation_reports",methods=["POST","GET"])
# @adminid_access_token_required
# def reconciliation_reports():
#     try:
#         if not session.get("adminId"):
#             return redirect("admin_login")
#         adminId = session.get("adminId")
#         redirectTo = request.args.get("redirectTo","payinReconciliation")
#         if redirectTo:
#             redirectval = redirectTo
#         else:
#             redirectval = "payinReconciliation"
            
#         permissionsList = check_permissions(session.get("adminId"),"reconcilationTransactionReportPermissions")
#         if "view" in permissionsList:
#             payinReconcillationList = []
#             payoutReconcillationList = []

#             startDate = request.args.get("startDate","")
#             endDate = request.args.get("endDate","")
#             merchantId = request.args.get("merchantId","")
#             merchantsList = []

#             # Set default date format
#             date_format = "%d-%m-%Y"
#             pagination = None
#             payoutPagination = None
#             payinTotalCreditAmount = 0
#             payinTotalDebitAmount = 0
#             try:
#                 if startDate:
#                     startDate = datetime.datetime.strptime(startDate, date_format)
#                     startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
#                 else:
#                     startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

#                 if endDate:
#                     endDate = datetime.datetime.strptime(endDate, date_format)
#                     endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
#                 else:
#                     endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
#             except Exception as ve:
#                 app.logger.error("Date parsing error: %s", ve)
#                 startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
#                 endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

#             merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
#             for each_merchant in merchants_queryset:
#                 merchantDict = fetching_user_details(each_merchant)
#                 merchantsList.append(merchantDict)

#             ##################################################### PAYIN RECONSILATION CODE #############################################################
#             # Correctly apply merchantId in the aggregation pipeline
#             match_stage = {
#                 "createdOn": {"$gte": startDate, "$lte": endDate}
#             }

#             # Add userId filter only if merchantId is provided
#             if merchantId:
#                 match_stage["userId"] = ObjectId(merchantId)

#             # Aggregation pipeline to sum by userId (unique merchants)
#             aggregation_pipeline = [
#                 {
#                     "$match": {
#                         **match_stage,  # Apply the existing match_stage conditions
#                         "status": 1     # Correctly filter by status inside $match
#                     }
#                 },
#                 # Sort by createdOn in descending order to get the most recent transaction first
#                 {
#                     "$sort": {"createdOn": -1}
#                 },
#                 {
#                     "$group": {
#                         "_id": "$userId",  # Group by userId (unique merchants)
#                         "totalCreditAmount": {
#                             "$sum": {
#                                 "$cond": [
#                                     {"$and": [{"$eq": ["$creditType", "Credit"]}, {"$eq": ["$userType", "user"]}]},
#                                     "$amount",
#                                     0
#                                 ]
#                             }
#                         },  # Sum only credit amounts for users
#                         "totalDebitAmount": {
#                             "$sum": {
#                                 "$cond": [
#                                     {"$and": [{"$eq": ["$creditType", "Debit"]}, {"$eq": ["$userType", "admin"]}]},
#                                     "$amount",
#                                     0
#                                 ]
#                             }
#                         },  # Sum only debit amounts for admins
#                         "latestPreviousBalance": {"$first": "$previousBalance"},  # First (latest) previousBalance after sorting by createdOn
#                         "latestCurrentBalance": {"$first": "$currentBalance"}  # First (latest) currentBalance after sorting by createdOn
#                     }
#                 },
#                 {
#                     "$sort": {"_id": 1}  # Sort by userId
#                 }
#             ]

#             # Execute the aggregation pipeline and materialize the cursor into a list
#             payins_aggregated = list(WalletTransactions.objects.aggregate(aggregation_pipeline))

#             # Initialize sums and the list for reconciliation
#             payinReconcillationList = []

#             # Pagination setup
#             page = request.args.get(get_page_parameter(), type=int, default=1)
#             per_page = 20  # Number of items per page
#             total_count = len(payins_aggregated)  # Total count of aggregated results

#             start = (page - 1) * per_page
#             end = min(start + per_page, total_count)

#             # Ensure `start` and `end` are in valid range
#             if start >= total_count:
#                 start = total_count - 1
#             if start < 0:
#                 start = 0

#             # Process the paginated aggregated results
#             snoCount = start

#             # Loop through only the relevant slice for pagination
#             for result in payins_aggregated[start:end]:
#                 snoCount += 1
#                 user_id = result["_id"]
#                 total_credit_amount = result["totalCreditAmount"]
#                 total_debit_amount = result["totalDebitAmount"]

#                 # Correct the field names in the final dictionary
#                 payinDict = {
#                     "payinTotalCreditAmount": formatINR("{:.2f}".format(float(total_credit_amount))),
#                     "payinTotalDebitAmount": formatINR("{:.2f}".format(float(total_debit_amount))),
#                     "payinDayStartFirstOpeningBalanceAmount": formatINR("{:.2f}".format(float(result.get("latestPreviousBalance", 0)))),  # Use latestPreviousBalance
#                     "payinDayEndLastgBalanceAmount": formatINR("{:.2f}".format(float(result.get("latestCurrentBalance", 0)))),  # Use latestCurrentBalance
#                     "snoCount": snoCount
#                 }

#                 # Fetch merchant name based on userId
#                 user_queryset = Users.objects(id=user_id).first()
#                 if user_queryset:
#                     payinDict["merchantName"] = user_queryset.fullName
#                 else:
#                     payinDict["merchantName"] = ""

#                 # Add the payin data to the reconciliation list
#                 payinReconcillationList.append(payinDict)

#             # Pagination object for rendering pagination controls in the template
#             pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="PayinReconciliation")




#             #############################################################################################################################################################


#             ##################################################### PAYOUT RECONSILATION CODE ##############################################################
#             payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate)
#             payoutOverallBalanceAmount = payouts_queryset.sum("amount")
#             payoutTotalCreditAmount = payouts_queryset.filter(transferType="Credit").sum("amount")
#             payoutTotalDebitAmount = payouts_queryset.filter(transferType="Debit").sum("amount")

#             if merchantId:
#                 payouts_queryset = payouts_queryset.filter(userId=merchantId)
#                 payoutTotalCreditAmount = payouts_queryset.filter(transferType="Credit").sum("amount")
#                 payoutTotalDebitAmount = payouts_queryset.filter(transferType="Debit").sum("amount")

            

#             # Get the first transaction of the day to fetch the opening balance
#             first_payout_transaction_of_day = payouts_queryset.order_by("createdOn").first()

#             # If there is a first transaction, get its previous balance
#             if first_payout_transaction_of_day:
#                 payoutDayStartFirstOpeningBalanceAmount = first_payout_transaction_of_day.previousBalance
#             else:
#                 payoutDayStartFirstOpeningBalanceAmount = 0 

#             # Get the Last transaction of the day to fetch the opening balance
#             last_payout_transaction_of_day = payouts_queryset.order_by("-createdOn").first()

#             # If there is a last transaction, get its current balance
#             if last_payout_transaction_of_day:
#                 payoutDayEndLastgBalanceAmount = last_payout_transaction_of_day.currentBalance
#             else:
#                 payoutDayEndLastgBalanceAmount = 0 

            
#             #Get the current page from the query parameters
#             payoutpage = request.args.get(get_page_parameter(), type=int, default=1)

#             per_payout_page = 20  # Number of items per page

#             # Query the database for the current page's data
#             total_payout_count = payouts_queryset.count()

#             payoutStart = (payoutpage - 1) * per_payout_page

#             payoutEnd = min(payoutStart + per_payout_page, total_payout_count)

#             # Ensure that payoutStart is less than or equal to payoutEnd
#             if payoutStart > payoutEnd:
#                 # You can either swap them or handle the case as needed
#                 payoutStart, payoutEnd = payoutEnd, payoutStart

#             total_reconciliation_payouts = payouts_queryset[payoutStart:payoutEnd]
            
#             snoPayoutCount = payoutStart
#             for each_payout in total_reconciliation_payouts:
#                 snoPayoutCount +=1
#                 payoutDict = {
#                 "payoutOverallBalanceAmount":payoutOverallBalanceAmount,
#                 "payoutDayStartFirstOpeningBalanceAmount":payoutDayStartFirstOpeningBalanceAmount,
#                 "payoutDayEndLastgBalanceAmount":payoutDayEndLastgBalanceAmount,
#                 "payoutTotalCreditAmount":formatINR("{:.2f}".format(float(payoutTotalCreditAmount))),
#                 "payoutTotalDebitAmount":formatINR("{:.2f}".format(float(payoutTotalDebitAmount))),
#                 "id":str(each_payout.id),
#                 "transferType":each_payout.transferType,
#                 "snoCount":snoPayoutCount
#                 }
#                 try:
#                     if each_payout.userId:
#                         payoutDict["merchantName"]=each_payout.userId.fullName
#                     else:
#                         payoutDict["merchantName"]=""
#                 except Exception as e:
#                     payoutDict["merchantName"]=""
#                 if payoutDict not in payoutReconcillationList:
#                     payoutReconcillationList.append(payoutDict)

#             # Pagination object for rendering pagination controls in the template
#             payoutPagination = Pagination(page=payoutpage, total=total_payout_count, per_page=per_payout_page, alignment="right", record_name="PayoutReconciliation")

#             #############################################################################################################################################################

#             return render_template("super_admin_templates/reconciliation_reports_list.html",
#                 redirectval=redirectval,
#                 pagination=pagination,
#                 payoutPagination=payoutPagination,
#                 merchantId=merchantId,
#                 merchantsList=merchantsList,
#                 payinReconcillationList=payinReconcillationList,
#                 payoutReconcillationList=payoutReconcillationList,
#                 startDate=startDate.strftime(date_format),
#                 endDate=endDate.strftime(date_format)
#                 )
#         else:
#             flash("Staff member does not have given view reconciliation report permissions!!")
#             return render_template("super_admin_templates/reconciliation_reports_list.html")
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         error = "Unable to fetched reconciliation reports data!!"
#         return render_template("super_admin_templates/reconciliation_reports_list.html", 
#             error=error,
#             redirectval=redirectval,
#             pagination=pagination,
#             payoutPagination=payoutPagination,
#             merchantId=merchantId,
#             merchantsList=merchantsList,
#             payinReconcillationList=payinReconcillationList,
#             payoutReconcillationList=payoutReconcillationList,
#             startDate=startDate.strftime(date_format),
#             endDate=endDate.strftime(date_format)
#             )


@admin_reports.route("/reconciliation_reports",methods=["POST","GET"])
@adminid_access_token_required
def reconciliation_reports():
    payinReconcillationList = []
    payoutReconcillationList = []
    merchantsList = []
    snoCount=0,
    snoPayoutCount=0,
    pagination=None
    payoutPagination = None
    payinTotalCreditAmount = 0
    payinTotalDebitAmount = 0
    form=ReconciliationSearchForm(request.args)
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        redirectTo = request.args.get("redirectTo","payinReconciliation")
        if redirectTo:
            redirectval = redirectTo
        else:
            redirectval = "payinReconciliation"
            
        permissionsList = check_permissions(session.get("adminId"),"reconcilationTransactionReportPermissions")
        if "view" in permissionsList:
            payinReconcillationList = []
            payoutReconcillationList = []

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            merchantId = request.args.get("merchantId","")
            merchantsList = []

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            payoutPagination = None
            payinTotalCreditAmount = 0
            payinTotalDebitAmount = 0
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
            merchantsList = list(merchants_queryset)   
            ##################################################### PAYIN RECONSILATION CODE #############################################################
            # Correctly apply merchantId in the aggregation pipeline
            if form.validate():
                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)
    
                match_stage = {
                    "createdOn": {"$gte": startDate, "$lte": endDate}
                }
                query = Q(createdOn__gte=startDate,createdOn__lte=endDate)
                if merchantId:
                    query  &= Q(userId__in=[merchantId])
                        
                # Add userId filter only if merchantId is provided
                if merchantId:
                    match_stage["userId"] = ObjectId(merchantId)

                # Aggregation pipeline to sum by userId (unique merchants)
                aggregation_pipeline = [
                    {
                        "$match": {
                            **match_stage,  # Apply the existing match_stage conditions
                            "status": 1     # Correctly filter by status inside $match
                        }
                    },
                    # Sort by createdOn in descending order to get the most recent transaction first
                    {
                        "$sort": {"createdOn": -1}
                    },
                    {
                        "$group": {
                            "_id": "$userId",  # Group by userId (unique merchants)
                            "totalCreditAmount": {
                                "$sum": {
                                    "$cond": [
                                        {"$and": [{"$eq": ["$creditType", "Credit"]}, {"$eq": ["$userType", "user"]}]},
                                        "$amount",
                                        0
                                    ]
                                }
                            },  # Sum only credit amounts for users
                            "totalDebitAmount": {
                                "$sum": {
                                    "$cond": [
                                        {"$and": [{"$eq": ["$creditType", "Debit"]}, {"$eq": ["$userType", "admin"]}]},
                                        "$amount",
                                        0
                                    ]
                                }
                            },  # Sum only debit amounts for admins
                            "latestPreviousBalance": {"$first": "$previousBalance"},  # First (latest) previousBalance after sorting by createdOn
                            "latestCurrentBalance": {"$first": "$currentBalance"}  # First (latest) currentBalance after sorting by createdOn
                        }
                    },
                    {
                        "$sort": {"_id": 1}  # Sort by userId
                    }
                ]

                # Execute the aggregation pipeline and materialize the cursor into a list
                payins_aggregated = list(WalletTransactions.objects.aggregate(aggregation_pipeline))

                # Initialize sums and the list for reconciliation
                payinReconcillationList = []

                # Pagination setup
                # page = request.args.get(get_page_parameter(), type=int, default=1)
                # per_page = 20  # Number of items per page
                # total_count = len(payins_aggregated)  # Total count of aggregated results

                # start = (page - 1) * per_page
                # end = min(start + per_page, total_count)

                # Ensure `start` and `end` are in valid range
                # if start >= total_count:
                #   start = total_count - 1
                # if start < 0:
                #   start = 0

                # Process the paginated aggregated results
                snoCount = start

                # Loop through only the relevant slice for pagination
                for result in payins_aggregated:
                    # snoCount += 1
                    user_id = result["_id"]
                    total_credit_amount = result["totalCreditAmount"]
                    total_debit_amount = result["totalDebitAmount"]

                    # Correct the field names in the final dictionary
                    payinDict = {
                        "payinTotalCreditAmount": formatINR("{:.2f}".format(float(total_credit_amount))),
                        "payinTotalDebitAmount": formatINR("{:.2f}".format(float(total_debit_amount))),
                        "payinDayStartFirstOpeningBalanceAmount": formatINR("{:.2f}".format(float(result.get("latestPreviousBalance", 0)))),  # Use latestPreviousBalance
                        "payinDayEndLastgBalanceAmount": formatINR("{:.2f}".format(float(result.get("latestCurrentBalance", 0)))),  # Use latestCurrentBalance
                        # "snoCount": snoCount
                    }

                    # Fetch merchant name based on userId
                    user_queryset = Users.objects(id=user_id).first()
                    if user_queryset:
                        payinDict["merchantName"] = user_queryset.fullName
                    else:
                        payinDict["merchantName"] = ""

                    # Add the payin data to the reconciliation list
                    payinReconcillationList.append(payinDict)
                total_count = len(payinReconcillationList)
    
                end = min(start + per_page, total_count)
                print("end",end)
                print("per_page",per_page)
                print("total_count",total_count)
                payinReconcillationList = payinReconcillationList[start:end]
                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="PayinReconciliation")

            
            #############################################################################################################################################################


            ##################################################### PAYOUT RECONSILATION CODE ##############################################################
                payoutpage = request.args.get(get_page_parameter(), type=int, default=1)

                per_payout_page = 20  # Number of items per page
                
                # total_payout_count = payouts_queryset.count()

                payoutStart = (payoutpage - 1) * per_payout_page
                snoPayoutCount = int(payoutStart)
                snoPayoutCount = payoutStart
                
                print("datetime time after",datetime.datetime.now())
                payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate).limit(payoutpage).skip(payoutpage)
    
                payoutOverallBalanceAmount = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate).sum("amount")
    
    
                payoutTotalCreditAmount = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,transferType="Credit" ).sum("amount")
    
    
                payoutTotalDebitAmount = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate, transferType="Debit").sum("amount")
    
                query = Q(createdOn__gte=startDate,createdOn__lte=endDate)

                if merchantId:
                    print("merchantId", merchantId)
                    query &= Q(userId__icontains=merchantId)

                # payoutOverallBalanceAmount = payouts_queryset.sum("amount")
                # payoutTotalCreditAmount = payouts_queryset.filter(transferType="Credit").sum("amount")
                # payoutTotalDebitAmount = payouts_queryset.filter(transferType="Debit").sum("amount")

                if merchantId:
        
                    payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,userId=merchantId).limit(payoutpage).skip(payoutpage)
    
    
                    payoutTotalCreditAmount = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,transferType="Credit",userId=merchantId ).sum("amount")
    
    
                    payoutTotalDebitAmount = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate, transferType="Debit",userId=merchantId).sum("amount")
     
     
                    # payouts_queryset = payouts_queryset.filter(userId=merchantId)
                    # payoutTotalCreditAmount = payouts_queryset.filter(transferType="Credit").sum("amount")
                    # payoutTotalDebitAmount = payouts_queryset.filter(transferType="Debit").sum("amount")

              
                print("datetime time after",datetime.datetime.now())

                # Get the first transaction of the day to fetch the opening balance
                first_payout_transaction_of_day = payouts_queryset.order_by("createdOn").first()

                # If there is a first transaction, get its previous balance
                if first_payout_transaction_of_day:
                    payoutDayStartFirstOpeningBalanceAmount = first_payout_transaction_of_day.previousBalance
                else:
                    payoutDayStartFirstOpeningBalanceAmount = 0 

                # Get the Last transaction of the day to fetch the opening balance
                last_payout_transaction_of_day = payouts_queryset.order_by("-createdOn").first()

                # If there is a last transaction, get its current balance
                if last_payout_transaction_of_day:
                    payoutDayEndLastgBalanceAmount = last_payout_transaction_of_day.currentBalance
                else:
                    payoutDayEndLastgBalanceAmount = 0 

                
                # #Get the current page from the query parameters
                # payoutpage = request.args.get(get_page_parameter(), type=int, default=1)

                # per_payout_page = 20  # Number of items per page
                
                # # total_payout_count = payouts_queryset.count()

                # payoutStart = (payoutpage - 1) * per_payout_page
                # snoPayoutCount = int(payoutStart)
                

                # Ensure that payoutStart is less than or equal to payoutEnd
                # if payoutStart > payoutEnd:
                #   # You can either swap them or handle the case as needed
                #   payoutStart, payoutEnd = payoutEnd, payoutStart

                # reconciliation_payouts = payouts_queryset
                
               
                for each_payout in payouts_queryset:
                    # snoPayoutCount +=1
                    payoutDict = {
                    "payoutOverallBalanceAmount":payoutOverallBalanceAmount,
                    "payoutDayStartFirstOpeningBalanceAmount":payoutDayStartFirstOpeningBalanceAmount,
                    "payoutDayEndLastgBalanceAmount":payoutDayEndLastgBalanceAmount,
                    "payoutTotalCreditAmount":formatINR("{:.2f}".format(float(payoutTotalCreditAmount))),
                    "payoutTotalDebitAmount":formatINR("{:.2f}".format(float(payoutTotalDebitAmount))),
                    "id":str(each_payout.id),
                    "transferType":each_payout.transferType,
                    # "snoCount":snoPayoutCount
                    }
                    try:
                        if each_payout.userId:
                            payoutDict["merchantName"]=each_payout.userId.fullName
                        else:
                            payoutDict["merchantName"]=""
                    except Exception as e:
                        payoutDict["merchantName"]=""
                        
                    if payoutDict not in payoutReconcillationList:
                        payoutReconcillationList.append(payoutDict)
    
                total_payout_count = len(payoutReconcillationList)
                # payoutEnd = min(payoutStart + per_payout_page,total_payout_count) 
    
                
                # print("payoutEnd",payoutEnd)
                # print("per_payout_page",per_payout_page)
                # print("total_payout_count",total_payout_count)
                # payoutReconcillationList = payoutReconcillationList[payoutStart:payoutEnd]

                # Pagination object for rendering pagination controls in the template
                payoutPagination = Pagination(page=payoutpage, total=total_payout_count, per_page=per_payout_page, alignment="right", record_name="PayoutReconciliation")

            #############################################################################################################################################################
            else:
                print("form errors",form.errors)  

            return render_template("super_admin_templates/reconciliation_reports_list.html",
                redirectval=redirectval,
                pagination=pagination,
                payoutPagination=payoutPagination,
                merchantId=merchantId,
                merchantsList=merchantsList,
                payinReconcillationList=payinReconcillationList,
                payoutReconcillationList=payoutReconcillationList,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                form=form,
                snoCount=snoCount,
                snoPayoutCount=snoPayoutCount,


                )
        else:
            flash("The staff member does not have permission to view Reconciliation report.", "danger")
            return redirect(url_for("admin.dashboard"))
            
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched reconciliation reports data!!"
        return render_template("super_admin_templates/reconciliation_reports_list.html", 
            error=error,
            redirectval=redirectval,
            pagination=pagination,
            payoutPagination=payoutPagination,
            # merchantId=merchantId,
            merchantsList=merchantsList,
            payinReconcillationList=payinReconcillationList,
            payoutReconcillationList=payoutReconcillationList,
            form=form,
            snoCount=snoCount,
            snoPayoutCount=snoPayoutCount,
            # startDate=startDate.strftime(date_format),
            # endDate=endDate.strftime(date_format)
            )


@admin_reports.route("/admin_download_payout_settlement_csv_reports", methods=["POST", "GET"])
@adminid_access_token_required
def admin_download_payout_settlement_csv_reports():
    data_status = {"responseStatus": 0, "result": ""}

    startDate = request.args.get("startDate", "")
    endDate = request.args.get("endDate", "")
    orderId = request.args.get("orderId", "")
    merchantId = request.args.get("merchantId", "")
    
    try:
        # Set default date format
        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

        query = Q(createdOn__gte=startDate,createdOn__lte=endDate)

        if orderId:
            print("orderId", orderId)
            query &= Q(merchantReferenceNumber__icontains=orderId)

        if merchantId:
            print("merchantId", merchantId)
            query &= Q(userId__icontains=merchantId)

        payouts_queryset = (
            FundTransfers.objects(query)
            .only("id","userId","createdOn","merchantReferenceNumber","transferType","amount","narration","beneficiaryName","fundTransferType","accountNumber","accountIFSCCode","beneficiaryMail","beneficiaryPhone","grandTotal","transactionUniqueId","transactionData","pgOrderId","previousBalance","currentBalance","errorMessage","userType")
            .order_by("-createdOn")
        )


        reportData = admin_download_payout_settlement_csv_reports_data(startDate, endDate, payouts_queryset)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to download success payout report data!!"
        return data_status




@admin_reports.route("/admin_download_utility_transaction_csv_reports", methods=["POST", "GET"])
@adminid_access_token_required
def admin_download_utility_transaction_csv_reports():
    data_status = {"responseStatus": 0, "result": ""}

    startDate = request.args.get("startDate", "")
    endDate = request.args.get("endDate", "")
    selectStatus = request.args.get("selectStatus","")
    orderId = request.args.get("orderId", "")
    merchantId = request.args.get("merchantId", "")
    
    try:
        # Set default date format
        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

        merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
        # for each_merchant in merchants_queryset:
        #     merchantDict = fetching_user_details(each_merchant)
        #     merchantsList.append(merchantDict)

        if selectStatus == "All" or selectStatus == "":
            status = [0,1,2]
        elif selectStatus == "Success":
            status = [1]
        elif selectStatus == "Processing":
            status = [2]
        else:
            status = [0]


        query = Q(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status)


        if orderId:
            query &= Q(orderId=orderId)

        if merchantId:
            query &= Q(userId__in=[merchantId])

        utility_queryset = Transactions.objects(query).order_by("-createdOn").all()

        reportData = admin_download_utility_transaction_csv_reports_data(startDate, endDate, utility_queryset)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to download success Utility Transaction report data!!"
        return data_status

# @admin_reports.route("/payin_balance_reports", methods=["POST", "GET"])
# @adminid_access_token_required
# def payin_balance_reports():
#     if not session.get("adminId"):
#         return redirect("admin_login")
    
#     adminId = session.get("adminId")
#     permissionsList = check_permissions(session.get("adminId"),"balanceReportPermissions")
#     if "view" in permissionsList:
#         try:
#             if not session.get("adminId"):
#                 return redirect("admin_login")

#             payinsList = []

#             selectedDate = request.args.get("payin_selectedDate", "")
#             merchantType = request.args.get("payin_merchantType", "")
#             merchantId = request.args.get("payin_merchantId", "")
#             merchantsList = []
#             latest_balance = None

#             redirectTo = request.form.get("redirectTo","payinBalanceReports")

#             date_format = "%d-%m-%Y"
#             pagination = None
#             payout_selectedDate = datetime.datetime.now().strftime(date_format)
#             print("_________________________________________",merchantId,merchantType,selectedDate,redirectTo)
#             # Date handling
#             if selectedDate:
#                 try:
#                     selectedDate = datetime.datetime.strptime(selectedDate, date_format)
#                 except Exception as ve:
#                     app.logger.error("Date parsing error: %s", ve)
#                     selectedDate = datetime.datetime.now()
#             else:
#                 selectedDate = datetime.datetime.now()

#             startDate = selectedDate.replace(hour=0, minute=0, second=0, microsecond=0)
#             endDate = selectedDate.replace(hour=23, minute=59, second=59, microsecond=999999)

#             merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
#             for each_merchant in merchants_queryset:
#                 merchantDict = fetching_user_details(each_merchant)
#                 merchantsList.append(merchantDict)

#             # Query FundTransfers
#             payins_queryset = WalletTransactions.objects(createdOn__gte=startDate, createdOn__lte=endDate)

#             print("______________________________a___+____+_+_+_",payins_queryset.count(),startDate,endDate)

#             # Filter by merchantId
#             if merchantId:
#                 payins_queryset = payins_queryset.filter(userId=merchantId)
            
#             final_payin_transaction_Data = []

#             # Fetch valid users and their latest balances
#             for each_payin in payins_queryset:
                
#                 print("+++++++++++++++++++++++++++++++++++++++++",each_payin.userId)
#                 userId = str(each_payin.userId.id)
#                 user_queryset = Users.objects(id=userId,status=1).first()  # Fetch user details

#                 if user_queryset and user_queryset.merchantType == merchantType:
#                     latest_transaction_query_set = WalletTransactions.objects(
#                         userId=userId,
#                         createdOn__gte=startDate,
#                         createdOn__lte=endDate
#                     ).order_by("-createdOn").first()
#                     print(latest_transaction_query_set,"(((((((((latest_transaction_query_set)))))))))")
#                     print(str(latest_transaction_query_set.id),"(((((((((latest_transaction_query_set)))))))))")
#                     if latest_transaction_query_set.amount:
#                         latest_user_transaction_balance = float(latest_transaction_query_set.amount)
#                     else:
#                         latest_user_transaction_balance = 0

#                     try:
#                         if user_queryset.parentId:
#                             parent_name = user_queryset.parentId.fullName
#                         else:
#                             parent_name = ""
#                     except Exception as e:
#                         parent_name = ""
                
#                     transaction_dict = {
#                         'userName': user_queryset.fullName,
#                         'parentName': parent_name,
#                         'merchantType': user_queryset.merchantType,
#                         'createdOn': latest_transaction_query_set.createdOn.strftime("%d-%m-%Y %I:%M:%S %p"),
#                         'latest_amount': latest_user_transaction_balance
#                     }
#                     if transaction_dict not in final_payin_transaction_Data: 
#                         final_payin_transaction_Data.append(transaction_dict)


#             # # Pagination setup
#             page = request.args.get(get_page_parameter(), type=int, default=1)
#             per_page = 1
#             total_count = len(final_payin_transaction_Data)
#             start = (page - 1) * per_page
#             end = min(start + per_page, total_count)
#             total_payins = final_payin_transaction_Data[start:end]
#             final_payin_transaction_Data = total_payins

#             pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="balance_reports")

#             return render_template("super_admin_templates/balance_reports_list.html",
#                 pagination=pagination,
#                 final_payin_transaction_Data=final_payin_transaction_Data,
#                 payin_selectedDate=selectedDate.strftime(date_format),
#                 payin_merchantType=merchantType,
#                 payin_merchantId=merchantId,
#                 merchantsList=merchantsList,
#                 payout_selectedDate=payout_selectedDate,
#                 redirectval=redirectTo
#             )
#         except Exception as e:
#             app.logger.error(traceback.format_exc())
#             error = "Unable to fetch balance transaction data!"
#             return render_template("super_admin_templates/balance_reports_list.html",
#                 error=error,
#             )
#     else:
#         flash("Staff member does not have given view payin balance report permissions!!")
#         return redirect(url_for("admin.dashboard"))


@admin_reports.route("/payin_balance_reports", methods=["POST", "GET"])
@adminid_access_token_required
def payin_balance_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    
    adminId = session.get("adminId")
    permissionsList = check_permissions(session.get("adminId"),"balanceReportPermissions")
    merchantsList = []
    payinsList = []
    snoCount = None
    final_payin_transaction_Data = []
    pagination = None
    latest_balance = None
    form1=BalancePayinReportsSearchForm(request.args)
    if "view" in permissionsList:
        try:
            if not session.get("adminId"):
                return redirect("admin_login")
            merchantsList = []
            payinsList = []
            latest_balance = None
            
            selectedDate = request.args.get("payin_selectedDate", "")
            merchantType = request.args.get("payin_merchantType", "")
            merchantId = request.args.get("payin_merchantId", "")
            redirectTo = request.form.get("redirectTo","payinBalanceReports")
            date_format = "%d-%m-%Y"
            payout_selectedDate = datetime.datetime.now().strftime(date_format)
            print("_________________________________________",merchantId,merchantType,selectedDate,redirectTo)
            
            
            # Date handling
            pagination = None
            if selectedDate:
                try:
                    selectedDate = datetime.datetime.strptime(selectedDate, date_format)
                except Exception as ve:
                    app.logger.error("Date parsing error: %s", ve)
                    selectedDate = datetime.datetime.now()
            else:
                selectedDate = datetime.datetime.now()

            startDate = selectedDate.replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = selectedDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            
            
            
            print("(((((((((((((((((((((((((((datetime)))))))))))))))))))))))))))",selectedDate)
            if form1.validate():
                print("(((((((((((((((((((((((((((timestaMP)))))))))))))))))))))))))))",selectedDate)
                pass
            
                
                
                  
                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0
                
                merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
                for each_merchant in merchants_queryset:
                    merchantDict = fetching_user_details(each_merchant)
                    merchantsList.append(merchantDict)

                # merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber","createdOn").order_by("-createdOn") .skip(start).limit(per_page)
               
                # merchantsList=list(merchants_queryset)
                
                
                # for each_merchant in merchants_queryset:
                #     # merchantDict = fetching_user_details(each_merchant)
                #     merchantDict = {
                #         "id": each_merchant.id,
                #         "parentId": each_merchant.parentId,
                #         "merchantType": each_merchant.merchantType,
                #         "userName": each_merchant.userName,
                #         "amount": each_merchant.amount,
                #         "createdOn": each_merchant.createdOn,
                #     }
                #     merchantsList.append(merchantDict)
                # total_count= Users.objects(status__nin=[2]).count()
                
                query = Q(createdOn__gte=startDate,createdOn__lte=endDate)
                    # payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,status=1).order_by("-createdOn").all()
                if merchantId:
                        # payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])
                    query &= Q(userId=merchantId)
                # Query FundTransfers
                payins_queryset = WalletTransactions.objects(query).only('id','userId','amount','createdOn')
            
                # print("______________________________a___+____+_+_+_",payins_queryset.count(),startDate,endDate)

                # Filter by merchantId
                # if merchantId:
                #     payins_queryset = payins_queryset.filter(userId=merchantId)
                final_payin_transaction_Data = []
                
                
                # filters &= Q(userId=merchantId)
                # total_count = WalletTransactions.objects(filters).count()
                # payins_queryset=(
                #     WalletTransactions.objects(filters)
                #     .only("id", "userName","parentName","merchantType","createdOn","latest_amount")
                #     .order_by("-id")
                #     .skip(start)
                #     .limit(per_page)
                # )
                # final_payin_transaction_Data=list(payins_queryset)
                
                
               

                # Fetch valid users and their latest balances
                for each_payin in payins_queryset:
                    
                    # print("+++++++++++++++++++++++++++++++++++++++++",each_payin.userId)
                    userId = str(each_payin.userId.id)
                    # user_queryset = Users.objects(id=userId,status=1).first()  # Fetch user details

                    if each_payin.userId.merchantType == merchantType:
                        latest_transaction_query_set = WalletTransactions.objects(
                            userId=userId,
                            createdOn__gte=startDate,
                            createdOn__lte=endDate
                        ).order_by("-createdOn").first()
                        # user_queryset=(
                        # WalletTransactions.objects()
                        # .only("id","parentName","merchantType","createdOn")
                        # .order_by("-id")
                        # .skip(start)
                        # .limit(per_page)
                        # )
                    # 	# final_payin_transaction_Data=list(user_queryset)
                    # # total_count = WalletTransactions.objects(query).count()
                    
                    # 	print(latest_transaction_query_set,"(((((((((latest_transaction_query_set)))))))))")
                    # 	# print(str(latest_transaction_query_set.id),"(((((((((latest_transaction_query_set)))))))))")
                        if latest_transaction_query_set.amount:
                            latest_user_transaction_balance = float(latest_transaction_query_set.amount)
                        else:
                            latest_user_transaction_balance = 0

                        try:
                            if latest_transaction_query_set.userId.parentId:
                                parent_name = latest_transaction_query_set.userId.parentId.fullName
                            else:
                                parent_name = ""
                        except Exception as e:
                            parent_name = ""
                    
                        transaction_dict = {
                            'userName': each_payin.userId.fullName,
                            'parentName': parent_name,
                            'merchantType': each_payin.userId.merchantType,
                            'createdOn': latest_transaction_query_set.createdOn.strftime("%d-%m-%Y %I:%M:%S %p"),
                            'latest_amount': latest_user_transaction_balance
                        }
                        if transaction_dict not in final_payin_transaction_Data:
                            final_payin_transaction_Data.append(transaction_dict)

                total_count = len(final_payin_transaction_Data)
                # # Pagination setup
                # page = request.args.get(get_page_parameter(), type=int, default=1)
                # per_page = 1
                # total_count = len(final_payin_transaction_Data)
                # start = (page - 1) * per_page
                end = min(start + per_page, total_count)
                print("end",end)
                print("per_page",per_page)
                print("total_count",total_count)
                final_payin_transaction_Data = final_payin_transaction_Data[start:end]
                # final_payin_transaction_Data = total_payins

                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="balance_reports")

                
            else:
                print("form errors",form1.errors)  
            return render_template("super_admin_templates/balance_reports_list.html",
                pagination=pagination,
                final_payin_transaction_Data=final_payin_transaction_Data,
                payin_selectedDate=selectedDate.strftime(date_format),
                payin_merchantType=merchantType,
                payin_merchantId=merchantId,
                merchantsList=merchantsList,
                payout_selectedDate=payout_selectedDate,
                redirectval=redirectTo,
                payinsList=payinsList,
                form1=form1,
                snoCount=snoCount,
            )
          
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch balance transaction data!"
            print("(((((((((((((((((((((((((((((((((((((((((((((exception)))))))))))))))))))))))))))))))))))))))))))))")
            return render_template("super_admin_templates/balance_reports_list.html",
                error=error,
                pagination=pagination,
                snoCount=snoCount,
                final_payin_transaction_Data=final_payin_transaction_Data,
                payin_selectedDate=selectedDate.strftime(date_format),
                payin_merchantType=merchantType,
                payin_merchantId=merchantId,
                merchantsList=merchantsList,
                payout_selectedDate=payout_selectedDate,
                redirectval=redirectTo,
                payinsList=payinsList,
                form1=form1,
            )
    else:
        flash("The staff member does not have permission to view Payin balance report.", "danger")
        return redirect(url_for("admin.dashboard"))


# @admin_reports.route("/payout_balance_reports", methods=["POST", "GET"])
# @adminid_access_token_required
# def payout_balance_reports():
    
# 	payoutsList = []
# 	merchantsList = []
# 	final_transaction_Data = []
# 	pagination = None
# 	latest_balance = None
# 	form=BalanceRepoetsSearchForm(request.args)
# 	try:
# 		if not session.get("adminId"):
# 			return redirect("admin_login")

# 		payoutsList = []

# 		selectedDate = request.form.get("payout_selectedDate", "")
# 		merchantType = request.form.get("payout_merchantType", "")
# 		merchantId = request.form.get("payout_merchantId", "")
# 		merchantsList = []
# 		latest_balance = None

# 		date_format = "%d-%m-%Y"
# 		pagination = None
# 		payin_selectedDate = datetime.datetime.now().strftime(date_format)

        
# 		redirectTo = request.form.get("redirectTo", "payoutBalanceReports")

# 		# Date handling
# 		if selectedDate:
# 			try:
# 				selectedDate = datetime.datetime.strptime(selectedDate, date_format)
# 			except Exception as ve:
# 				app.logger.error("Date parsing error: %s", ve)
# 				selectedDate = datetime.datetime.now()
# 		else:
# 			selectedDate = datetime.datetime.now()

# 		startDate = selectedDate.replace(hour=0, minute=0, second=0, microsecond=0)
# 		endDate = selectedDate.replace(hour=23, minute=59, second=59, microsecond=999999)
# 		if form.validate():
            
# 			page = request.args.get(get_page_parameter(), type=int, default=1)
# 			per_page = 3  # Number of items per page
# 			start = (page - 1) * per_page
# 			snoCount = int(start)
# 			total_count=0
            
# 			merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
# 			for each_merchant in merchants_queryset:
# 				merchantDict = fetching_user_details(each_merchant)
# 				merchantsList.append(merchantDict)
                
# 			total_count= Users.objects(status__nin=[2]).count()
# 			# Query FundTransfers
# 			payouts_queryset = FundTransfers.objects(createdOn__gte=startDate, createdOn__lte=endDate)

# 			# Filter by merchantId
# 			if merchantId:
# 				payouts_queryset = payouts_queryset.filter(userId=merchantId)
            
# 			final_transaction_Data = []

# 			# Fetch valid users and their latest balances
# 			for each_payout in payouts_queryset:
# 				userId = str(each_payout.userId.id)
# 				user_queryset = Users.objects(id=userId,status=1).first()  # Fetch user details

# 				if user_queryset and user_queryset.merchantType == merchantType:
# 					latest_transaction_query_set = FundTransfers.objects(
# 						userId=userId,
# 						createdOn__gte=startDate,
# 						createdOn__lte=endDate
# 					).order_by("-createdOn").first()
# 					print(latest_transaction_query_set,"(((((((((latest_transaction_query_set)))))))))")
# 					print(str(latest_transaction_query_set.id),"(((((((((latest_transaction_query_set)))))))))")
# 					if latest_transaction_query_set.amount:
# 						latest_user_transaction_balance = float(latest_transaction_query_set.amount)
# 					else:
# 						latest_user_transaction_balance = 0

# 					try:
# 						if user_queryset.parentId:
# 							parent_name = user_queryset.parentId.fullName
# 						else:
# 							parent_name = ""
# 					except Exception as e:
# 						parent_name = ""
                
# 					transaction_dict = {
# 						'userName': user_queryset.fullName,
# 						'parentName': parent_name,
# 						'merchantType': user_queryset.merchantType,
# 						'createdOn': latest_transaction_query_set.createdOn.strftime("%d-%m-%Y %I:%M:%S %p"),
# 						'latest_amount': latest_user_transaction_balance
# 					}
# 					if transaction_dict not in final_transaction_Data: 
# 						final_transaction_Data.append(transaction_dict)


# 			# # Pagination setup
# 			# page = request.args.get(get_page_parameter(), type=int, default=1)
# 			# per_page = 1
# 			# total_count = len(final_transaction_Data)
# 			# start = (page - 1) * per_page
# 			# end = min(start + per_page, total_count)
# 			# total_payouts = final_transaction_Data[start:end]
# 			# final_transaction_Data = total_payouts

# 			pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="balance_reports")

# 			print("_____________Rrrrrrrrrr",redirectTo)
            

# 			return render_template("super_admin_templates/balance_reports_list.html",
                    
# 				pagination=pagination,
# 				final_transaction_Data=final_transaction_Data,
# 				payout_selectedDate=selectedDate.strftime(date_format),
# 				payout_merchantType=merchantType,
# 				payout_merchantId=merchantId,
# 				payin_selectedDate=payin_selectedDate,
# 				merchantsList=merchantsList,
# 				redirectval=redirectTo,
# 				form=form,
# 			)
# 		else:
# 			print("form errors",form.errors)  
# 	except Exception as e:
# 		app.logger.error(traceback.format_exc())
# 		error = "Unable to fetch balance transaction data!"
# 		return render_template("super_admin_templates/balance_reports_list.html",
# 			error=error,
# 			pagination=pagination,
# 			final_transaction_Data=final_transaction_Data,
# 			payout_selectedDate=selectedDate.strftime(date_format),
# 			payout_merchantType=merchantType,
# 			payout_merchantId=merchantId,
# 			payin_selectedDate=payin_selectedDate,
# 			merchantsList=merchantsList,
# 			redirectval=redirectTo,
# 			form=form,
# 		)



@admin_reports.route("/payout_balance_reports", methods=["POST", "GET"])
@adminid_access_token_required
def payout_balance_reports():
    
    payoutsList = []
    merchantsList = []
    final_transaction_Data = []
    snoCount = None
    pagination = None
    latest_balance = None
    redirectTo = request.form.get("redirectTo", "payoutBalanceReports")
    form2=BalancePayoutReportsSearchForm(request.args)
    try:
        if not session.get("adminId"):
            return redirect("admin_login")

        payoutsList = []
        merchantsList = []
        latest_balance = None
        
        selectedDate = request.args.get("payout_selectedDate", "")
        merchantType = request.args.get("payout_merchantType", "")
        merchantId = request.args.get("payout_merchantId", "")
        date_format = "%d-%m-%Y"

        payin_selectedDate = datetime.datetime.now().strftime(date_format)
        print("_________________________________________",merchantId,merchantType,selectedDate,redirectTo)      
        pagination = None
        
        redirectTo = request.form.get("redirectTo", "payoutBalanceReports")

        # Date handling
        if selectedDate:
            try:
                selectedDate = datetime.datetime.strptime(selectedDate, date_format)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                selectedDate = datetime.datetime.now()
        else:
            selectedDate = datetime.datetime.now()

        startDate = selectedDate.replace(hour=0, minute=0, second=0, microsecond=0)
        endDate = selectedDate.replace(hour=23, minute=59, second=59, microsecond=999999)
        
        if form2.validate():
            
            page = request.args.get(get_page_parameter(), type=int, default=1)
            per_page = 20  # Number of items per page
            start = (page - 1) * per_page
            snoCount = int(start)
            total_count=0
            
            merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
            for each_merchant in merchants_queryset:
                merchantDict = fetching_user_details(each_merchant)
                merchantsList.append(merchantDict)

                
            query = Q(createdOn__gte=startDate,createdOn__lte=endDate)
            # Query FundTransfers
            # payouts_queryset = FundTransfers.objects(createdOn__gte=startDate, createdOn__lte=endDate)

            # Filter by merchantId
            if merchantId:
                query &= Q(userId=merchantId)
                # payouts_queryset = payouts_queryset.filter(userId=merchantId)
            payouts_queryset = FundTransfers.objects(query).only('id','userId','amount','createdOn')
   
            final_transaction_Data = []

            # Fetch valid users and their latest balances
            for each_payout in payouts_queryset:
                userId = str(each_payout.userId.id)
                # user_queryset = Users.objects(id=userId,status=1).first()  # Fetch user details

                # if user_queryset and user_queryset.merchantType == merchantType:
                if each_payout.userId.merchantType == merchantType:
                    latest_transaction_query_set = FundTransfers.objects(
                        userId=userId,
                        createdOn__gte=startDate,
                        createdOn__lte=endDate
                    ).order_by("-createdOn").first()
     
                # if each_payin.userId.merchantType == merchantType:
                # 		latest_transaction_query_set = WalletTransactions.objects(
                # 			userId=userId,
                # 			createdOn__gte=startDate,
                # 			createdOn__lte=endDate
                # 		).order_by("-createdOn").first()
     
     
     
                    # print(latest_transaction_query_set,"(((((((((latest_transaction_query_set)))))))))")
                    # print(str(latest_transaction_query_set.id),"(((((((((latest_transaction_query_set)))))))))")
                    if latest_transaction_query_set.amount:
                        latest_user_transaction_balance = float(latest_transaction_query_set.amount)
                    else:
                        latest_user_transaction_balance = 0

                    try:
                        if user_queryset.parentId:
                            parent_name = user_queryset.parentId.fullName
                        else:
                            parent_name = ""
                    except Exception as e:
                        parent_name = ""
                
                    transaction_dict = {
                        'userName': user_queryset.fullName,
                        'parentName': parent_name,
                        'merchantType': user_queryset.merchantType,
                        'createdOn': latest_transaction_query_set.createdOn.strftime("%d-%m-%Y %I:%M:%S %p"),
                        'latest_amount': latest_user_transaction_balance
                    }
                    if transaction_dict not in final_transaction_Data: 
                        final_transaction_Data.append(transaction_dict)
            total_count = len(final_transaction_Data)

            # # Pagination setup
            # page = request.args.get(get_page_parameter(), type=int, default=1)
            # per_page = 1
            # total_count = len(final_transaction_Data)
            # start = (page - 1) * per_page
            # end = min(start + per_page, total_count)
            # total_payouts = final_transaction_Data[start:end]
            # final_transaction_Data = total_payouts
            end = min(start + per_page, total_count)
            print("end",end)
            print("per_page",per_page)
            print("total_count",total_count)
            final_transaction_Data = final_transaction_Data[start:end]
            
            pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="balance_reports")

            print("_____________Rrrrrrrrrr",redirectTo)
            

            
        else:
            print("form errors",form2.errors)  

        return render_template("super_admin_templates/balance_reports_list.html",
                    
            pagination=pagination,
            final_transaction_Data=final_transaction_Data,
            payout_selectedDate=selectedDate.strftime(date_format),
            payout_merchantType=merchantType,
            payout_merchantId=merchantId,
            payin_selectedDate=payin_selectedDate,
            merchantsList=merchantsList,
            redirectval=redirectTo,
            form2=form2,
            snoCount=snoCount,
        )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetch balance transaction data!"
        return render_template("super_admin_templates/balance_reports_list.html",
            error=error,
            pagination=pagination,
            final_transaction_Data=final_transaction_Data,
            payout_selectedDate=selectedDate.strftime(date_format),
            payout_merchantType=merchantType,
            payout_merchantId=merchantId,
            payin_selectedDate=payin_selectedDate,
            merchantsList=merchantsList,
            redirectval=redirectTo,
            form2=form2,
            snoCount=snoCount,
        )


@admin_reports.route("/cummulative_reports", methods=["POST", "GET"])
@adminid_access_token_required
def cummulative_reports():
    if not session.get("adminId"):
        return redirect("admin_login")  
    status = []
    merchantsList = []
    payoutsList = []
    final_transaction_Data = []
    adminId = session.get("adminId")
    page = ""
    total_count = ""
    per_page = ""
    snoCount = 0
    pagination = ""

    form = CummulativeReportsForm(request.args)

    permissionsList = check_permissions(session.get("adminId"),"cummulativeReportPermissions")

    if "view" in permissionsList:
        try:
            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                flash("Invalid Format","danger")
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            


            if form.validate(): 
                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20
                start = (page - 1) * per_page

                filters = Q(createdOn__gte=startDate,createdOn__lte=endDate)

                # total_count = Transactions.objects(filters).count()

                cummulative_reports_queryset = Transactions.objects(filters).only("id","categoryId","categoryName")

                final_transaction_Data = []

                for transaction in cummulative_reports_queryset:
                    unique_category_id = str(transaction.categoryId.id)

                    category_name = transaction.categoryName

                    category_total_amount = Transactions.objects(categoryId=unique_category_id,createdOn__gte=startDate, createdOn__lte=endDate).sum("amount")
                    category_total_txn_count = Transactions.objects(categoryId=unique_category_id,createdOn__gte=startDate, createdOn__lte=endDate).count()
                    category_total_commission_amount = Transactions.objects(categoryId=unique_category_id,createdOn__gte=startDate, createdOn__lte=endDate).sum("commissionCharges.commissionAmount")

                    category_dict = {
                        "category_name":category_name,
                        "category_total_amount":category_total_amount,
                        "category_total_txn_count":category_total_txn_count,
                        "category_total_commission_amount":category_total_commission_amount
                    }           

                    if category_dict not in final_transaction_Data:
                        final_transaction_Data.append(category_dict)  


                total_count = len(final_transaction_Data)
                end = min(start + per_page, total_count)
                total_payouts = final_transaction_Data[start:end]
                final_transaction_Data = total_payouts
                snoCount = start
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")
            else:
                print("form errors", form.errors)
            return render_template("super_admin_templates/cummulative_reports_list.html",
                pagination=pagination,
                final_transaction_Data=final_transaction_Data,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                form = form,
                page = page,
                snoCount = snoCount
            )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch balance transaction data!"
            return render_template("super_admin_templates/cummulative_reports_list.html",
                error=error,
                pagination=pagination,
                final_transaction_Data=final_transaction_Data,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                form = form,
                page = page,
                snoCount = snoCount
            )
    else:
        flash("The staff member does not have permission to view Cummulative report.", "danger")
        return redirect(url_for("admin.dashboard"))



@admin_reports.route("/account_summary_transactions", methods=["POST", "GET"])
@adminid_access_token_required
def account_summary_transactions():
    try:
        selectYear = None
        selectMonth = None
        startMonthYear = None
        endMonthYear = None
        current_year = None 
        last_year = None
        payinAccountSummaryList=[]
        payoutAccountSummaryList=[]
        
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        redirectTo = request.args.get("redirectTo","payinAccountSummary")
        if redirectTo :
            redirectval=redirectTo
        else :
            redirectval ="payinAccountSummary"
        form = AccountSummarySearchForm(request.args)
        permissionsList = check_permissions(session.get("adminId"), "accountSummaryPermissions")
        if "view" in permissionsList:
            merchantsList = []
            pagination = None
            current_year = datetime.datetime.now().year
            last_year = current_year - 1
            if form.validate():
                selectYear = request.args.get("selectYear", default=str(datetime.datetime.now().year))
                selectMonth = request.args.get("selectMonth", default=datetime.datetime.now().strftime("%B"))

            
                month_number = datetime.datetime.strptime(selectMonth, "%B").month
            
                startMonthYear = datetime.datetime(int(selectYear), month_number, 1)
                endMonthYear = datetime.datetime(int(selectYear), month_number, monthrange(int(selectYear), month_number)[1])

                if not startMonthYear and not  endMonthYear:
                    flash("Invalid date range provided.")
                    return render_template("super_admin_templates/account_summary_transaction_list.html")
                
                startMonthYear = startMonthYear.replace(hour=0, minute=0, second=0, microsecond=0)
                endMonthYear = endMonthYear.replace(hour=23, minute=59, second=59, microsecond=999999)

                startMonthYear = startMonthYear.replace(hour=0, minute=0, second=0, microsecond=0)
                endMonthYear = endMonthYear.replace(hour=23, minute=59, second=59, microsecond=999999)

                # Aggregation query to group transactions by day, summing amounts and counting transactions
                pipeline = [
                    {
                        "$match": {
                            "createdOn": {"$gte": startMonthYear, "$lte": endMonthYear},
                            "status":1,
                            "userType":"user"
                        }
                    },
                    {
                        "$group": {
                            "_id": {"$dateToString": {"format": "%Y-%m-%d", "date": "$createdOn"}},
                            "totalAmount": {"$sum": "$amount"},
                            "txnCount": {"$sum": 1}
                        }
                    },
                    {
                        "$sort": {"_id": 1}
                    }
                ]
                payinAccountSummaryList = []
                payin_aggregated = list(WalletTransactions.objects.aggregate(*pipeline))

                for each_payin in payin_aggregated:
                    payinAccountSummaryDict = {
                        "eachDayPayinDate":datetime.datetime.strptime(each_payin["_id"], "%Y-%m-%d").strftime("%d-%m-%Y"),
                        "eachDayPayinTotalAmount": formatINR("{:.2f}".format(each_payin["totalAmount"])),
                        "eachDayPayinTotalTxnCount": each_payin["txnCount"]
                    }
                    payinAccountSummaryList.append(payinAccountSummaryDict)

                payoutAccountSummaryList = []
                payout_aggregated = list(FundTransfers.objects.aggregate(*pipeline))
                for each_payout in payout_aggregated:
                    payoutAccountSummaryDict = {
                        "eachDayPayoutDate":datetime.datetime.strptime(each_payout["_id"], "%Y-%m-%d").strftime("%d-%m-%Y"),
                        "eachDayPayoutTotalAmount": formatINR("{:.2f}".format(each_payout["totalAmount"])),
                        "eachDayPayoutTotalTxnCount": each_payout["txnCount"]
                    }
                    payoutAccountSummaryList.append(payoutAccountSummaryDict)
            print("form errrrr",form.errors)
            return render_template("super_admin_templates/account_summary_transaction_list.html",
                selectYear=selectYear,selectMonth=selectMonth,
                startMonthYear=startMonthYear,endMonthYear=endMonthYear,
                current_year=current_year,
                last_year=last_year,
                payinAccountSummaryList=payinAccountSummaryList,
                payoutAccountSummaryList=payoutAccountSummaryList,
                redirectval=redirectval,
                form=form
                )    

        else:
            flash("The staff member does not have permission to view Account summary transactions.", "danger")
            return redirect(url_for("admin.dashboard"))

    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetch Account summary transaction report data!!"
        return render_template("super_admin_templates/account_summary_transaction_list.html", 
        error=error,
        selectYear=selectYear,
        selectMonth=selectMonth,
        current_year=current_year,
        last_year=last_year,
        startMonthYear=startMonthYear,
        endMonthYear=endMonthYear,
        payinAccountSummaryList=payinAccountSummaryList,
        payoutAccountSummaryList=payoutAccountSummaryList,
        redirectval=redirectval,
        form=form
        )
    
    
@admin_reports.route("/payin_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def payin_transaction_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    pagination=None
    payinList=[]
    selectStatus=""
    merchantsList=[]
    merchantId=""
    pgId=""
    pgList=[]
    siteTitleList=[]
    siteTitle=""
    snoCount=0

    form=PayinSearchForm(request.args)
    try:
        permissionsList = check_permissions(session.get("adminId"),"payinTransactionsPermissions")
        if "view" in permissionsList:
            payinList = []

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            selectStatus = request.args.get("selectStatus","")
            # merchantRefNo = request.args.get("merchantRefNo","")
            # orderId = request.args.get("orderId","")
            searchId=request.args.get("searchId","")
            # merchantName = request.args.get("merchantName","")
            merchantId = request.args.get("merchantId","")
            pgId = request.args.get("pgId","")
            transactionType = request.args.get("transactionType","")
            paymentModeId = request.args.get("paymentModeId","")
            subPaymentModeId = request.args.get("subPaymentModeId","")
            siteTitle = request.args.get("siteTitle","")
            siteTitleList=[]
            
            status = []
            merchantsList = []
            pgList = []
            transactionTypeCheck=["Credit"]
            total_credit_amount = 0.0
            total_success_credit_amount = 0.0
            total_debit_amount = 0.0
            processing_amount=0.0
            overall_credit_amount = 0.0
            overall_debit_amount = 0.0
            total_settled_amount = 0.0
            total_unsettled_amount = 0.0
            total_initiated_amount = 0.0
            total_failed_amount = 0.0
            refund_amount = 0.0
            paymentsModeList=[]


            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20 
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                merchantsList=list(merchants_queryset)
                
                pg_queryset = TransactionAPI.objects(transactionType="PaymentGateway",status__in=[0,1]).only("id","apiName" ).order_by("-id")
                pgList = list(pg_queryset)

                payments_mod_queryset = PaymentMode.objects(status__in=[0,1],walletType="Payin").only('id','paymentMode').order_by("-id").all()
                paymentsModeList=list(payments_mod_queryset)
                
                multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).order_by("-id").all()
                siteTitleList =  list(multiple_app_sites_queryset)

                if selectStatus == "All" or selectStatus == "":
                    status = [0,1,2,4,5]
                elif selectStatus == "Success":
                    status = [1]
                elif selectStatus == "Processing":
                    status = [2]
                elif selectStatus == "Refund":
                    status = [5]
                else:
                    status = [0]

                if transactionType == "All":
                    transactionTypeCheck=["Credit","Debit"]
                elif transactionType == "Debit":
                    transactionTypeCheck=["Debit"]
                else:
                    transactionTypeCheck=["Credit"]
               
            

                query=Q()
                if searchId:
                    # payin_queryset = WalletTransactions.objects(Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId)).order_by("-createdOn").all()
                    query &= (Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId))
                    # payin_queryset = payin_queryset.filter()
                else:
                    # payin_queryset = WalletTransactions.objects(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status,creditType__in=transactionTypeCheck).order_by("-createdOn").all()
                    query = Q(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status,creditType__in=transactionTypeCheck)

        
                    if merchantId:
                        # payin_queryset = payin_queryset.filter(userId__in=[merchantId])
                        query &= Q(userId__in=[merchantId])

                    if pgId:
                        # payin_queryset = payin_queryset.filter(paymentGatewayId__in=[pgId])
                        query &= Q(paymentGatewayId__in=[pgId])

                    if paymentModeId:
                        payments_mode_queryset = PaymentMode.objects(id=paymentModeId).first()
                        # payin_queryset = payin_queryset.filter(paymentType=payments_mode_queryset.paymentMode)
                        query &= Q(paymentType=payments_mode_queryset.paymentMode)
                    
                    if subPaymentModeId:
                        sub_payments_mode_queryset = SubPaymentModes.objects(id=subPaymentModeId).first()
                        # payin_queryset = payin_queryset.filter(subPaymentMode=sub_payments_mode_queryset.subPaymentModeType)
                        query &= Q(subPaymentMode=sub_payments_mode_queryset.subPaymentModeType)
                    
                    if siteTitle:
                        user_ids = Users.objects(siteTitle__icontains=siteTitle).only('id').values_list('id')
                        # payin_queryset = payin_queryset.filter(userId__in=user_ids)
                        query &= Q(userId__in=user_ids)
                total_count = WalletTransactions.objects(query).count()

                
                payin_queryset = WalletTransactions.objects(query).order_by("-createdOn").limit(per_page).skip(start)
                    

                for payout in payin_queryset:
                    if payout.creditType == "Credit" and payout.status == 1:
                        total_credit_amount += payout.amount
                    if payout.creditType == "Debit":
                        total_debit_amount += payout.amount
                    if payout.status == 2:
                        processing_amount += payout.amount
                    if payout.creditType == "Refund":
                        refund_amount += payout.amount
                    if payout.creditType == "Credit" and payout.status == 1:
                        total_success_credit_amount += payout.amount
                    elif payout.status == 0:
                        total_failed_amount += payout.amount

                # Round the results (if needed)
                total_credit_amount = round_last_digits(total_credit_amount or 0.0)
                total_debit_amount = round_last_digits(total_debit_amount or 0.0)
                processing_amount = round_last_digits(processing_amount or 0.0)
                refund_amount = round_last_digits(refund_amount or 0.0)
                total_success_credit_amount = round_last_digits(total_success_credit_amount or 0.0)
                total_failed_amount = round_last_digits(total_failed_amount or 0.0)
                
                total_settled_amount = round_last_digits(WalletTransactions.objects(status=1, settlementStatus=2).sum("amount") or 0.0)
                total_unsettled_amount = round_last_digits(WalletTransactions.objects(status=1, settlementStatus=1).sum("amount") or 0.0)
                total_initiated_amount = round_last_digits(WalletTransactions.objects(status=3).sum("amount") or 0.0)

                for each_pay_in in payin_queryset:
                    payInDict = fetching_payin_details(each_pay_in)
                    payinList.append(payInDict)
                
                overall_payins_queryset = WalletTransactions.objects(status__in=[1,2])
                overall_credit_amount = round(WalletTransactions.objects(status__in=[1,2],creditType="Credit").sum("amount") or 0.0,2)
                overall_debit_amount = round(WalletTransactions.objects(status__in=[1,2],creditType="Debit").sum("amount") or 0.0,2)


                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")
            else:
                print("form errors",form.errors)

            return render_template("super_admin_templates/payin_all_transactions.html",
                pagination=pagination,
                payinList=payinList,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                selectStatus=selectStatus,
                # merchantName=merchantName,
                # merchantRefNo=merchantRefNo,
                merchantsList=merchantsList,
                merchantId=merchantId,
                # orderId=orderId,
                searchId=searchId,
                transactionType=transactionType,
                pgId=pgId,
                pgList=pgList,
                paymentModeId=paymentModeId,
                subPaymentModeIdValue=subPaymentModeId,
                paymentsModeList=paymentsModeList,
                totalSucessCrediAmount=total_success_credit_amount,
                totalCreditAmount=total_credit_amount,
                totalDebitAmount=total_debit_amount,
                overAllCrediAmount=overall_credit_amount,
                overAllDebitAmount=overall_debit_amount,
                processingAmount=processing_amount,
                refundAmount=refund_amount,
                total_settled_amount=total_settled_amount,
                total_unsettled_amount=total_unsettled_amount,
                total_initiated_amount=total_initiated_amount,
                overall_credit_amount=overall_credit_amount,
                overall_debit_amount=overall_debit_amount,
                total_failed_amount=total_failed_amount,
                siteTitleList = siteTitleList,
                siteTitle=siteTitle,
                form=form,
                snoCount=snoCount
                )
        else:
            flash("The staff member does not have permission to view All transactions.", "danger")
            return redirect(url_for("admin.dashboard"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetch all transaction reports data!!"
        return render_template("super_admin_templates/payin_all_transactions.html", 
            error=error,
            pagination=pagination,
            payinList=payinList,
            selectStatus=selectStatus,
            # merchantName=merchantName,
            # merchantRefNo=merchantRefNo,
            merchantsList=merchantsList,
            merchantId=merchantId,
            pgId=pgId,
            pgList=pgList,
            # orderId=orderId,
            siteTitleList = siteTitleList,
            siteTitle=siteTitle,
            form=form
            )

# @transaction_report.route("/pay_in_transactions_reports",methods=["POST","GET"])
# def pay_in_transactions_reports():
#     try:
#         if not session.get("adminId"):
#             return redirect("admin_login")
#         adminId = session.get("adminId")
#         permissionsList = check_permissions(session.get("adminId"),"payinTransactionReportPermissions")
#         if "view" in permissionsList:
#             payInTransactionsList = []
#             merchantsList = []
#             apiDropdownList =[]
#             platformList = []

#             startDate = request.args.get("startDate","")
#             endDate = request.args.get("endDate","")
#             transactionId = request.args.get("transactionId","")
#             merchantName = request.args.get("merchantName","")
#             selectStatus = request.args.get("selectStatus","")
#             merchantId = request.args.get("merchantId","")
#             status = []

#             # Set default date format
#             date_format = "%d-%m-%Y"
#             pagination = None
#             try:
#                 if startDate:
#                     startDate = datetime.datetime.strptime(startDate, date_format)
#                     startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
#                 else:
#                     startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

#                 if endDate:
#                     endDate = datetime.datetime.strptime(endDate, date_format)
#                     endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
#                 else:
#                     endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
#             except Exception as ve:
#                 app.logger.error("Date parsing error: %s", ve)
#                 startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
#                 endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

#             merchants_queryset = Users.objects(status__nin=[2]).order_by("-id")
#             for each_merchant in merchants_queryset:
#                 merchantDict = fetching_user_details(each_merchant)
#                 merchantsList.append(merchantDict)
            

#             if selectStatus == "All" or selectStatus == "":
#                 status = [0,1,2,3,4,5]
#             elif selectStatus == "Success":
#                 status = [1]
#             elif selectStatus == "Processing":
#                 status = [2]
#             elif selectStatus == "Refund":
#                 status = [4,5]
#             else:
#                 status = [0]

#             wallet_transactions_queryset = WalletTransactions.objects(
#                 createdOn__gte=startDate,createdOn__lte=endDate,status__in=status).order_by("-id").all()
            
#             if merchantName:
#                 merchantIds = []
#                 merchants_queryset = Users.objects(fullName__icontains=merchantName)
#                 merchantIds = [str(each_merchant.id) for each_merchant in merchants_queryset]
#                 wallet_transactions_queryset = wallet_transactions_queryset.filter(userId__in=merchantIds)

#             if transactionId:
#                 wallet_transactions_queryset = wallet_transactions_queryset.filter(transactionId__icontains=transactionId)

#             if merchantId:
#                 wallet_transactions_queryset = wallet_transactions_queryset.filter(userId__in=[merchantId])

#             # Get the current page from the query parameters
#             page = request.args.get(get_page_parameter(), type=int, default=1)

#             per_page = 20  # Number of items per page

#             # Query the database for the current page's data
#             total_count = wallet_transactions_queryset.count()

#             start = (page - 1) * per_page

#             end = min(start + per_page, total_count)

#             total_payins = wallet_transactions_queryset[start:end]
            
#             snoCount = start
#             for each_pay_in in total_payins:
#                 snoCount +=1
#                 payIndDict = fetching_payin_details(each_pay_in)
#                 payIndDict["snoCount"]=snoCount
#                 payInTransactionsList.append(payIndDict)

#             apiname_queryset = TransactionAPI.objects(status__in=[0,1]).order_by("sorting")  
#             for each_payin_transaction in apiname_queryset:
#                 payin_transaction_dict = fetching_transaction_api_details(each_payin_transaction)
#                 apiDropdownList.append(payin_transaction_dict)     

#             # Pagination object for rendering pagination controls in the template
#             pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")

#             return render_template("super_admin_templates/pay_in_transactions_reports_list.html",
#                 pagination=pagination,
#                 selectStatus=selectStatus,
#                 merchantName=merchantName,
#                 transactionId=transactionId,
#                 startDate=startDate.strftime(date_format),
#                 endDate=endDate.strftime(date_format),
#                 payInTransactionsList=payInTransactionsList,
#                 merchantId=merchantId,
#                 merchantsList=merchantsList,
#                 platformList =platformList,
#                 apiDropdownList=apiDropdownList
#                 )
#         else:
#             flash("Staff member does not have given view payin transactions reports permissions!!")
#             return render_template("super_admin_templates/pay_in_transactions_reports_list.html")
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         error = "Unable to fetched pay in transactions data!!"
#         return render_template("super_admin_templates/pay_in_transactions_reports_list.html", 
#             error=error,
#             pagination=pagination,
#             selectStatus=selectStatus,
#             transactionId=transactionId,
#             merchantName=merchantName,
#             startDate=startDate.strftime(date_format),
#             endDate=endDate.strftime(date_format),
#             payInTransactionsList=payInTransactionsList,
#             merchantId=merchantId,
#             merchantsList=merchantsList,
#             platformList=platformList,
#             apiDropdownList=apiDropdownList
#             )

@admin_reports.route("/payin_success_transaction_reports",methods=["POST","GET"])
@adminid_access_token_required
def payin_success_transaction_reports():
    payinList=[]
    pagination=None
    merchantName=""
    orderId=""
    searchId=""
    merchantId=""
    merchantsList=[]
    merchantRefNo=""
    siteTitleList = []
    siteTitle=""
    snoCount=0

    form=PayinSuccessSearchForm(request.args)
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        permissionsList = check_permissions(session.get("adminId"),"payinsuccessTransactionsPermissions")
        if "view" in permissionsList:
            payinList = []
            merchantsList = []

            total_credit_amount = 0.0
            total_success_credit_amount = 0.0
            total_debit_amount = 0.0
            processing_amount=0.0
            overall_credit_amount = 0.0
            overall_debit_amount = 0.0
            refund_amount = 0.0

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            searchId=request.args.get("searchId","")
            merchantId = request.args.get("merchantId","")
            siteTitle = request.args.get("siteTitle","")
            siteTitleList=[]

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            if form.validate():
                
                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20 
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0


                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                merchantsList=list(merchants_queryset)

                query = Q(status=1)
                if searchId:
                    # payin_queryset = WalletTransactions.objects(Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId),status=1).order_by("-createdOn").all()
                    query &= (Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId))
                else:
                    # payin_queryset = WalletTransactions.objects(createdOn__gte=startDate,createdOn__lte=endDate,status=1).order_by("-createdOn").all()
                    query = Q(createdOn__gte=startDate,createdOn__lte=endDate,status=1)


                    if merchantId:
                        # payin_queryset = payin_queryset.filter(userId__in=[merchantId])
                        query &= Q(userId__in=[merchantId])
                    
                    if siteTitle:
                        # user_ids = Users.objects(siteTitle__icontains=siteTitle).values_list('id')
                        # payin_queryset = payin_queryset.filter(userId__in=user_ids)
                        user_ids = Users.objects(siteTitle__icontains=siteTitle).only('id').values_list('id')
                        # payin_queryset = payin_queryset.filter(userId__in=user_ids)
                        query &= Q(userId__in=user_ids)
                total_count = WalletTransactions.objects(query).count()

                payin_queryset = WalletTransactions.objects(query).order_by("-createdOn").limit(per_page).skip(start)

                snoCount = start

                # total_credit_amount = round(total_payins.filter(creditType="Credit", status=1).sum("amount") or 0.0,2)
                # total_debit_amount = round(total_payins.filter(creditType="Debit").sum("amount",) or 0.0,2)
                # processing_amount = round(total_payins.filter(creditType="Debit",status=2).sum("amount") or 0.0,2)
                # refund_amount = round(total_payins.filter(creditType="Refund",).sum("amount") or 0.0,2)
                # total_success_credit_amount=round(total_payins.filter(creditType="Credit",status=1).sum("amount") or 0.0,2)

                for payout in payin_queryset:
                    if payout.creditType == "Credit" and payout.status == 1:
                        total_credit_amount += payout.amount
                    if payout.creditType == "Debit":
                        total_debit_amount += payout.amount
                    if payout.creditType == "Debit" and payout.status == 2:
                        processing_amount += payout.amount
                    if payout.creditType == "Refund":
                        refund_amount += payout.amount
                    if payout.creditType == "Credit" and payout.status == 1:
                        total_success_credit_amount += payout.amount
                

                for each_pay_in in payin_queryset:
                    # snoCount +=1
                    payInDict = fetching_payin_details(each_pay_in)
                    # payInDict["snoCount"]=snoCount
                    payinList.append(payInDict)

                multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).order_by("-id").all()
                siteTitleList =  list(multiple_app_sites_queryset)

                overall_payouts_queryset = WalletTransactions.objects()
                overall_credit_amount = round(WalletTransactions.objects(creditType="Credit").sum("amount") or 0.0,2)
                overall_debit_amount = round(WalletTransactions.objects(creditType="Debit").sum("amount") or 0.0,2)
                # overall_credit_amount = round(overall_payouts_queryset.filter(.sum("amount") or 0.0,2)
                # overall_debit_amount = round(overall_payouts_queryset.filter().sum("amount") or 0.0,2)
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="success_payouts")
            else:
                print("form errors",form.errors)


                # Pagination object for rendering pagination controls in the template

            return render_template("super_admin_templates/payin_success_transaction_reports_list.html",
                pagination=pagination,
                payinList=payinList,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                merchantName=merchantName,
                orderId=orderId,
                searchId=searchId,
                merchantId=merchantId,
                merchantsList=merchantsList,
                merchantRefNo=merchantRefNo,
                totalSucessCrediAmount=total_success_credit_amount,
                totalCreditAmount=total_credit_amount,
                totalDebitAmount=total_debit_amount,
                overAllCrediAmount=overall_credit_amount,
                overAllDebitAmount=overall_debit_amount,
                processingAmount=processing_amount,
                refundAmount=refund_amount,
                siteTitleList = siteTitleList,
                siteTitle=siteTitle,
                form=form,snoCount=snoCount
                )
        else:
            flash("The staff member does not have permission to view Success transactions.", "danger")
            return redirect(url_for("admin.dashboard"))
            
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched success transaction reports data!!"
        return render_template("super_admin_templates/payin_success_transaction_reports_list.html", 
            error=error,
            payinList=payinList,
            pagination=pagination,
            # startDate=startDate.strftime(date_format),
            # endDate=endDate.strftime(date_format),
            merchantName=merchantName,
            orderId=orderId,
            searchId=searchId,
            merchantId=merchantId,
            merchantsList=merchantsList,
            merchantRefNo=merchantRefNo,
            siteTitleList = siteTitleList,
            siteTitle=siteTitle,
            form=form
            )

@admin_reports.route("/pending_payin_transactions", methods=["POST", "GET"])
@adminid_access_token_required
def pending_payin_transactions():
    pagination=None
    pendingPayinList=[]
    selectStatus=""
    orderId=""
    searchId=""
    merchantId=""
    merchantsList=[]
    merchantName=""
    siteTitleList = []
    siteTitle=""
    snoCount= ""
    form=PayinSuccessSearchForm(request.args)
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        permissionsList = check_permissions(session.get("adminId"),"payinpendingTransactionsPermissions")
        if "view" in permissionsList:

            startDate = request.args.get("startDate", "")
            endDate = request.args.get("endDate", "")
            selectStatus = request.args.get("selectStatus", "")
            orderId = request.args.get("orderId", "")
            searchId=request.args.get("searchId","")
            merchantName = request.args.get("merchantName", "")
            merchantId = request.args.get("merchantId", "")
            siteTitle = request.args.get("siteTitle","")
            siteTitleList=[]
            

            status = []
            pendingPayinList = []
            merchantsList = []
            overall_credit_amount = 0.0
            overall_debit_amount = 0.0
            total_pending_amount = 0.0

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20 
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                merchantsList=list(merchants_queryset)

                if selectStatus == "All" or selectStatus =="":
                    status = [0, 2]
                elif selectStatus == "Processing":
                    status = [2]
                else:
                    status = [0]

                query = Q()
                if searchId:
                    # payin_queryset = WalletTransactions.objects(Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId),).order_by("-createdOn").all()
                    query &= (Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId))
                else:
                    # payin_queryset = WalletTransactions.objects(createdOn__gte=startDate,createdOn__lte=endDate,status=2).order_by("-createdOn").all()

                    query = Q(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status)

                    if merchantId:
                        # payin_queryset = payin_queryset.filter(userId__in=[merchantId])
                        query &= Q(userId__in=[merchantId])
                    
                    if siteTitle:
                        user_ids = Users.objects(siteTitle__icontains=siteTitle).values_list('id')
                        # payin_queryset = payin_queryset.filter(userId__in=user_ids)
                        query &= Q(userId__in=user_ids)
                total_count = WalletTransactions.objects(query).count()

                payin_queryset = WalletTransactions.objects(query).order_by("-createdOn").limit(per_page).skip(start)

      

                total_pending_amount = round(payin_queryset.filter(status=0).sum("amount",) or 0.0,2)
                for each_pay_in in payin_queryset:
                    # snoCount +=1
                    payInDict = fetching_payin_details(each_pay_in)
                    # payInDict["snoCount"]=snoCount
                    pendingPayinList.append(payInDict)
                
                multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).order_by("-id").all()
                siteTitleList =  list(multiple_app_sites_queryset)

                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="payouts")
            else:
                print("form errors",form.errors)
            return render_template("super_admin_templates/pending_payin_transactions.html",
                                   pagination=pagination,
                                   pendingPayinList=pendingPayinList,
                                   selectStatus=selectStatus,
                                   orderId=orderId,
                                   searchId=searchId,
                                   merchantId=merchantId,
                                   merchantsList=merchantsList,
                                   startDate=startDate.strftime(date_format),
                                   endDate=endDate.strftime(date_format),
                                   merchantName=merchantName,
                                   overAllCrediAmount=overall_credit_amount,
                                   overAllDebitAmount=overall_debit_amount,
                                   totalPendingAmount=total_pending_amount,
                                   siteTitleList = siteTitleList,
                                   siteTitle=siteTitle,
                                   form=form,
                                   snoCount=snoCount
                                   )
        else:
            flash("The staff member does not have permission to view Pending payout transactions.", "danger")
            return redirect(url_for("admin.dashboard"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched payout pending transaction data!!"
        return render_template("super_admin_templates/pending_payin_transactions.html",
                               error=error,
                               pagination=pagination,
                               pendingPayinList=pendingPayinList,
                               selectStatus=selectStatus,
                               orderId=orderId,
                               searchId=searchId,
                               merchantId=merchantId,
                               merchantsList=merchantsList,
                               startDate=startDate.strftime(date_format),
                               endDate=endDate.strftime(date_format),
                               merchantName=merchantName,
                               siteTitleList = siteTitleList,
                               siteTitle=siteTitle,
                                   form=form)


@admin_reports.route("admin_download_pending_payin_transactions_csv_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_pending_payin_transactions_csv_reports():
    data_status={"responseStatus":0,"result":""}

    startDate = request.args.get("startDate", "")
    endDate = request.args.get("endDate", "")
    selectStatus = request.args.get("selectStatus", "")
    orderId = request.args.get("orderId", "")
    merchantId = request.args.get("merchantId", "")

    try:
        status = []
        # Set default date format
        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

        if selectStatus == "All" or selectStatus =="":
            status = [0, 2]
        elif selectStatus == "Processing":
            status = [2]
        else:
            status = [0]
   
        payin_queryset = WalletTransactions.objects(createdOn__gte=startDate, createdOn__lte=endDate, status__in=status).order_by("-createdOn").all()

        if orderId:
            payin_queryset = payin_queryset.filter(transactionUniqueId__icontains=orderId)

        if merchantId:
            payin_queryset = payin_queryset.filter(userId__in=[merchantId])

        reportData = admin_download_pending_payin_transactions_csv_reports(startDate,endDate,payin_queryset)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download pending payout report data!!"
        return data_status


@admin_reports.route("/payin_initiated_transactions", methods=["POST", "GET"])
@adminid_access_token_required
def payin_initiated_transactions():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    initiatedPayinList=[]
    pagination=None
    orderId=""
    searchId=""
    merchantId=""
    merchantsList=[]
    merchantName=""
    siteTitleList = []
    siteTitle=""
    snoCount=""
    form=PayinSuccessSearchForm(request.args)
    permissionsList = check_permissions(session.get("adminId"), "payinInitiatedTransactionsPermissions")
    if "view" in permissionsList:
        try:
            startDate = request.args.get("startDate", "")
            endDate = request.args.get("endDate", "")
            selectStatus = request.args.get("selectStatus", "")
            orderId = request.args.get("orderId", "")
            searchId=request.args.get("searchId","")
            merchantName = request.args.get("merchantName", "")
            merchantId = request.args.get("merchantId", "")
            siteTitle = request.args.get("siteTitle","")
            siteTitleList=[]

            status = []
            initiatedPayinList = []
            merchantsList = []

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            if form.validate():

                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20 
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0

                merchants_queryset = Users.objects(status__nin=[2]).only("id","fullName","phoneNumber").order_by("-createdOn")
                merchantsList=list(merchants_queryset)
                
                multiple_app_sites_queryset = MultipleAppSites.objects(status__in=[0,1]).order_by("-id").all()
                siteTitleList =  list(multiple_app_sites_queryset)

                # Set status to 3 for initiated transactions
                status = [3]
                query = Q()
                if searchId:
                    # payin_queryset = WalletTransactions.objects(Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId),status=3).order_by("-createdOn").all()
                    query &= (Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId) & Q(status=3))
                else:
                    # payin_queryset = WalletTransactions.objects(createdOn__gte=startDate,createdOn__lte=endDate,status=3).order_by("-createdOn").all()
                    query = Q(createdOn__gte=startDate,createdOn__lte=endDate,status=3)

                    if merchantId:
                        # payin_queryset = payin_queryset.filter(userId__in=[merchantId])
                        query &= Q(userId__in=[merchantId])
                    
                    if siteTitle:
                        user_ids = Users.objects(siteTitle__icontains=siteTitle).values_list('id')
                        # payin_queryset = payin_queryset.filter(userId__in=user_ids)
                        query &= Q(userId__in=user_ids)
                
                total_count = WalletTransactions.objects(query).count()

                payin_queryset = WalletTransactions.objects(query).order_by("-createdOn").limit(per_page).skip(start)

                snoCount = start
                for each_pay_in in payin_queryset:
                    # snoCount += 1
                    payInDict = fetching_payin_details(each_pay_in)
                    # payInDict["snoCount"] = snoCount
                    initiatedPayinList.append(payInDict)

                # Pagination object for rendering pagination controls in the template
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="initiated_payins")
            else:
                print("form errors",form.errors)

            return render_template("super_admin_templates/payin_initiated_transactions.html",
                                   pagination=pagination,
                                   initiatedPayinList=initiatedPayinList,
                                   selectStatus=selectStatus,
                                   orderId=orderId,
                                   searchId=searchId,
                                   merchantId=merchantId,
                                   merchantsList=merchantsList,
                                   startDate=startDate.strftime(date_format),
                                   endDate=endDate.strftime(date_format),
                                   merchantName=merchantName,
                                   siteTitleList = siteTitleList,
                                   siteTitle=siteTitle,
                                   form=form,
                                   snoCount=snoCount

                                   )
        
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch initiated transaction data!!"
            return render_template("super_admin_templates/payin_initiated_transactions.html",
                                   error=error,
                                   pagination=pagination,
                                   initiatedPayinList=initiatedPayinList,
                                   selectStatus=selectStatus,
                                   orderId=orderId,
                                   searchId=searchId,
                                   merchantId=merchantId,
                                   merchantsList=merchantsList,
                                #    startDate=startDate.strftime(date_format),
                                #    endDate=endDate.strftime(date_format),
                                   merchantName=merchantName,
                                   siteTitleList = siteTitleList,
                                   siteTitle=siteTitle,
                                   form=form)
    
    else:
        flash("The staff member does not have permission to view Initiated transactions.", "danger")
        return redirect(url_for("admin.dashboard"))


@admin_reports.route("/operator_income_reports", methods=["POST", "GET"])
@adminid_access_token_required
def operator_income_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    permissionsList = check_permissions(session.get("adminId"),"operatorIncomeReportPermissions")
    pagination = None
    final_transaction_Data = []
    operator_report_data = []
    form=OprationIncomeReportsForm(request.args)
    if "view" in permissionsList:
        try:
            operator_report_data = []

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            final_transaction_Data = []
            
            print("_________________________________________",startDate,endDate)
            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            

            if form.validate():
                
                page = request.args.get(get_page_parameter(), type=int, default=1)
                per_page = 20  # Number of items per page
                start = (page - 1) * per_page
                snoCount = int(start)
                total_count=0
         
                operator_income_reports_queryset = Transactions.objects(createdOn__gte=startDate, createdOn__lte=endDate)
                operator_income_reports_queryset = list(operator_income_reports_queryset)

                final_transaction_Data = []
                unique_operators = set()

                for transaction in operator_income_reports_queryset:
                    if not transaction.operatorId:
                        continue
                    
                    unique_operator_id = str(transaction.operatorId.id)

                    if unique_operator_id in unique_operators:
                        continue  # Skip to the next transaction if already processed
                    
                    unique_operators.add(unique_operator_id)
                    operatorName = transaction.operatorId.operatorName



                    operator_income_total_amount = Transactions.objects(operatorId=unique_operator_id,createdOn__gte=startDate, createdOn__lte=endDate).sum("amount")

                    operator_income_total_txn_count = Transactions.objects(operatorId=unique_operator_id,createdOn__gte=startDate, createdOn__lte=endDate).count()

                    transactions = Transactions.objects(
                        operatorId=unique_operator_id,
                        createdOn__gte=startDate,
                        createdOn__lte=endDate
                    )

                    total_gst_amount = 0
                    total_tds_amount = 0
                    total_charge_val = 0

                    
                    transactionsList=[]
                    for transaction in transactions:
                        
                        
                        
                        
                        if transaction and transaction.commissionCharges:
                            gst_amount = transaction.commissionCharges.get("gstAmount", 0)
                            tds_amount = transaction.commissionCharges.get("tdsAmount", 0)
                            charge_amount = transaction.commissionCharges.get("chargeAmount", 0)
                        

                            if isinstance(gst_amount, (float)):
                                total_gst_amount += gst_amount

                            if isinstance(tds_amount, (float)):
                                total_tds_amount += tds_amount

                            if isinstance(charge_amount, (float)):
                                total_charge_val += charge_amount
                        commissionCharges ={
                            "chargeAmount":transaction.commissionCharges.get("chargeAmount", 0),
                            "gstAmount":transaction.commissionCharges.get("gstAmount", 0),
                            "tdsAmount":transaction.commissionCharges.get("tdsAmount", 0)
                        }
      
                        transactionsdict={
               
                            # "fullName":transaction.userId.fullName,
                            "transactionId":transaction.transactionId,
                            "categoryName":transaction.categoryName,
                            "serviceName":transaction.serviceName,
                            # "operatorName":transaction.operatorId.operatorName,
                            "amount":transaction.amount,
                            "commissionCharges":commissionCharges
                        }
                        try:
                            if transaction.userId:
                                transactionsdict["fullName"]=transaction.userId.fullName
                            else:
                                transactionsdict["fullName"]=""
                        except:
                            transactionsdict["fullName"]=""
                        try:
                            if transaction.operatorId:
                                transactionsdict["operatorName"]=transaction.operatorId.operatorName
                            else:
                                transactionsdict["operatorName"]=""
                        except:
                            transactionsdict["operatorName"]=""
                        transactionsList.append(transactionsdict) 

                    commissionCharges = {
                        "total_gst_amount": total_gst_amount,
                        "total_tds_amount": total_tds_amount,
                        "total_charge_val": total_charge_val
                    }

                    # Construct the final category_dict
                    category_dict = {
                        "operator_name": operatorName,
                        "operator_income_total_amount": operator_income_total_amount,
                        "operator_income_total_txn_count": operator_income_total_txn_count,
                        "commissionCharges": commissionCharges,  # Include the commissionCharges object
                        "transactions": transactionsList
                    }

                    # Ensure unique entries for each operator
                    if category_dict not in final_transaction_Data:
                        final_transaction_Data.append(category_dict) 

                total_count = len(final_transaction_Data)
                # page = request.args.get(get_page_parameter(), type=int, default=1)
                # per_page = 20
                # total_count = len(final_transaction_Data)
                # start = (page - 1) * per_page
                # end = min(start + per_page, total_count)
                # total_payouts = final_transaction_Data[start:end]
                # final_transaction_Data = total_payouts
                end = min(start + per_page, total_count)
                print("end",end)
                print("per_page",per_page)
                print("total_count",total_count)
                final_transaction_Data = final_transaction_Data[start:end]
    
                pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="operator_income_report")

            else:
                print("form errors",form.errors)  	

            return render_template("super_admin_templates/operator_income_reports_list.html",
                pagination=pagination,
                final_transaction_Data=final_transaction_Data,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                form=form,
                snoCount=snoCount,	
                operator_report_data=operator_report_data,

            )
            
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to fetch balance transaction data!"
            return render_template("super_admin_templates/operator_income_reports_list.html",
                error=error,
                pagination=pagination,
                final_transaction_Data=final_transaction_Data,
                form=form,
                snoCount=snoCount,
                operator_report_data=operator_report_data,
            )
    else:
        flash("The staff member does not have permission to view Operator Income Reports.", "danger")
        return redirect(url_for("admin.dashboard"))
      




@admin_reports.route("/admin_check_payin_status", methods=["POST"])
@adminid_access_token_required
@csrf.exempt
def admin_check_payin_status():
    data_status = {"responseStatus":0,"result":""}
    pgOrderId = request.form.get("pgOrderId","")
    print(pgOrderId,"pgOrderId")
    responseDict = {}
    payinPaymentstatusResponseDict = {}
    try:
        if not session.get("adminId"):
            return redirect("admin_login")

        if not pgOrderId:
            data_status["result"]="Required fields are missing!!"
            return data_status
        
        wallet_transactions_queryset = WalletTransactions.objects(Q(pgOrderId=pgOrderId) | Q(orderId=pgOrderId)).first()
        if not wallet_transactions_queryset:
            data_status["result"]="Invalid Order Id!!"
            return data_status

        order_id = str(wallet_transactions_queryset.orderId)
        payInPaymentGatewayId = str(wallet_transactions_queryset.paymentGatewayId.id)
        payin_gate_way_queryset = TransactionAPI.objects(id=str(payInPaymentGatewayId)).first()
        if not payin_gate_way_queryset:
            data_status["result"]="Invalid request found!!"
            return data_status
        paymentGateWayCode = payin_gate_way_queryset.code
        paramsList = payin_gate_way_queryset.paramsList
        autoSettlement = payin_gate_way_queryset.autoSettlement
        txnDate = payin_gate_way_queryset.createdOn.strftime("%d-%m-%Y")

        ############################################## Slab Calculation for Payin #########################################################################
        # payment_mode_queryset = PaymentMode.objects(paymentMode="UPI").first()
        # paymentModeId = str(payment_mode_queryset.id)
        # sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType="UPI").first()
        # subPaymentModeId = str(sub_payment_mode_queryset.id)
        patternId = str(wallet_transactions_queryset.userId.patternId.id)

        ###################################################################################################################################################
        
        if paymentGateWayCode == "AccurePay_PayIn":
            get_api_key = ""
            get_salt = ""
            get_base_url=''
            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                if get_key == "api_key":
                    get_api_key = each_key.get("value")
                    
                if get_key == "salt":
                    get_salt = each_key.get("value")

                if get_key == "base_url":
                    get_base_url = each_key.get("value")
            
            ######################################################### Check Accurepay Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_accurepay_payin_paymentstatus(get_api_key,get_salt,get_base_url,pgOrderId)
            ########################################################################################################################################################

        elif paymentGateWayCode == "WowPe_Payin":
            get_api_key = ""
            get_secret_key = ""
            get_base_url=''
            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                if get_key == "api_key":
                    get_api_key = each_key.get("value")
                    
                if get_key == "secret_key":
                    get_secret_key = each_key.get("value")

                if get_key == "base_url":
                    get_base_url = each_key.get("value")


            ######################################################### Check Wowpe Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_wowpe_payin_paymentstatus(get_api_key,get_secret_key,get_base_url,pgOrderId)
            ########################################################################################################################################################

        elif paymentGateWayCode == "Fstac_Payin":
            get_api_key = ""
            get_secret_key = ""
            get_base_url=''
            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                if get_key == "api_key":
                    get_api_key = each_key.get("value")
                    
                if get_key == "secret_key":
                    get_secret_key = each_key.get("value")

                if get_key == "base_url":
                    get_base_url = each_key.get("value")


            ######################################################### Check Fstac Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_fstac_payin_paymentstatus(get_api_key,get_secret_key,get_base_url,pgOrderId)
            ########################################################################################################################################################

        elif paymentGateWayCode == "Payu_Payin":
            get_api_key = ""
            get_secret_key = ""
            get_base_url = ""
            get_client = ""
            get_salt = ""

            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                if get_key == "api_key":
                    get_api_key = each_key.get("value")
                    
                if get_key == "secret_key":
                    get_secret_key = each_key.get("value")

                if get_key == "base_url":
                    get_base_url = each_key.get("value")

                if get_key == "client_id":
                    get_client = each_key.get("value")

                if get_key == "salt":
                    get_salt = each_key.get("value")


            print(get_api_key,"get_api_key1")
            print(get_secret_key,"get_secret_key1")
            print(get_base_url,"get_base_url1")
            print(get_client,"get_client1")
            print(get_salt,"get_salt1")
            ######################################################### Check PayU Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_payu_payin_paymentstatus(get_api_key,get_salt,get_base_url,pgOrderId)
            ########################################################################################################################################################
        elif paymentGateWayCode == "Lyra_Payin":
            user_name = ""
            get_base_url = ""
            password = ""

            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                get_key = each_key.get("key")
                if get_key == "base_url":
                    get_base_url = each_key.get("value")
                if get_key == "user_name":
                    user_name = each_key.get("value")
                if get_key == "password":
                    password = each_key.get("value")
            ######################################################### Check Lyra Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_lyra_payin_paymentstatus(get_base_url,str(wallet_transactions_queryset.transactionId),user_name,password)
            print(payinPaymentstatusResponseDict,"(((((((((payinPaymentstatusResponseDict)))))))))")
            ########################################################################################################################################################

        elif paymentGateWayCode == "Getepay_Payin":
            mid = ""
            get_base_url = ""
            callback_url = ""
            return_url=""
            encryption_key = ""
            encryption_iv = ""
            terminalId = ""
            vpa = ""
            for each_key in paramsList:
                get_key = each_key.get("key")
                if get_key == "mid":
                    mid = each_key.get("value")
                if get_key == "get_base_url":
                    get_base_url = each_key.get("value")
                if get_key == "callback_url":
                    callback_url = each_key.get("value")
                if get_key == "return_url":
                    return_url = each_key.get("value")
                if get_key == "encryption_key":
                    encryption_key = each_key.get("value")
                if get_key == "encryption_iv":
                    encryption_iv = each_key.get("value")
                if get_key == "terminalId":
                    terminalId = each_key.get("value")
                if get_key == "vpa":
                    vpa = each_key.get("value")
           
            print(mid, str(wallet_transactions_queryset.transactionId), terminalId,"((((((((((((((((((((((KEYS FOR GETEPAY))))))))))))))))))))))")
            # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+"TPSL"+str(orderId)
            # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+str(orderId)
            transactionType="single"
            ###################################################################### Get Payin Code ############################################################################
            payinPaymentstatusResponseDict = getepay_status_check(mid, str(wallet_transactions_queryset.statusCheckId), terminalId, encryption_key, encryption_iv, get_base_url)
            ##################################################################################################################################################################
            print(payinPaymentstatusResponseDict,"((((((((((((((((((payinPaymentstatusResponseDict in get epayin))))))))))))))))))")
        elif paymentGateWayCode == "Worldline_Payin":
            get_base_url = ""
            callback_url = ""
            api_key = ""
            secret_key = ""
            merchantIdentifier = ""
            api_encryption_key = ""
            requestType = ""
            transactionType = ""
            encryption_iv = ""
            graampay_check = ""
            for each_key in paramsList:
                get_key = each_key.get("key")
                get_key = each_key.get("key")
                if get_key == "get_base_url":
                    get_base_url = each_key.get("value")
                if get_key == "merchantIdentifier":
                    merchantIdentifier = each_key.get("value")
                if get_key == "callback_url":
                    callback_url = each_key.get("value")
                if get_key == "encryption_key":
                    api_encryption_key = each_key.get("value")
                if get_key == "encryption_iv":
                    encryption_iv = each_key.get("value")
                if get_key == "transactionType":
                    transactionType = each_key.get("value")
                if get_key == "requestType":
                    requestType = each_key.get("value")
        
            print(mid, str(wallet_transactions_queryset.transactionId),"((((((((((((((((((((((KEYS FOR world))))))))))))))))))))))")
            # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+"TPSL"+str(orderId)
            # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+str(orderId)
            ###################################################################### Get Payin Code ############################################################################
            payinPaymentstatusResponseDict = worldline_status_check(wallet_transactions_queryset.statusCheckId, txnDate, merchantIdentifier, api_encryption_key, encryption_iv, get_base_url)
            ##################################################################################################################################################################
            print(payinPaymentstatusResponseDict,"((((((((((((((((((payinPaymentstatusResponseDict in get epayin))))))))))))))))))")

        else:
            data_status["result"]="Please contact to admin to enable payin option!!"
            return data_status

        if payinPaymentstatusResponseDict.get("responseStatus") == 1:
            if payinPaymentstatusResponseDict.get("bankRefNo"):
                bank_reference_number = payinPaymentstatusResponseDict.get("bankRefNo")
            else:
                bank_reference_number = wallet_transactions_queryset.bankRefId

            if payinPaymentstatusResponseDict.get("paymentStatus") == 1:
                order_queryset = WalletTransactions.objects(orderId=order_id).first()
                amount=float(order_queryset.amount)
                transactionAmount = float(order_queryset.amount)
                errorMessage=""
                if (float(payinPaymentstatusResponseDict.get("orderAmount")) >= float(amount)) and order_queryset.status!=6:
                    amountstatus = 1
                    errorMessage = "Success"
                else:
                    amountstatus = 6
                    errorMessage = "Insufficient amount credited!!"
                
                if order_queryset.status!=1 and amountstatus==1:
                    userId=str(order_queryset.userId.id)
                    walletId=str(order_queryset.id)
                    paymentMode=payinPaymentstatusResponseDict.get('payment_mode')
                    cardType = str(wallet_transactions_queryset.cardType)
                    if cardType=="":
                        cardType=payinPaymentstatusResponseDict.get('cardType')
                    payment_mode_queryset = PaymentMode.objects(paymentMode=str(paymentMode)).first()
                    paymentModeId=""
                    subPaymentModeId=""
                    commissionCharges={}
                    if payment_mode_queryset:
                        paymentModeId = str(payment_mode_queryset.id)
                        if cardType!="":
                            subPaymentMode=cardType
                            sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=str(subPaymentMode)).first()
                            if sub_payment_mode_queryset:
                                subPaymentModeId = str(sub_payment_mode_queryset.id)
                        else:
                            subPaymentMode=paymentMode
                            sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=str(subPaymentMode)).first()
                            if sub_payment_mode_queryset:
                                subPaymentModeId = str(sub_payment_mode_queryset.id)

                        if subPaymentModeId=="":
                            subPaymentMode=paymentMode
                            sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=str(subPaymentMode)).first()
                            if sub_payment_mode_queryset:
                                subPaymentModeId = str(sub_payment_mode_queryset.id)

                    print(subPaymentModeId,"(((((((((((subPaymentModeId)))))))))))")
                    print(paymentModeId,"(((((((((((paymentModeId)))))))))))")
                    print(patternId,"(((((((((((patternId)))))))))))")
                    print(payInPaymentGatewayId,"(((((((((((payInPaymentGatewayId)))))))))))")
                    if subPaymentModeId!="" and paymentModeId!="" and patternId!="":
                        commissionCharges = slab_calculation_for_payin_merchant(amount,paymentModeId,subPaymentModeId,patternId)
                        if commissionCharges.get("transactionAmount"):
                            transactionAmount=commissionCharges.get("transactionAmount")
                        else:
                            transactionAmount=transactionAmount
                    
                    pgOrderId = str(order_queryset.pgOrderId)
                    
                    
                    transaction_id=str(order_queryset.transactionId)

                    balanceResult=user_payin_balance_update(str(order_queryset.userId.id),float(transactionAmount),"Credit",str(payInPaymentGatewayId))
                    if balanceResult.get('responseStatus')==0:
                        data_status["result"]="Unable to connect with server. Please Try again."
                        return data_status
                                
                    
                    payinbalancelogs_queryset=PayinBalanceLogs(
                        transactionAPIId=str(payInPaymentGatewayId),
                        userId=str(order_queryset.userId.id),
                        previousBalance=round_last_digits(float(balanceResult.get('transactionPreviousBalance'))),
                        currentBalance=round_last_digits(float(balanceResult.get('transactionCurrentBalance'))),
                        orderId=order_queryset.orderId,
                        amount=round_last_digits(float(amount)),
                        grandTotal=round_last_digits(float(transactionAmount)),
                        transferType="Credit",
                        userType="user",
                        transactionId=transaction_id,
                        createdOn=datetime.datetime.now(),
                        status=1
                        ).save()

                    order_queryset.update(
                        status=1,payInResponseCallBackData=payinPaymentstatusResponseDict.get("transactionData"),
                        responseCallBackTime=datetime.datetime.now(),
                        transactionId=transaction_id,bankRefId=bank_reference_number,errorMessage=payinPaymentstatusResponseDict.get("message"),grandTotal=round_last_digits(float(transactionAmount)),walletLog="Wallet Balance is added with the amount of " + str(amount) + ".",previousBalance=round_last_digits(float(balanceResult.get('userPreviousBalance'))),currentBalance=round_last_digits(float(balanceResult.get('userCurrentBalance'))),commissionCharges=commissionCharges,pgOrderId=str(payinPaymentstatusResponseDict.get('pgOrderId')),customerVpa=str(payinPaymentstatusResponseDict.get('customerVpa')),currency=str(payinPaymentstatusResponseDict.get('currency')),cardmasked=str(payinPaymentstatusResponseDict.get('cardmasked')),paymentType=paymentMode)
                    if paymentModeId!="":
                        order_queryset.update(paymentModeId=ObjectId(paymentModeId))
                    if subPaymentModeId!="":
                        order_queryset.update(subPaymentModeId=ObjectId(subPaymentModeId))

                    if autoSettlement==True:
                        try:
                            settlement_response=merchant_payin_auto_settlement(str(userId),str(walletId),str(payInPaymentGatewayId))
                            print(settlement_response,"settlement_response")
                            pass
                        except Exception as e:
                            pass
                    try:
                        merchantName = str(order_queryset.userId.fullName)
                        trnsactionDate = datetime.datetime.now().astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p")
                        mail_subject = "Load Funds for Graam Pay from Merchant " + merchantName + "."
                        sender_mail_query = SenderMails.objects(status=1,mailType="Payin Transactions Mail").first()
                        mail_data = {
                        "merchantName":merchantName,
                        "amount":formatINR("{:.2f}".format(float(amount))),
                        "transactionId":str(order_queryset.transactionId),
                        "paymentMode":paymentMode,
                        "cardNumber":str(payinPaymentstatusResponseDict.get('cardmasked')),
                        "orderId":str(order_queryset.orderId),
                        "bankRefId":str(bank_reference_number),
                        "transactionDate":trnsactionDate,
                        }
                        if sender_mail_query:
                            sendermailsList = sender_mail_query.mailsList
                            recipients_list = sendermailsList
                            template_name = "emails/loadfunds.html"
                            
                            mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                            
                            merchant_mail_subject = "Payment Transaction Alert From Graam Pay"
                            merchant_recipients_list = [order_queryset.userId.email]

                            mailoutputData = send_asynchronous_email(merchant_mail_subject, merchant_recipients_list, template_name, mail_data)

                    except Exception as e:
                        app.logger.error(traceback.format_exc())
                        pass

                    try:
                        user_queryset=Users.objects(id=str(order_queryset.userId.id)).first()
                        if user_queryset.parentId and commissionCharges.get("slabId") != None:
                            user_parent_payin_commission_details(str(user_queryset.parentId.id),amount,payInPaymentGatewayId,order_queryset.transactionId,str(paymentModeId),str(subPaymentModeId),commissionCharges.get("chargeAmount"),commissionCharges.get("chargeValue"),commissionCharges.get("chargeType"),str(user_queryset.id),float(commissionCharges.get("gstAmount")),float(commissionCharges.get("tdsAmount")))
                    except Exception as e:
                        app.logger.error(traceback.format_exc())
                        pass
                else:
                    order_queryset.update(status=amountstatus,payInResponseCallBackData=payinPaymentstatusResponseDict.get("transactionData"),responseCallBackTime=datetime.datetime.now(),transactionId=order_queryset.transactionId,bankRefId=bank_reference_number,currency=payinPaymentstatusResponseDict.get("currency"),grandTotal=round_last_digits(float(transactionAmount)),walletLog="Wallet Balance is added with the amount of " + str(amount) + ".",pgOrderId=str(payinPaymentstatusResponseDict.get('pgOrderId')),customerVpa=str(payinPaymentstatusResponseDict.get('customerVpa')),errorMessage=errorMessage,cardmasked=str(payinPaymentstatusResponseDict.get('cardmasked')))

            elif payinPaymentstatusResponseDict.get("paymentStatus")==0 or payinPaymentstatusResponseDict.get("paymentStatus")==4:
                order_queryset = WalletTransactions.objects(orderId=order_id).first()
                amount=float(order_queryset.amount)
                if order_queryset.status==1:
                    amount=float(order_queryset.amount)
                    transactionAmount = float(order_queryset.grandTotal)
                    transaction_id=order_queryset.transactionId
                    
                    balanceResult=user_payin_balance_update(str(order_queryset.userId.id),float(order_queryset.grandTotal),"Debit",str(payInPaymentGatewayId))
                    if balanceResult.get('responseStatus')==0:
                        data_status["result"]="Unable to connect with server. Please Try again."
                        return data_status
                        
                    payinbalancelogs_queryset=PayinBalanceLogs(
                        transactionAPIId=str(payInPaymentGatewayId),
                        userId=str(order_queryset.userId.id),
                        previousBalance=float(balanceResult.get('transactionPreviousBalance')),
                        currentBalance=float(balanceResult.get('transactionCurrentBalance')),
                        orderId=order_queryset.orderId,
                        amount=round_last_digits(float(amount)),
                        grandTotal=round_last_digits(float(order_queryset.grandTotal)),
                        transferType="Debit",
                        userType="user",
                        transactionId=transaction_id,
                        createdOn=datetime.datetime.now(),
                        status=1
                        ).save()

                    rorderId = random_digit_generate(16)
                    wallet_transaction_table = WalletTransactions(
                        userId = str(order_queryset.userId.id),
                        amount = round_last_digits(float(order_queryset.amount)),
                        grandTotal=round_last_digits(float(order_queryset.grandTotal)),
                        paymentGatewayId = str(payInPaymentGatewayId),
                        currency=order_queryset.currency,
                        paymentType = order_queryset.paymentType,
                        creditType = "Debit",
                        transactionId = transaction_id,
                        transactionData = payinPaymentstatusResponseDict.get("transactionData"),
                        orderId = str(rorderId),
                        walletLog="Wallet Balance is refunded with the amount of " + str(order_queryset.amount) + ".",
                        userType="user",
                        createdBy = None,
                        createdOn = datetime.datetime.now(),
                        location = "",
                        platform = "api",
                        agent = "",
                        customerEmail = order_queryset.customerEmail,
                        customerName = order_queryset.customerName,
                        customerPhonenumber = order_queryset.customerPhonenumber,
                        previousBalance=round_last_digits(float(balanceResult.get('userPreviousBalance'))),
                        currentBalance=round_last_digits(float(balanceResult.get('userCurrentBalance'))),
                        paymentLinkId = None,
                        PaymentButtonId = None,
                        paymentPageId = None,
                        errorMessage = "Refunded",
                        paymentChannel = "Wowpe",
                        bankRefId=order_queryset.bankRefId,
                        cardmasked="",
                        pgOrderId=order_queryset.orderId,
                        slabId=str(order_queryset.slabId.id),
                        walletTransactionId=str(order_queryset.id),
                        commissionCharges=order_queryset.commissionCharges,
                        customerVpa="",
                        clientIp=client_ip,
                        status = 5
                        ).save()

                    order_queryset.update(status=payinPaymentstatusResponseDict.get("paymentStatus"),payInResponseCallBackData=payinPaymentstatusResponseDict.get("transactionData"),responseCallBackTime=datetime.datetime.now(),transactionId=wallet_transactions_queryset.transactionId,bankRefId=bank_reference_number,errorMessage=payinPaymentstatusResponseDict.get("message"),walletLog="Wallet Balance is added with the amount of " + str(amount) + ".",pgOrderId=str(payinPaymentstatusResponseDict.get('pgOrderId')),customerVpa=str(payinPaymentstatusResponseDict.get('customerVpa')),currency=str(payinPaymentstatusResponseDict.get('currency')),cardmasked=str(payinPaymentstatusResponseDict.get('cardmasked')))
                else:
                    order_queryset.update(status=payinPaymentstatusResponseDict.get("paymentStatus"),payInResponseCallBackData=payinPaymentstatusResponseDict.get("transactionData"),responseCallBackTime=datetime.datetime.now(),transactionId=order_queryset.transactionId,bankRefId=bank_reference_number,errorMessage=payinPaymentstatusResponseDict.get("message"),walletLog="Wallet Balance is added with the amount of " + str(amount) + ".",pgOrderId=str(payinPaymentstatusResponseDict.get('pgOrderId')),customerVpa=str(payinPaymentstatusResponseDict.get('customerVpa')),currency=str(payinPaymentstatusResponseDict.get('currency')),cardmasked=str(payinPaymentstatusResponseDict.get('cardmasked')))

            responseDict={
            'amount':float(wallet_transactions_queryset.amount),
            'message':payinPaymentstatusResponseDict.get("message"),
            'payment_mode':payinPaymentstatusResponseDict.get("payment_mode"),
            'response_code':payinPaymentstatusResponseDict.get("response_code"),
            'transaction_id':wallet_transactions_queryset.transactionId,
            "bank_reference_number":bank_reference_number,
            "status":payinPaymentstatusResponseDict.get("status")
            }
            data_status["responseStatus"]=1
            data_status['result']=responseDict
            return data_status
        else:
            responseDict={
            "status":"failed",
            "message":payinPaymentstatusResponseDict.get("message")
            }
            data_status["result"]=responseDict
            return data_status

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get payin payment status data!!"
        return data_status

@admin_reports.route("/beneficiary_list",methods=["POST","GET"])
@adminid_access_token_required
def beneficiary_list():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        beneficiaryList = []
        merchantsList = []
        pgList = []
        pagination = ""
        
        form = BeneficiaryListForm(request.args)
        permissionsList = check_permissions(session.get("adminId"),"beneficiariesListPermissions")
        if "view" in permissionsList: 
            
            creditorAccountNumber = request.args.get("creditorAccountNumber","")
            transactionReferenceNumber = request.args.get("transactionReferenceNumber","")
            searchId=request.args.get("searchId","")
            merchantName = request.args.get("merchantName","")
            creditorName = request.args.get("creditorName","")
            merchantId = request.args.get("merchantId","")
            
           
            # Set default date format
            
            page = request.args.get(get_page_parameter(), type=int, default=1)
            per_page = 20
            start = (page - 1) * per_page
            snoCount = int(start)
            merchants_queryset = Users.objects(status__nin=[2])
            total_count=0
            merchants_queryset = Users.objects(status__nin=[2]).only("id","phoneNumber","fullName")
            merchantsList = list(merchants_queryset)

            filters=Q()
            print("((((((((((((((((((((((searchid))))))))))))))))))))))",searchId)
            if form.validate():
                if searchId:
                    filters &= Q(beneficiaryName__icontains=searchId)
                if creditorAccountNumber:
                    filters &= Q(accountNumber__icontains=creditorAccountNumber)
                if merchantId:
                    filters &= Q(userIdsList__in=[merchantId])
                # Apply all filters at once, order by created date
                beneficiaries_queryset = Beneficiaries.objects(filters).order_by("-createdOn").skip(start).limit(per_page)

     

                for each_beneficiary in beneficiaries_queryset:
                   
                    beneficiaryDict = fetching_beneficiary_details(each_beneficiary)
                    beneficiaryDict["snoCount"] = snoCount
                    beneficiaryList.append(beneficiaryDict)
            # if form.validate():
            #     if searchId:
            #         filters &=(Q(beneficiaryName__icontains=searchId))
 
            #     if creditorAccountNumber:
            #         print("creditorAccountNumber", creditorAccountNumber)
            #         filters &= Q(accountNumber__icontains=creditorAccountNumber)
                    
            #     print("(((((((((((((((((((((((formvalidate)))))))))))))))))))))))",form.validate)
            # # if form.validate():
            # #     if form.creditorAccountNumber.data:
            # #         filters &= Q(accountNumber__icontains=form.creditorAccountNumber.data)
            # #     if form.searchId.data:
            # #         filters &= Q(beneficiaryName__icontains=form.searchId.data)
                
            #     beneficiaries_queryset = Beneficiaries.objects(filters).skip(start).limit(per_page)
                
            #     total_count = beneficiaries_queryset.count()
            #     beneficiaryList=list(beneficiaries_queryset)
            #     print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", len(beneficiaryList))
            #     print("###############################################", beneficiaries_queryset.count())
            #     print("############################$$$$$$$$$$$$$$$$$$$$$$", total_count)
            #     print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1", filters)

            #     # beneficiaries_queryset = Beneficiaries.objects(filters).order_by("-createdOn")
            #     # total_count = beneficiaries_queryset.count()
            #     # beneficiaries_paginated = beneficiaries_queryset.skip(start).limit(per_page)
 
                payout_gate_way_queryset = TransactionAPI.objects(transactionType="Payout",status=1,preAuthorization=True)
                for each_payout in payout_gate_way_queryset:
                    pgDict = fetching_transaction_api_details(each_payout)
                    pgList.append(pgDict)

            #     # beneficiaries_queryset = Beneficiaries.objects.order_by("-createdOn").all()

                # merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
                
                # for each_merchant in merchants_queryset:
                # 	merchantDict = fetching_user_details(each_merchant)
                # 	merchantsList.append(merchantDict)
                
            #     # if creditorAccountNumber:
            #     #     beneficiaries_queryset = beneficiaries_queryset.filter(accountNumber__icontains=creditorAccountNumber)

            #     # if searchId:f
            #     #     beneficiaries_queryset = beneficiaries_queryset.filter(beneficiaryName__icontains=searchId)
                
                
            #     # if searchId:
            #     #   beneficiaries_queryset = beneficiaries_queryset.filter(Q(name__icontains=searchId) | Q(creditorName__icontains=searchId))

            #     # if merchantId:
            #     #     beneficiaries_queryset = beneficiaries_queryset.filter(userIdsList=[merchantId])

            #     # Get the current page from the query parameters
            #     # page = request.args.get(get_page_parameter(), type=int, default=1)

            #     # per_page = 50  # Number of items per page

            #     # # Query the database for the current page's data
            #     # total_count = beneficiaries_queryset.count()

            #     # start = (page - 1) * per_page

            #     # end = min(start + per_page, total_count)

            #     # total_payouts = beneficiaries_queryset[start:end]
                
            #     # snoCount = start
                
            #     for each_beneficiary in beneficiaries_queryset:
            #         snoCount +=1
            #         beneficiaryDict = fetching_beneficiary_details(each_beneficiary)
            #         beneficiaryDict["snoCount"]=snoCount
            #         beneficiaryList.append(beneficiaryDict)
                total_count = beneficiaries_queryset.count()	
            snoCount = start

            # Pagination object for rendering pagination controls in the template
            pagination = Pagination(page=page, total=total_count, per_page=per_page, alignment="right", record_name="beneficiary")
            # else:
            #    flash(list(form.errors.values())[0][0], "danger")
                 
            print("(((((((((((((((((((((((((((((((((((form)))))))))))))))))))))))))))))))))))",form)
            return render_template("super_admin_templates/beneficiary_list.html",
                pagination=pagination,
                beneficiaryList=beneficiaryList,
                creditorAccountNumber=creditorAccountNumber, 
                merchantName=merchantName,
                transactionReferenceNumber=transactionReferenceNumber,
                merchantsList=merchantsList,
                pgList=pgList,
                searchId=searchId,
                creditorName=creditorName,
                page=page,
                snoCount = snoCount,
                form = form,
                merchantId=merchantId,
                )
            
        else:
            flash("The staff member does not have permission to view Beneficiaries List.","danger")
            return redirect(url_for("admin.dashboard"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetch all beneficiaries data"
        return render_template("super_admin_templates/beneficiary_list.html", 
            error=error,
            pagination=pagination,
            beneficiaryList=beneficiaryList,
            creditorAccountNumber=creditorAccountNumber, 
            merchantName=merchantName,
            merchantsList=merchantsList,
            pgList=pgList,
            transactionReferenceNumber=transactionReferenceNumber,
            searchId=searchId,
            creditorName=creditorName,
            page=page,
            snoCount = snoCount,
            form = form,
            merchantId=merchantId,
            )

# @admin_reports.route("/beneficiary_list", methods=["GET", "POST"])
# @adminid_access_token_required
# def beneficiary_list():
#     try:
#         if not session.get("adminId"):
#             return redirect("admin_login")

#         adminId = session.get("adminId")
#         beneficiaryList = []
#         merchantsList = []
#         pgList = []
#         pagination = ""
#         page = request.args.get(get_page_parameter(), type=int, default=1)
#         per_page = 20
#         start = (page - 1) * per_page
#         snoCount = int(start)

#         form = BeneficiaryListForm(request.args)
#         permissionsList = check_permissions(adminId, "beneficiariesListPermissions")

#         if "view" not in permissionsList:
#             flash("Staff member does not have given view beneficiaries List permissions!!")
#             return render_template("super_admin_templates/beneficiary_list.html")

#         # Read inputs from validated form
#         if form.validate():
#             filters = Q()

#             if form.creditorAccountNumber.data:
#                 filters &= Q(creditorAccountNumber__icontains=form.creditorAccountNumber.data)

#             if form.searchId.data:
#                 filters &= Q(searchId__icontains=form.searchId.data)

#             total_queryset = Beneficiaries.objects(filters).order_by("-createdOn")
#             total_count = total_queryset.count()
#             beneficiaries_queryset = total_queryset.skip(start).limit(per_page)

#             for each_beneficiary in beneficiaries_queryset:
#                 snoCount += 1
#                 beneficiaryDict = fetching_beneficiary_details(each_beneficiary)
#                 beneficiaryDict["snoCount"] = snoCount
#                 beneficiaryList.append(beneficiaryDict)

#             # Pagination
#             pagination = Pagination(page=page, total=total_count, per_page=per_page,alignment="right", record_name="beneficiary")
#         else:
#             flash(" " + str(form.errors))

#         # Payout API info
#         payout_gate_way_queryset = TransactionAPI.objects(
#             transactionType="Payout", status=1, preAuthorization=True
#         )
#         for each_payout in payout_gate_way_queryset:
#             pgDict = fetching_transaction_api_details(each_payout)
#             pgList.append(pgDict)

#         # Merchants List
#         merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
#         for each_merchant in merchants_queryset:
#             merchantDict = fetching_user_details(each_merchant)
#             merchantsList.append(merchantDict)

#         return render_template("super_admin_templates/beneficiary_list.html",
#             pagination=pagination,
#             beneficiaryList=beneficiaryList,
#             creditorAccountNumber=form.creditorAccountNumber.data,
#             merchantName=request.args.get("merchantName", ""),
#             transactionReferenceNumber=request.args.get("transactionReferenceNumber", ""),
#             merchantsList=merchantsList,
#             pgList=pgList,
#             searchId=form.searchId.data,
#             creditorName=request.args.get("creditorName", ""),
#             page=page,
#             snoCount=start,
#             form=form
#         )

#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         error = "Unable to fetch all beneficiaries data!"
#         return render_template("super_admin_templates/beneficiary_list.html",
#             error=error,
#             pagination=pagination,
#             beneficiaryList=beneficiaryList,
#             creditorAccountNumber="",
#             merchantName="",
#             merchantsList=merchantsList,
#             pgList=pgList,
#             transactionReferenceNumber="",
#             searchId="",
#             creditorName="",
#             page=1,
#             snoCount=0,
#             form=form
#         )


########################################################################################################################################################################################

def admin_download_payout_excel_transaction_reports_data(startDate, endDate, payouts_queryset,fileName):
    relative_temp_excel_file_name = ""
    try:
        # Format the date strings for the filename
        # start_date_str = startDate.strftime("%d-%m-%Y")
        # end_date_str = endDate.strftime("%d-%m-%Y")
        # merchant_name = payouts_queryset[0].userId.fullName.replace(" ", "_") if payouts_queryset else "Unknown_Merchant"
        # fileName = f"{merchant_name}_payout_transactions_{start_date_str}_{end_date_str}.xlsx"
        # fileName = f"payout_transactions_{start_date_str}_{end_date_str}.xlsx"

        payout_transaction_data = {
            "Site Title":[],
            "User Type": [],
            "PG Name": [],
            "Merchant Name": [],
            "Beneficiary Name": [],
            "Beneficiary Account Number": [],
            "Beneficiary IFSC": [],
            "Order ID": [],
            "Txn ID": [],
            "Transfer Type":[],
            "Amount(₹)": [],
            "Grand Total(₹)": [],
            "Type": [],
            "Account Number": [],
            "UTR": [],
            "Charge Amount(₹)": [],
            "GST Amount(₹)": [],
            "TDS Amount(₹)": [],
            "Transaction Date": [],
            "Transaction Status": []
        }
        for each_record in payouts_queryset:
            try:
                if each_record.siteTitle:
                    payout_transaction_data["Site Title"].append(each_record.siteTitle)
                else:
                    payout_transaction_data["Site Title"].append("")
            except Exception as e:
                payout_transaction_data["Site Title"].append("")

            payout_transaction_data["User Type"].append(each_record.userType)
            try:
                if each_record.transactionAPIId:
                    payout_transaction_data["PG Name"].append(each_record.transactionAPIId.apiName)
                else:
                    payout_transaction_data["PG Name"].append("N/A")
            except Exception as e:
                payout_transaction_data["PG Name"].append("N/A")

            try:
                if each_record.userId:
                    payout_transaction_data["Merchant Name"].append(each_record.userId.fullName)
                else:
                    payout_transaction_data["Merchant Name"].append("N/A")
            except Exception as e:
                payout_transaction_data["Merchant Name"].append("N/A")
            payout_transaction_data["Beneficiary Name"].append(each_record.beneficiaryName)
            payout_transaction_data["Beneficiary Account Number"].append(each_record.accountNumber)
            payout_transaction_data["Beneficiary IFSC"].append(each_record.accountIFSCCode)
            payout_transaction_data["Order ID"].append(each_record.merchantReferenceNumber)
            payout_transaction_data["Txn ID"].append(each_record.transactionUniqueId)
            payout_transaction_data["Transfer Type"].append("Credit" if each_record.transferType == "Refund" else each_record.transferType)
            payout_transaction_data["Amount(₹)"].append(each_record.amount)
            payout_transaction_data["Grand Total(₹)"].append(each_record.grandTotal)
            payout_transaction_data["Type"].append(each_record.paymentMode)
            payout_transaction_data["Account Number"].append(each_record.accountNumber)
            payout_transaction_data["UTR"].append(each_record.bankReferenceNumber)
            payout_transaction_data["Transaction Date"].append(each_record.createdOn)

            # Transaction Status
            if each_record.status == 1:
                payout_transaction_data["Transaction Status"].append("Success")
            elif each_record.status == 2:
                payout_transaction_data["Transaction Status"].append("Processing")
            elif each_record.status == 4:
                payout_transaction_data["Transaction Status"].append("Reversal")
            elif each_record.status == 5:
                payout_transaction_data["Transaction Status"].append("Refund")
            else:
                payout_transaction_data["Transaction Status"].append("Failed")

            if each_record.commissionCharges:
                payout_transaction_data["Charge Amount(₹)"].append(each_record.commissionCharges.get("chargeAmount", 0.00))
                payout_transaction_data["GST Amount(₹)"].append(each_record.commissionCharges.get("gstAmount", 0.00))
                payout_transaction_data["TDS Amount(₹)"].append(each_record.commissionCharges.get("tdsAmount", 0.00))
            else:
                payout_transaction_data["Charge Amount(₹)"].append(0.00)
                payout_transaction_data["GST Amount(₹)"].append(0.00)
                payout_transaction_data["TDS Amount(₹)"].append(0.00)

        # Create DataFrame
        df = pd.DataFrame(payout_transaction_data)

        # Define file path
        base_dir = os.path.join(app.config['SITE_ROOT'], "media/admin_reports", "payout")
        os.makedirs(base_dir, exist_ok=True)

        relative_temp_excel_file_name = os.path.join("media/admin_reports", "payout", fileName)
        full_file_name = os.path.join(app.config['SITE_ROOT'], relative_temp_excel_file_name)

        # Save DataFrame to Excel
        df.to_excel(full_file_name, index=False)

        # Send the file as a downloadable attachment
        return send_file(
            full_file_name,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            download_name=fileName,
            as_attachment=True
        )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return relative_temp_excel_file_name

@admin_reports.route("/admin_download_payout_transaction_excel_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_payout_transaction_excel_reports():
    data_status={"responseStatus":0,"result":""}
    startDate = request.args.get("startDate","")
    endDate = request.args.get("endDate","")
    selectStatus = request.args.get("selectStatus","")
    orderId = request.args.get("orderId","")
    searchId = request.args.get("searchId","")
    merchantId = request.args.get("merchantId","")
    pgId = request.args.get("pgId","")
    transactionType = request.args.get("transactionType","")
    siteTitle = request.args.get("siteTitle","")
    print("searchId",searchId)
    print("pgId",pgId)
    try:
        status = []
        transactionTypeCheck=["Credit","Refund"]
        date_format = "%d-%m-%Y"
        
        merchant_name=""
        start_date_str = ""
        end_date_str = ""
        searchIdFileName=""
        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
       
        if selectStatus == "All" or selectStatus == "":
            status = [0,1,2,3,4,5]
        elif selectStatus == "Success":
            status = [1]
        elif selectStatus == "Processing":
            status = [2]
        elif selectStatus == "Reversal":
            status = [4]
        elif selectStatus == "Refund":
            status = [5]
        else:
            status = [0]

        if transactionType == "All":
            transactionTypeCheck=["Credit","Debit","Refund"]
        elif transactionType == "Debit":
            transactionTypeCheck=["Debit"]

        addName=False

        # if orderId:
        #       payouts_queryset = payouts_queryset.filter(transactionUniqueId__icontains=orderId)
        query = Q()
        if searchId:
            # payouts_queryset =  FundTransfers.objects(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId)).order_by("-createdOn").all()

            query &= (Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId))

            searchIdFileName=str(searchId)+"_"
        else:
            start_date_str = startDate.strftime("%d-%m-%Y")+"_"
            end_date_str = endDate.strftime("%d-%m-%Y")+"_"

            # payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status,transferType__in=transactionTypeCheck).order_by("-createdOn").all()

            query &= Q(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status,transferType__in=transactionTypeCheck)

            if merchantId:
                # payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])
                query &= Q(userId__in=[merchantId])
                # if payouts_queryset:
                #     merchant_name=payouts_queryset[0].userId.fullName.replace(" ", "_")+"_"
                addName = True

            if pgId:
                query &= Q(transactionAPIId__in=[pgId])
                # payouts_queryset = payouts_queryset.filter(transactionAPIId__in=[pgId])
                
            if siteTitle:
                    user_ids = Users.objects(siteTitle__icontains=siteTitle).only("id").values_list('id')
                    # payouts_queryset = payouts_queryset.filter(userId__in=user_ids)
                    query &= Q(userId__in=user_ids)
        payouts_queryset = FundTransfers.objects(query).order_by("-createdOn").all()
        if addName:
            merchant_name=payouts_queryset[0].userId.fullName.replace(" ", "_")+"_"

        fileName = f"{merchant_name}{start_date_str}{end_date_str}{searchIdFileName}payout_transactions.xlsx"

        reportData = admin_download_payout_excel_transaction_reports_data(startDate,endDate,payouts_queryset,fileName)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download payout transaction report data!!"
        return data_status

@admin_reports.route("/admin_download_payin_ledger_xlsx_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_payin_ledger_xlsx_reports():
    data_status={"responseStatus":0,"result":""}
    startDate = request.args.get("startDate","")
    endDate = request.args.get("endDate","")
    # selectStatus = request.args.get("selectStatus","")
    searchId = request.args.get("searchId","")
    pgId = request.args.get("pgId","")
    merchantId = request.args.get("merchantId","")
    siteTitle = request.args.get("siteTitle","")

    try:
        status = []
        # Set default date format
        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
       
        # payin_ledger_reports = WalletTransactions.objects(status__in=[1,2,4,5],createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()
        
        query=Q()

        if searchId:
            # payin_ledger_reports = payin_ledger_reports.filter(Q(orderId__icontains=searchId) | Q(pgOrderId__icontains=searchId))
            query &=Q(orderId__icontains=searchId) | Q(pgOrderId__icontains=searchId)
        else:
            query&=Q(createdOn__gte=startDate,createdOn__lte=endDate)
            if siteTitle:
                user_ids = Users.objects(siteTitle__icontains=siteTitle).only('id').values_list('id')
                # payin_ledger_reports = payin_ledger_reports.filter(userId__in=user_ids)
                query &= Q(userId__in=user_ids)
            if merchantId:
                # payin_ledger_reports = payin_ledger_reports.filter(userId__in=[merchantId])
                query &= Q(userId__in=[merchantId])
            if pgId:
                # payin_ledger_reports = payin_ledger_reports.filter(paymentGatewayId__in=[pgId])
                query &= Q(paymentGatewayId__in=[pgId])

        payin_ledger_reports = WalletTransactions.objects(query).order_by("-createdOn").all()

        reportData = admin_download_payin_ledger_xlsx_reports_data(startDate,endDate,payin_ledger_reports)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download payin transactions report data!!"
        return data_status


def admin_download_payin_ledger_xlsx_reports_data(startDate, endDate, payin_ledger_reports):
    relative_temp_excel_file_name = ""
    try:
        # Format the date strings for the filename
        start_date_str = startDate.strftime("%d-%m-%Y")
        end_date_str = endDate.strftime("%d-%m-%Y")
        fileName = f"payin_ledger_transactions_{start_date_str}_{end_date_str}.xlsx"

        payin_transaction_data = {
            "Site Title":[],
            "User Type": [],
            "PG Name": [],
            "Merchant Name": [],
            "Order ID": [],
            "Txn ID": [],
            "Opening Balance(₹)": [],
            "CrDrType": [],
            "Credit Amount(₹)": [],
            "Debit Amount(₹)": [],
            "Closing Balance(₹)": [],
            "Transaction Date": [],
            "Transaction Status": []
        }
        
        for each_record in payin_ledger_reports:
            if each_record.creditType=="Credit" :
                creditAmount=each_record.grandTotal
            else:
                creditAmount = 0
            if each_record.creditType=="Debit":
                debitAmount=each_record.grandTotal
            else:
                debitAmount=0
            payin_transaction_data["User Type"].append(each_record.userType)
            payin_transaction_data["PG Name"].append(each_record.paymentGatewayId.apiName)
            payin_transaction_data["Merchant Name"].append(each_record.userId.fullName)
            payin_transaction_data["Order ID"].append(each_record.orderId)
            payin_transaction_data["Txn ID"].append(each_record.pgOrderId)
            payin_transaction_data["Opening Balance(₹)"].append(each_record.previousBalance)
            payin_transaction_data["CrDrType"].append(each_record.creditType)
            payin_transaction_data["Credit Amount(₹)"].append(creditAmount)
            payin_transaction_data["Debit Amount(₹)"].append(debitAmount)
            payin_transaction_data["Closing Balance(₹)"].append(each_record.currentBalance)
            payin_transaction_data["Transaction Date"].append(each_record.createdOn)
            try:
                if each_record.siteTitle:
                    payin_transaction_data["Site Title"].append(each_record.siteTitle)
                else:
                    payin_transaction_data["Site Title"].append("")
            except Exception as e:
                payin_transaction_data["Site Title"].append("")

            # Transaction Status
            if each_record.status == 1:
                payin_transaction_data["Transaction Status"].append("Success")
            elif each_record.status == 2:
                payin_transaction_data["Transaction Status"].append("Processing")
            else:
                payin_transaction_data["Transaction Status"].append("Failed")

        # Create DataFrame
        df = pd.DataFrame(payin_transaction_data)

        # Define file path
        base_dir = os.path.join(app.config['SITE_ROOT'], "media/admin_reports", "payinledger")
        os.makedirs(base_dir, exist_ok=True)

        relative_temp_excel_file_name = os.path.join("media/admin_reports", "payinledger", fileName)
        full_file_name = os.path.join(app.config['SITE_ROOT'], relative_temp_excel_file_name)

        # Save DataFrame to Excel
        df.to_excel(full_file_name, index=False)

        # Send the file as a downloadable attachment
        return send_file(
            full_file_name,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            download_name=fileName,
            as_attachment=True
        )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return relative_temp_excel_file_name

@admin_reports.route("/admin_download_payout_ledger_xlsx_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_payout_ledger_xlsx_reports():
    data_status={"responseStatus":0,"result":""}
    try:
        adminId = session.get("adminId")
        payoutsList = []
        merchantsList = []

        startDate = request.args.get("startDate","")
        endDate = request.args.get("endDate","")
        orderId = request.args.get("orderId","")
        searchId=request.args.get("searchId","")
        transactionUniqueId = request.args.get("transactionUniqueId","")
        merchantId = request.args.get("merchantId","")
        pgId = request.args.get("pgId","")
        transactionType = request.args.get("transactionType","")        
        siteTitle = request.args.get("siteTitle","")

        # Set default date format
        date_format = "%d-%m-%Y"
        pagination = None
        transactionTypeCheck=["Credit","Refund"]
        merchant_name=""
        start_date_str = ""
        end_date_str = ""
        searchIdFileName=""

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

        merchants_queryset = Users.objects(status__nin=[2]).order_by("-createdOn")
        for each_merchant in merchants_queryset:
            merchantDict = fetching_user_details(each_merchant)
            merchantsList.append(merchantDict)

        # fund_transfer_queryset = FundTransfers.objects(status__in=[0,1,2,3,4,5],createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()

        # if orderId:
        #   fund_transfer_queryset = fund_transfer_queryset.filter(merchantReferenceNumber=orderId)

        if transactionType == "All":
                transactionTypeCheck=["Credit","Debit","Refund"]
        elif transactionType == "Debit":
            transactionTypeCheck=["Debit"]
        addName = False

        query=Q()
        if searchId:
            # payouts_queryset =  FundTransfers.objects(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId)).order_by("-createdOn").all()
            query &= (Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId)| Q(pgOrderId__icontains=searchId))
            searchIdFileName=str(searchId)+"_"

        else:
            start_date_str = startDate.strftime("%d-%m-%Y")+"_"
            end_date_str = endDate.strftime("%d-%m-%Y")+"_"

            # payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,
            # transferType__in=transactionTypeCheck).order_by("-createdOn").all()
            query = Q(createdOn__gte=startDate,createdOn__lte=endDate,transferType__in=transactionTypeCheck)

            if merchantId:
                # payouts_queryset = payouts_queryset.filter(userId__in=[merchantId])
                query &= Q(userId__in=[merchantId])
                addName=True
                # if payouts_queryset:
                    # merchant_name=payouts_queryset[0].userId.fullName.replace(" ", "_")+"_"

            if pgId:
                # payouts_queryset = payouts_queryset.filter(transactionAPIId__in=[pgId])
                query &= Q(transactionAPIId__in=[pgId])
            
            if siteTitle:
                user_ids = Users.objects(siteTitle__icontains=siteTitle).values_list('id')
                # payouts_queryset = payouts_queryset.filter(userId__in=user_ids)
                query &= Q(userId__in=user_ids)
        

        payouts_queryset = FundTransfers.objects(query).order_by("-createdOn").all()
        if merchantId and len(payouts_queryset) > 0:
            merchant_name=payouts_queryset[0].userId.fullName.replace(" ", "_")+"_"

        fileName = f"{merchant_name}{start_date_str}{end_date_str}{searchIdFileName}payout_ledger.xlsx"
            
        reportData = admin_download_payout_ledger_xlsx_reports_data(startDate,endDate,payouts_queryset,fileName)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download payout transactions report data!!"
        return data_status

def admin_download_payout_ledger_xlsx_reports_data(startDate, endDate, fund_transfer_queryset,fileName):
    relative_temp_excel_file_name = ""
    try:
        # Format the date strings for the filename
        # start_date_str = startDate.strftime("%d-%m-%Y")
        # end_date_str = endDate.strftime("%d-%m-%Y")
        # merchant_name = fund_transfer_queryset[0].userId.fullName.replace(" ", "_") if fund_transfer_queryset else "Unknown_Merchant"

        # fileName = f"payout_Ledger_report_{start_date_str}_{end_date_str}.xlsx"
        # fileName = f"{merchant_name}_payout_Ledger_report_{start_date_str}_{end_date_str}.xlsx"


        payout_ledger_data = {
            "Site Title":[],
            "User Type": [],
            "PG Name": [],
            "Order ID": [],
            "Txn ID": [],
            "PgOrderId": [],
            "Merchant Name": [],
            "Beneficiary Name": [],
            "Beneficiary Account Number": [],
            "Beneficiary IFSC": [],
            "Opening Balance(₹)": [],
            "CrDrType": [],
            "Credit Amount(₹)": [],
            "Debit Amount(₹)": [],
            "Closing Balance(₹)": [],
            "UTR": [],
            "Amount(₹)": [],
            "Charge Amount(₹)": [],
            "GST Amount(₹)": [],
            "TDS Amount(₹)": [],
            "Transaction Date": [],
            "Transaction Status": []
        }
        
        for each_record in fund_transfer_queryset:
            try:
                if each_record.siteTitle:
                    payout_ledger_data["Site Title"].append(each_record.siteTitle)
                else:
                    payout_ledger_data["Site Title"].append("")
            except Exception as e:
                payout_ledger_data["Site Title"].append("")
            payout_ledger_data["User Type"].append(each_record.userType)
            payout_ledger_data["PG Name"].append(each_record.transactionAPIId.apiName)
            payout_ledger_data["Order ID"].append(each_record.merchantReferenceNumber)
            payout_ledger_data["Txn ID"].append(each_record.transactionUniqueId)
            payout_ledger_data["PgOrderId"].append(each_record.pgOrderId)
            payout_ledger_data["Merchant Name"].append(each_record.userId.fullName)
            payout_ledger_data["Beneficiary Name"].append(each_record.beneficiaryName)
            payout_ledger_data["Beneficiary Account Number"].append(each_record.accountNumber)
            payout_ledger_data["Beneficiary IFSC"].append(each_record.accountIFSCCode)
            payout_ledger_data["Opening Balance(₹)"].append(each_record.previousBalance)
            # payout_ledger_data["CrDrType"].append(each_record.transferType)
            payout_ledger_data["CrDrType"].append("Credit" if each_record.transferType == "Refund" else each_record.transferType)
            payout_ledger_data["Credit Amount(₹)"].append(each_record.grandTotal if each_record.transferType in ["Credit", "Refund"] else None)
            # payout_ledger_data["Credit Amount(₹)"].append(each_record.grandTotal if each_record.transferType == "Credit" else None)
            payout_ledger_data["Debit Amount(₹)"].append(each_record.grandTotal if each_record.transferType == "Debit" else None)
            payout_ledger_data["Closing Balance(₹)"].append(each_record.currentBalance)
            payout_ledger_data["UTR"].append(each_record.bankReferenceNumber)
            payout_ledger_data["Transaction Date"].append(each_record.createdOn)

            # Transaction Status
            if each_record.status == 1:
                payout_ledger_data["Transaction Status"].append("Success")
            elif each_record.status == 2:
                payout_ledger_data["Transaction Status"].append("Processing")
            elif each_record.status == 4:
                payout_ledger_data["Transaction Status"].append("Reversal")
            elif each_record.status == 5:
                payout_ledger_data["Transaction Status"].append("Refund")
            else:
                payout_ledger_data["Transaction Status"].append("Failed")

            # Charges and Amounts
            if each_record.commissionCharges:
                payout_ledger_data["Charge Amount(₹)"].append(each_record.commissionCharges.get("chargeAmount", 0.00))
                payout_ledger_data["GST Amount(₹)"].append(each_record.commissionCharges.get("gstAmount", 0.00))
                payout_ledger_data["TDS Amount(₹)"].append(each_record.commissionCharges.get("tdsAmount", 0.00))
            else:
                payout_ledger_data["Charge Amount(₹)"].append(0.00)
                payout_ledger_data["GST Amount(₹)"].append(0.00)
                payout_ledger_data["TDS Amount(₹)"].append(0.00)

            payout_ledger_data["Amount(₹)"].append(each_record.amount if each_record.amount else 0.00)

        # Create DataFrame
        df = pd.DataFrame(payout_ledger_data)

        # Define file path
        base_dir = os.path.join(app.config['SITE_ROOT'], "media/admin_reports", "payout_ledger")
        os.makedirs(base_dir, exist_ok=True)

        relative_temp_excel_file_name = os.path.join("media/admin_reports", "payout_ledger", fileName)
        full_file_name = os.path.join(app.config['SITE_ROOT'], relative_temp_excel_file_name)

        # Save DataFrame to Excel
        df.to_excel(full_file_name, index=False)

        # Send the file as a downloadable attachment
        return send_file(
            full_file_name,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            download_name=fileName,
            as_attachment=True
        )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return relative_temp_excel_file_name

@admin_reports.route("/admin_download_payin_transactions_excel_reports",methods=["POST","GET"])
@adminid_access_token_required
def admin_download_payin_transactions_excel_reports():
    data_status={"responseStatus":0,"result":""}
    startDate = request.args.get("startDate","")
    endDate = request.args.get("endDate","")
    selectStatus = request.args.get("selectStatus","")
    transactionType = request.args.get("transactionType","")
    orderId = request.args.get("orderId","")
    searchId = request.args.get("searchId","")
    merchantId = request.args.get("merchantId","")
    pgId = request.args.get("pgId","")
    subPaymentModeId = request.args.get("subPaymentModeId","")
    paymentModeId = request.args.get("paymentModeId","")
    siteTitle = request.args.get("siteTitle","")


    try:
        status = []
        transactionTypeCheck=["Credit"]
        # Set default date format
        date_format = "%d-%m-%Y"

        merchant_name=""
        start_date_str = ""
        end_date_str = ""
        searchIdFileName=""

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
       
        if selectStatus == "All" or selectStatus == "":
            status = [0,1,2,4,5]
        elif selectStatus == "Success":
            status = [1]
        elif selectStatus == "Processing":
            status = [2]
        else:
            status = [0]
        addName=False

        # payin_transaction_reports = WalletTransactions.objects(
        #   status__in=[0, 1, 2, 4, 5],createdOn__gte=startDate,createdOn__lte=endDate
        #   ).order_by("-createdOn")

        if transactionType == "All":
            transactionTypeCheck=["Credit","Debit"]
        elif transactionType == "Debit":
            transactionTypeCheck=["Debit"]

        query=Q()
        if searchId:
                # payin_queryset = WalletTransactions.objects(Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId)).order_by("-createdOn").all()
                query &= (Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId)| Q(pgOrderId__icontains=searchId))
                # payin_queryset = payin_queryset.filter()
                searchIdFileName=str(searchId)+"_"
        else:
            start_date_str = startDate.strftime("%d-%m-%Y")+"_"
            end_date_str = endDate.strftime("%d-%m-%Y")+"_"

            # payin_queryset = WalletTransactions.objects(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status,creditType__in=transactionTypeCheck).order_by("-createdOn").all()

            query = Q(createdOn__gte=startDate,createdOn__lte=endDate,status__in=status,creditType__in=transactionTypeCheck)
            
            if merchantId:
                addName=True
                # payin_queryset = payin_queryset.filter(userId__in=[merchantId])
                query &= Q(userId=merchantId)
                # if payin_queryset:
                    # merchant_name=payin_queryset[0].userId.fullName.replace(" ", "_")+"_"

            if pgId:
                # payin_queryset = payin_queryset.filter(paymentGatewayId__in=[pgId])
                query &= Q(paymentGatewayId=pgId)

            if paymentModeId:
                    payments_mode_queryset = PaymentMode.objects(id=paymentModeId).first()
                    # payin_queryset = payin_queryset.filter(paymentType=payments_mode_queryset.paymentMode)
                    query &= Q(paymentType=payments_mode_queryset.paymentMode)
            if subPaymentModeId:
                sub_payments_mode_queryset = SubPaymentModes.objects(id=subPaymentModeId).first()
                # payin_queryset = payin_queryset.filter(subPaymentMode=sub_payments_mode_queryset.subPaymentModeType)
                query &= Q(subPaymentMode=sub_payments_mode_queryset.subPaymentModeType)
                
            if siteTitle:
                # user_ids = Users.objects(siteTitle__icontains=siteTitle).values_list('id')
                # payin_queryset = payin_queryset.filter(userId__in=user_ids)
                query &= Q(siteTitle=siteTitle)

        payin_queryset = WalletTransactions.objects(query).order_by("-createdOn")

        if addName:
            merchant_name=payin_queryset[0].userId.fullName.replace(" ", "_")+"_"
        fileName = f"{merchant_name}{start_date_str}{end_date_str}{searchIdFileName}payin_transactions.xlsx"
            
        reportData = admin_download_payin_transactions_excel_reports_data(startDate,endDate,payin_queryset,fileName)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download payin ledger report data!!"
        return data_status

def admin_download_payin_transactions_excel_reports_data(startDate, endDate, payin_transaction_reports,fileName):
    downloadPayoutExcelReportsList = []
    relative_temp_excel_file_name = ""
    try:
        # Format the date strings for the filename
        # start_date_str = startDate.strftime("%d-%m-%Y")
        # end_date_str = endDate.strftime("%d-%m-%Y")
        # fileName = f"payin_{start_date_str}_{end_date_str}.xlsx"

        payin_transactions_data = {
            "Site Title":[],
            "User Type": [],
            "PG Name": [],
            "Payment Mode": [], ###
            "SubPayment Mode": [], ####
            "Order ID": [],
            "PG ID": [],
            "Txn ID": [],
            "Merchant Name": [],
            "Merchant Type": [],
            "Opening Balance(₹)": [],
            "CrDrType": [],
            "Credit Amount(₹)": [],
            "Debit Amount(₹)": [],
            "Closing Balance(₹)": [],
            "Amount(₹)": [],
            "Charge Amount(₹)": [],
            "Charge Value": [],
            "GST Amount(₹)": [],
            "TDS Amount(₹)": [],
            "Transaction Date": [],
            "Status": [],
            # "AD Name": [], #######
            # "AD Charge": [], #######
            # "AD Amount": [], #######
            # "MD Name": [], #######
            # "MD Charge": [], #######
            # "MD Amount": [], #######
            # "SD Name": [], #######
            # "SD Charge": [], #######
            # "SD Amount": [], #######
            # "PG Amount": [], #######
            # "PG Charge": [], #######
            # "PG GST Amount": [], #######
            
        }
        for each_record in payin_transaction_reports:
            # print("id check",each_record.id)
            try:
                if each_record.siteTitle:
                    payin_transactions_data["Site Title"].append(each_record.siteTitle)
                else:
                    payin_transactions_data["Site Title"].append("")
            except Exception as e:
                payin_transactions_data["Site Title"].append("")
            payin_transactions_data["User Type"].append(each_record.userType)
            payin_transactions_data["PG Name"].append(each_record.paymentGatewayId.apiName)

            payin_transactions_data["Payment Mode"].append(each_record.paymentType)
            try:
                if each_record.subPaymentModeId:
                    payin_transactions_data["SubPayment Mode"].append(each_record.subPaymentModeId.subPaymentModeType)
                else:
                    payin_transactions_data["SubPayment Mode"].append("")
            except Exception as e:
                payin_transactions_data["SubPayment Mode"].append("")


            payin_transactions_data["Order ID"].append(each_record.orderId)
            if each_record.statusCheckId:
                payin_transactions_data["PG ID"].append(each_record.statusCheckId)
            else:
                payin_transactions_data["PG ID"].append("")
            payin_transactions_data["Txn ID"].append(each_record.pgOrderId)
            try:
                name_number = str(each_record.userId.fullName) + " - "+  str(each_record.userId.phoneNumber)
                payin_transactions_data["Merchant Name"].append(name_number)
            except Exception as e:
                payin_transactions_data["Merchant Name"]=""
                pass
            try:
                payin_transactions_data["Merchant Type"].append(each_record.userId.merchantType)
            except Exception as e:
                payin_transactions_data["Merchant Type"]=""
                pass
            payin_transactions_data["Opening Balance(₹)"].append(each_record.previousBalance)
            payin_transactions_data["CrDrType"].append(each_record.creditType)
            payin_transactions_data["Credit Amount(₹)"].append(each_record.grandTotal if each_record.creditType == "Credit" else None)
            payin_transactions_data["Debit Amount(₹)"].append(each_record.grandTotal if each_record.creditType == "Debit" else None)
            payin_transactions_data["Closing Balance(₹)"].append(each_record.currentBalance)
            if each_record.amount:
                payin_transactions_data["Amount(₹)"].append(each_record.amount)
            else:
                payin_transactions_data["Amount(₹)"].append(0)

            if each_record.commissionCharges == {}:
                payin_transactions_data["Charge Amount(₹)"].append(0.00)
                payin_transactions_data["Charge Value"].append(0.00)
                payin_transactions_data["GST Amount(₹)"].append(0.00)
                payin_transactions_data["TDS Amount(₹)"].append(0.00)
            else:
                payin_transactions_data["Charge Value"].append(each_record.commissionCharges.get("chargeValue", 0.00))
                payin_transactions_data["Charge Amount(₹)"].append(each_record.commissionCharges.get("chargeAmount", 0.00))
                payin_transactions_data["GST Amount(₹)"].append(each_record.commissionCharges.get("gstAmount", 0.00))
                payin_transactions_data["TDS Amount(₹)"].append(each_record.commissionCharges.get("tdsAmount", 0.00))
            
            payin_transactions_data["Transaction Date"].append(each_record.createdOn)

            if each_record.status == 1:
                payin_transactions_data["Status"].append("Success")
            elif each_record.status == 2:
                payin_transactions_data["Status"].append("Processing")
            elif each_record.status == 3:
                payin_transactions_data["Status"].append("Initiated")
            elif each_record.status == 4:
                payin_transactions_data["Status"].append("Reversal")
            elif each_record.status == 5:
                payin_transactions_data["Status"].append("Refund")
            else:
                payin_transactions_data["Status"].append("Failed")
            # print("each_record.id",each_record.id)
            # print("each_record.transactionId",each_record.transactionId)
            # if each_record.creditType == "Credit" and each_record.status==1:
            # 	sd_check = False
            # 	md_check = False
            # 	ad_check = False
            # 	user_commissions_queryset = UserCommissions.objects(Q(walletId=each_record.id ) | Q(transactionId = each_record.transactionId)).all()
                # if len(user_commissions_queryset) > 0:
                # 	# print("got data some things for transaction id and wallet id ", each_record.id, " ------------ ",each_record.id)
                # 	for each_user_comm_record in user_commissions_queryset:
                # 		name = str(each_user_comm_record.userId.fullName) + " - "+  str(each_record.userId.phoneNumber)
                # 		if each_user_comm_record.userId.merchantType == "Super Distributor":
                # 			sd_check = True
                # 			# print("inside Super Distributor")
                # 			payin_transactions_data["SD Name"].append(name)
                # 			payin_transactions_data["SD Charge"].append(float(each_user_comm_record.parrentSlabCommissionValue))
                # 			payin_transactions_data["SD Amount"].append(round(float(each_user_comm_record.parrentCommissionAmount),2))

                # 		elif each_user_comm_record.userId.merchantType == "Master Distributor":
                # 			md_check = True
                # 			# print("inside Master Distributor")
                # 			payin_transactions_data["MD Name"].append(name)
                # 			payin_transactions_data["MD Charge"].append( float(each_user_comm_record.parrentSlabCommissionValue))
                # 			payin_transactions_data["MD Amount"].append(round(float(each_user_comm_record.parrentCommissionAmount),2))

                # 		elif each_user_comm_record.userId.merchantType == "Area Distributor":
                # 			ad_check = True
                # 			# print("inside Area Distributor")
                # 			payin_transactions_data["AD Name"].append(name)
                # 			payin_transactions_data["AD Charge"].append(float(each_user_comm_record.parrentSlabCommissionValue))
                # 			payin_transactions_data["AD Amount"].append(round(float(each_user_comm_record.parrentCommissionAmount),2))

                # 		else:
                # 			# print("merchant type in else",each_user_comm_record.userId.merchantType )
                # 			pass

                # if not sd_check:
                # 	payin_transactions_data["SD Name"].append("")
                # 	payin_transactions_data["SD Charge"].append(0.00)
                # 	payin_transactions_data["SD Amount"].append(0.00)
                # if not md_check:
                # 	payin_transactions_data["MD Name"].append("")
                # 	payin_transactions_data["MD Charge"].append(0.00)
                # 	payin_transactions_data["MD Amount"].append(0.00)
                # if not ad_check:
                # 	payin_transactions_data["AD Name"].append("")
                # 	payin_transactions_data["AD Charge"].append(0.00)
                # 	payin_transactions_data["AD Amount"].append(0.00)

                # company_commissions_queryset = CompanyCommissions.objects(Q(walletId=each_record.id ) | Q(transactionId = each_record.transactionId)).first()
                # if company_commissions_queryset:
                # 	payin_transactions_data["PG Amount"].append(company_commissions_queryset.aggregatorCommissionCharges.get("chargeAmount"))
                # 	payin_transactions_data["PG Charge"].append(company_commissions_queryset.aggregatorCommissionCharges.get("chargeValue"))
                # 	payin_transactions_data["PG GST Amount"].append(company_commissions_queryset.aggregatorCommissionCharges.get("gstAmount"))
                # else:
                # 	payin_transactions_data["PG Charge"].append(0.00)
                # 	payin_transactions_data["PG Amount"].append( 0.00)
                # 	payin_transactions_data["PG GST Amount"].append( 0.00)
            # else:
            # 	payin_transactions_data["SD Name"].append("")
            # 	payin_transactions_data["SD Charge"].append(0.00)
            # 	payin_transactions_data["SD Amount"].append(0.00)
            # 	payin_transactions_data["MD Name"].append("")
            # 	payin_transactions_data["MD Charge"].append(0.00)
            # 	payin_transactions_data["MD Amount"].append(0.00)
            # 	payin_transactions_data["AD Name"].append("")
            # 	payin_transactions_data["AD Charge"].append(0.00)
            # 	payin_transactions_data["AD Amount"].append(0.00)
            # 	payin_transactions_data["PG Charge"].append(0.00)
            # 	payin_transactions_data["PG Amount"].append( 0.00)
            # 	payin_transactions_data["PG GST Amount"].append( 0.00)

            # lengths = [len(value) for value in payin_transactions_data.values()]
    
            # If the lengths are not all the same, print the iteration and lengths
            # if len(set(lengths)) == 1:
                # print(f"**********************************Inconsistent lengths found at iteration {each_record.transactionId}. Lengths: {lengths}")
            # print(payin_transactions_data,"payin_transacion_reports")
        # Create DataFrame
        df = pd.DataFrame(payin_transactions_data)

        # Define file path
        base_dir = os.path.join(app.config['SITE_ROOT'], "media/admin_reports", "payin")
        if not os.path.exists(base_dir):
            os.makedirs(base_dir)

        relative_temp_excel_file_name = os.path.join("media/admin_reports", "payin", fileName)
        os.makedirs(base_dir, exist_ok=True)
        full_file_name = os.path.join(app.config['SITE_ROOT'], relative_temp_excel_file_name)

        # Save DataFrame to Excel
        df.to_excel(full_file_name, index=False)

        # Send the file as a downloadable attachment
        return send_file(
            full_file_name,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            download_name=fileName,
            as_attachment=True
        )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return relative_temp_excel_file_name


@admin_reports.route("/admin_bulkbeneficiaries_statuscheck",methods=["POST"])
@adminid_access_token_required
@csrf_protect
def admin_bulkbeneficiaries_statuscheck():
    data_status = {"responseStatus":0,"result":""}
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    form = PaymentGatewaybeneForm()
    form.paymentGatewayId.choices = [
        (str(each.id), each.apiName) for each in TransactionAPI.objects(status=1)
    ]

    if SERVER_STATUS == "DOWN":
        data_status["result"] = SERVER_MAINTAINCE_MESSAGE
        return data_status

    if not form.validate_on_submit():
        for field, errors in form.errors.items():
            for error in errors:
                flash(f"{error}", "danger")
        return redirect(url_for('admin_reports.beneficiary_list'))

    
    try:
        paymentGatewayId = request.form.get("paymentGatewayId","")
        beneCodesList = request.form.getlist("beneCodesList")
        print(paymentGatewayId,"((((((paymentGatewayId))))))")
        # print(beneCodesList,"((((((beneCodesList))))))")
        print(type(beneCodesList),"((((((beneCodesList))))))")
        print(len(beneCodesList),"((((((Length beneCodesList))))))")
        if not (paymentGatewayId and beneCodesList):
            data_status["result"] = "Required fields are missing!!"
            return redirect(url_for('admin_reports.beneficiary_list'))

        if beneCodesList == ['']:
            data_status["result"] = "Required fields are missing!!"
            return redirect(url_for('admin_reports.beneficiary_list'))
        errorList =[]
        benecodesList =[]

        payout_gate_way_queryset = TransactionAPI.objects(id=paymentGatewayId,status=1).first()
        if not payout_gate_way_queryset:
            data_status["result"] = "Payout option is disabled please contact to admin!!"
            return redirect(url_for('admin_reports.beneficiary_list'))
        
        
    
        counter = 0 
        for each_bene_code in beneCodesList:
            print(each_bene_code,"(((((((EACH each_bene_code)))))))")
            counter=counter+1
            beneCode=each_bene_code

            if beneCode != "":
                if not beneCode:
                    data_status["result"] = "Invalid benecodes!!"
                    return data_status
                print(beneCode,"((((((beneCode))))))")
                benecodesList.append(beneCode)

        print(benecodesList,"((((((((((((benecodesList))))))))))))")
        if len(benecodesList) == []:
            data_status["result"] = "Invalid request!!"
            return redirect(url_for('admin_reports.beneficiary_list'))

        uuid=random_alphanumeric_generate(20)
                
        if payout_gate_way_queryset:
            if payout_gate_way_queryset.code == "Axis_Payout":
                client_id = ""
                client_secret = ""
                get_api_key=""
                channelId=""
                serviceRequestId=""
                corpCode=""
                serviceRequestVersion=""
                get_base_url=""
                corp_account_number=""

                for each_key in payout_gate_way_queryset.paramsList:
                    get_key = each_key.get("key")
                    if get_key=="client_id":
                        client_id=each_key.get("value")
                    if get_key=="client_secret":
                        client_secret=each_key.get("value")
                    if get_key=="encryption_key":
                        get_api_key=each_key.get("value")
                    if get_key=="channel_id":
                        channelId=each_key.get("value")
                    if get_key=="service_request_id":
                        serviceRequestId=each_key.get("value")
                    if get_key=="service_request_version":
                        serviceRequestVersion=each_key.get("value")
                    if get_key=="corp_code":
                        corpCode=each_key.get("value")
                    if get_key=="get_base_url":
                        get_base_url=each_key.get("value")
                    if get_key=="corp_account_number":
                        corp_account_number=each_key.get("value")
                
                requestUUID = str(random_alphanumeric_generate(15))
                
                fromDate=(datetime.datetime.now() - timedelta(days=25)).strftime("%Y-%m-%d")
                toDate=datetime.datetime.now().strftime("%Y-%m-%d")

                ###################### Axis Bulk Beneficiary Enquiry Functionality Code #####################################
                paymentgatewayResponseStatusDict = axis_bulk_beneficiary_enquiry(
                    client_id=client_id,
                    client_secret=client_secret,
                    key=get_api_key,
                    channelId=channelId,
                    get_base_url=get_base_url,
                    apiVersion="1.0",
                    requestUUID=requestUUID,
                    serviceRequestId=serviceRequestId,
                    serviceRequestVersion=serviceRequestVersion,
                    corpCode=corpCode,
                    userId=None,
                    fromDate=fromDate,
                    toDate=toDate,
                    emailId=admin_recieve_email,
                    status="All",
                    benecodesList=benecodesList
                    )
                ##########################################################################################################
            else:
                data_status["result"]="Unable to connect to the server!!"
                return redirect(url_for('admin_reports.beneficiary_list'))
            #######################################  Common code for Bene Creations ##########################################
            if paymentgatewayResponseStatusDict.get("responseStatus") == 1:
                transactionData = paymentgatewayResponseStatusDict.get("transactionData")
                beneList = paymentgatewayResponseStatusDict.get("beneList")
                responseList = paymentgatewayResponseStatusDict.get("responseList")
                print(beneList,"(((((((((((((Bulk beneList enquiries)))))))))))))")
                for each_bene in responseList:
                    beneId = each_bene.get("beneCode")
                    bene_data_queryset = Beneficiaries.objects(beneCodeList__beneCode=beneId).first()
 
                    if bene_data_queryset:
                        if each_bene.get("status").lower() == "active":
                            # Copy the existing beneCodeList
                            existingBenecodesList = bene_data_queryset.beneCodeList
                            for each_dict in existingBenecodesList:
                                # Check if transactionAPIId matches
                                if each_dict.get("transactionApiId") == str(payout_gate_way_queryset.id):
                                    # Update the matched dictionary
                                    each_dict.update({
                                        "beneCode": each_dict.get("beneCode"),
                                        "transactionApiId": each_dict.get("transactionApiId"),
                                        "status": "Active"
                                    })
                                    break
                            # Save the updated list back to the database
                            bene_data_queryset.beneCodeList = existingBenecodesList
                            bene_data_queryset.save()

                data_status["responseStatus"]=1
                data_status["result"]="Bulk benificaries enquiries data successfully!"
                return redirect(url_for('admin_reports.beneficiary_list'))

            elif paymentgatewayResponseStatusDict.get("responseStatus") == 0:
                data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                return redirect(url_for('admin_reports.beneficiary_list'))
            else:
                data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                return redirect(url_for('admin_reports.beneficiary_list'))
        else:
            data_status["result"]="Please contact to admin to enable payout option!!"
            return redirect(url_for('admin_reports.beneficiary_list'))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return redirect(url_for('admin_reports.beneficiary_list'))

@admin_reports.route("/payin_invoice_report", methods=["GET"])
@adminid_access_token_required
def payin_invoice_report():
    try:
        payinId = request.args.get('payinId')
        payinDict={}
        print("((((((((((payinId))))))))))",payinId)    
        if request.method =="GET" :
            if payinId:
                payin_query_set = WalletTransactions.objects(id=payinId).first()
                
                payinDict = fetching_payin_details(payin_query_set)

                print("(((((payinDict)))))",payinDict)
                ## getting invoice company details 
                transactionApiId = payin_query_set.paymentGatewayId
                invoiceType = transactionApiId.invoiceType
                commissionCharges = payinDict.get("commissionCharges")
                productName = payinDict.get("productName")
                if productName == None:
                    payinDict["productName"] = ""
                print("(((((commissionCharges)))))",commissionCharges)
                gstAmount = commissionCharges["gstAmount"]
                invoice_company_query_set = InvoiceCompanyDetails.objects(transactionApiIdsList__in=[transactionApiId]).first()
                invoice_template = invoice_company_query_set.invoiceTemplate
                if not invoice_company_query_set:
                    payinDict["companyLogo"]=""
                    payinDict["companyAddress"]=""
                    payinDict["email"]=""
                    payinDict["mobileNumber"]=""
                else:
                    try:
                        if invoice_company_query_set.companyLogo:
                            payinDict["companyLogo"]=domain+invoice_company_query_set.companyLogo
                        else:
                            payinDict["companyLogo"]=""
                    except Exception as e:
                        payinDict["companyLogo"]=""

                    try:
                        if invoice_company_query_set.companyLogo:
                            payinDict["companyLogo"]=invoice_company_query_set.companyLogo
                        else:
                            payinDict["companyLogo"]=""

                        if invoice_company_query_set.address:
                            payinDict["companyAddress"]=invoice_company_query_set.address
                        else:
                            payinDict["companyAddress"]=""

                        if invoice_company_query_set.email:
                            payinDict["email"]=invoice_company_query_set.email
                        else:
                            payinDict["email"]=""

                        if invoice_company_query_set.mobileNumber:
                            payinDict["mobileNumber"]=invoice_company_query_set.mobileNumber
                        else:
                            payinDict["mobileNumber"]=""
                        if invoice_company_query_set.invoiceTemplate:
                            
                            print("============invoice template===", invoice_template)
                            
                            invoice_template = invoice_template.replace("{#customerName#}",str(payinDict.get("customerName")))
                            invoice_template = invoice_template.replace("{#customerEmail#}",str(payinDict.get("customerEmail")))
                            invoice_template = invoice_template.replace("{#userName#}", payinDict.get("merchantName",""))
                            invoice_template = invoice_template.replace("{#userEmail#}", payinDict.get("merchantEmail",""))
                            invoice_template = invoice_template.replace("{#invoiceId#}",str(payinDict.get("invoiceId","")) or str(payinDict.get("orderId","")))
                            invoice_template = invoice_template.replace("{#grandTotal#}", str(round(float(str(payinDict.get("grandTotal",'0')or '0').replace(",","")),2)))
                            invoice_template = invoice_template.replace("{#amount#}", str(round(float(str(payinDict.get("amount",'0')or '0').replace(",","")),2)))
                            invoice_template = invoice_template.replace("{#transactionId#}",payinDict.get("transactionId",""))
                            gstAmount = float(str(payinDict.get("gstAmount",0) or 0).replace(",",""))
                            chargeAmount = float(str(payinDict.get("chargeAmount",0) or 0).replace(",",""))
                            charges = round(chargeAmount+gstAmount,2)
                            invoice_template = invoice_template.replace("{#charges#}", str(charges))

                            created_on_date = payinDict.get("createdOn","")
                            if created_on_date:
                                date_format = "%d-%m-%Y %I:%M %p"
                                created_on_date = datetime.datetime.strptime(created_on_date, date_format)
                                new_time = created_on_date + timedelta(minutes=2)
                                dueDate = created_on_date + timedelta(days=15)

                                # Format the new time in 'DD-MM-YYYY HH:MM' format (24-hour clock)
                                recipientDate = new_time.strftime('%d-%m-%Y %H:%M')
                                createdon = created_on_date.strftime('%d-%m-%Y %H:%M')
                                issuedDate = created_on_date.strftime('%d-%m-%Y')
                                dueDate = dueDate.strftime('%d-%m-%Y')
                                invoice_template = invoice_template.replace("{#issuedDate#}",issuedDate)
                                invoice_template = invoice_template.replace("{#dueDate#}",dueDate)
                                invoice_template = invoice_template.replace("{#issuedDateTime#}",createdon)
                                invoice_template = invoice_template.replace("{#recipientDate#}",recipientDate)

                            
                            invoice_template = invoice_template.replace("{#productName#}",str(payinDict.get("productName")))
                            paymentMode = payinDict.get("card_type","") + " " + payinDict.get("mode","") + " " +payinDict.get("cardmasked","")
                            invoice_template = invoice_template.replace("{#paymentMode#}", paymentMode)

                            userId = payinDict.get("userId")
                            if userId:
                                user_kyc_queryset = UserKYC.objects(userId=userId).first()
                                bankAccount = user_kyc_queryset.bankAccountNumber or ""
                                if bankAccount:
                                    bankAccount = mask_and_get_value(bankAccount)
                                invoice_template = invoice_template.replace("{#bankAccount#}",bankAccount)
                                panNumber = user_kyc_queryset.panNumber or ""
                                if panNumber:
                                    panNumber = mask_and_get_value(panNumber)
                                invoice_template = invoice_template.replace("{#panNumber#}",panNumber)

                        else:
                            invoice_template = "super_admin_templates/invoice_payin.html"
                    except Exception as e:
                        payinDict["companyAddress"]=""
                        payinDict["email"]=""
                        payinDict["mobileNumber"]=""
                    
                ### calculating due date 
                created_on_date = datetime.datetime.strptime(payinDict["createdOn"], "%d-%m-%Y %I:%M %p").date()
                due_date = created_on_date + timedelta(days=15)  # Add 15 days to createdOn
                payinDict["dueDate"] = due_date.strftime("%Y-%m-%d")  # Format the due date
                payinDict["created_on_date"] = created_on_date # Format the due date

                # new_inv_num = fetch_latest_invoice_number("25412",payinDict["createdOn"])
                # print("((((((((((((new_inv_num))))))))))))",new_inv_num)
                amount = payinDict.get("amount", 0)
                grandTotal = payinDict.get("grandTotal", 0)
                if invoiceType == "commission":
                #### cal cgst sgst and priceperunit
                    payinDict["gstAmount"] = gstAmount
                else:
                    amount = payinDict.get("amount", 0)
                    # payinDict["gstAmount"] = round(float(amount) * 0.18, 2)  # 18% of amount

                    payinDict["gstAmount"] = 0  # 18% of amount #since cal not done

                # payinDict["pricePerUnit"] = round(float(amount) * 0.18, 2)  # 9% of amount
                print("((((((((((pay_in_datapay_in_data))))))))))",payinDict)

                return render_template("super_admin_templates/sample_invoice_payin.html",invoice_template = invoice_template, payinDict=payinDict)
            else:
                # flash("Staff member does not have view payin transactions reports permissions!")
                return render_template("super_admin_templates/invoice_payin.html", payinDict=payinDict)

    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetch pay-in transactions data!"
        return render_template("super_admin_templates/invoice_payin.html",payinDict=payinDict)


@admin_reports.route("/get_sub_payment_list_using_payment_mode", methods=["POST"])
@csrf.exempt
@adminid_access_token_required
def get_sub_payment_list_using_payment_mode():
    data_status = {"responseStatus": 0, "result": ""}
    # Get paymentModeIdsList as a string, then split if necessary
    paymentModeIdsList = request.form.get("paymentModeIdsList")

    print("in get sub payment modes", paymentModeIdsList)
    
    # If it's a single string with comma-separated ObjectIds, split it
    if isinstance(paymentModeIdsList, str):
        paymentModeIdsList = paymentModeIdsList.split(",")
    
    print(paymentModeIdsList, "((((((((((paymentModeIdsList))))))))))")
    
    # If the list is empty, return an error
    if not paymentModeIdsList:
        data_status["result"] = "Required fields are missing!!"
        return data_status

    try:
        payment_mod_queryset = PaymentMode.objects(id__in=paymentModeIdsList, status__in=[0, 1])
        paymentModesList = [str(each_payment_mode.id) for each_payment_mode in payment_mod_queryset]
        print(paymentModesList, "paymentModesList")

        subPaymentsModeList = []
        sub_payments_mod_queryset = SubPaymentModes.objects(
            paymentModeId__in=paymentModesList, status__in=[0, 1]
        ).order_by("-id").all()

        for each_sub_payment_mode in sub_payments_mod_queryset:
            subPaymentsModeDict = fetching_sub_payment_mode_details(each_sub_payment_mode)
            subPaymentsModeList.append(subPaymentsModeDict)

        data_status["responseStatus"] = 1
        data_status["result"] = "PaymentMode based sub payments data fetched successfully!"
        data_status["subPaymentsModeList"] = subPaymentsModeList
        return data_status
    
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch sub payments data!!"
        return data_status


def admin_download_beneficiary_list_excel_reports_data(beneficiaries_queryset):
    relative_temp_excel_file_name = ""
    try:
        fileName = "beneficiary_list.xlsx"

        beneficaries_data = {
            # "Merchant Name": [],
            "Account Number": [],
            "Original Name": [],
            "Ifsc Code": [],
            "Bank Name": [],
            "Created On": [],
        }

        for each_record in beneficiaries_queryset:
            # beneficaries_data["Merchant Name"].append(each_record.userId.merchantName)
            beneficaries_data["Account Number"].append(each_record.accountNumber)
            beneficaries_data["Original Name"].append(each_record.beneficiaryName) 
            beneficaries_data["Ifsc Code"].append(each_record.ifscCode) 
            beneficaries_data["Bank Name"].append(each_record.masterBankId.bankName)
            beneficaries_data["Created On"].append(each_record.createdOn)

        # Create DataFrame
        df = pd.DataFrame(beneficaries_data)

        # Define file path
        base_dir = os.path.join(app.config['SITE_ROOT'], "media/beneficiaries", "users")
        os.makedirs(base_dir, exist_ok=True)

        relative_temp_excel_file_name = os.path.join("media/beneficiaries", "users", fileName)
        full_file_name = os.path.join(app.config['SITE_ROOT'], relative_temp_excel_file_name)

        # Save DataFrame to Excel
        df.to_excel(full_file_name, index=False)

        # Send the file as a downloadable attachment
        response = send_file(
            full_file_name,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            download_name=fileName,
            as_attachment=True
        )

        return response
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return {"error": "Unable to generate the report"}

@admin_reports.route("/admin_download_beneficiary_list_excel_reports", methods=["POST", "GET"])
@adminid_access_token_required
def admin_download_beneficiary_list_excel_reports():
    try:
        creditorAccountNumber = request.args.get("creditorAccountNumber", "")
        searchId = request.args.get("searchId", "")
        merchantId = request.args.get("merchantId", "")

        print(creditorAccountNumber,"((((((creditorAccountNumber))))))")
        print(searchId,"((((((searchId))))))")

        beneficiaries_queryset = Beneficiaries.objects.order_by("-createdOn").all()

        if searchId:
            beneficiaries_queryset = beneficiaries_queryset.filter(beneficiaryName__icontains=searchId)

        if creditorAccountNumber:
            beneficiaries_queryset = beneficiaries_queryset.filter(accountNumber__icontains=creditorAccountNumber)

        # if merchantId:
        #     user_ids = Users.objects(merchantUniqueNumber__icontains=merchantId).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)

        # print(merchantEmail,"((((((((((((((((merchantEmail))))))))))))))))")
        # if merchantEmail:
        #     user_ids = Users.objects(email__icontains=merchantEmail).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)

        # if merchantPhone:
        #     user_ids = Users.objects(phoneNumber__icontains=merchantPhone).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)
        
        # if merchantType:
        #         user_ids = Users.objects(merchantType__icontains=merchantType).values_list('id')
        #         user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)
            
        # if patternId:
        #     user_ids = Users.objects(patternId__icontains=patternId).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)
        
        # if parentId:
        #     user_ids = Users.objects(parentId__icontains=parentId).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)
        
        # if siteTitle:
        #     user_ids = Users.objects(siteTitle__icontains=siteTitle).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)

        
        return admin_download_beneficiary_list_excel_reports_data(beneficiaries_queryset)

    except Exception as e:
        app.logger.error(traceback.format_exc())
        return {"responseStatus": 0, "result": "Unable to download benificaries report data!"}
    
    
    
def admin_download_commission_reports_list_excel_reports_data(commission_transactions_queryset):
    relative_temp_excel_file_name = ""
    try:
        fileName = "commission_reports_list.xlsx"

        commission_reports_data = {
            "Merchant Name": [],
            "Trasaction ID": [],
            "Parent Commission Amount(₹)": [],
            # "Beneficiary Mail": [],
            # "Beneficiary Phone": [],
            "Amount(₹)": [],
            # "Fund Transfer Type": [],
            "Previous Balance": [],
            "Current Balance": [],
            "Transfer Type": [],
            # "Transaction Id": [],
            "Txn.Dt": [],
            # "Slab Name:": [],
            "Child Commission Value": [],
            "Child Commission Type": [],
            "Parrent Slab Commission Type:": [],
            "Parrent Slab Commission Value": [],
            "Parrent Commission Type": [],
            "Parrent Commission Data": [],
            "Settlement Status": [],
            "Comment": [],
            # "Narration": [],
            # "Status Message:": [],
        }

        for each_record in commission_transactions_queryset:
            # commission_reports_data["Merchant Name"].append(each_record.userId.fullName)
            commission_reports_data["Trasaction ID"].append(each_record.transactionId)
            commission_reports_data["Parent Commission Amount(₹)"].append(each_record.parrentCommissionAmount)
            # commission_reports_data["Beneficiary Mail"].append(each_record.beneficiaryMail) 
            # commission_reports_data["Beneficiary Phone"].append(each_record.beneficiaryPhone) 
            commission_reports_data["Amount(₹)"].append(each_record.totalAmount)
            # commission_reports_data["Fund Transfer Type"].append(each_record.fundTransferType)
            commission_reports_data["Previous Balance"].append(each_record.previousBalance)
            commission_reports_data["Current Balance"].append(each_record.currentBalance) 
            commission_reports_data["Transfer Type"].append(each_record.transferType)
            # commission_reports_data["Transaction Id"].append(each_record.transactionUniqueId)
            commission_reports_data["Txn.Dt"].append(each_record.createdOn)
            # commission_reports_data["Slab Name:"].append(each_record.slabName)
            commission_reports_data["Child Commission Value"].append(each_record.childCommissionValue) 
            commission_reports_data["Child Commission Type"].append(each_record.childCommissionType) 
            commission_reports_data["Parrent Slab Commission Type:"].append(each_record.parrentSlabCommissionType)
            commission_reports_data["Parrent Slab Commission Value"].append(each_record.parrentSlabCommissionValue)
            commission_reports_data["Parrent Commission Type"].append(each_record.parrentCommissionType)
            commission_reports_data["Parrent Commission Data"].append(each_record.parentcommissionData) 
            commission_reports_data["Settlement Status"].append(each_record.settlementStatus)
            commission_reports_data["Comment"].append(each_record.comment)
            # commission_reports_data["Narration"].append(each_record.narration)
            # commission_reports_data["Status Message:"].append(each_record.errorMessage)
            try:
                if each_record.userId:
                    commission_reports_data["Merchant Name"].append(each_record.userId.fullName)
                else:
                    commission_reports_data["Merchant Name"].append("N/A")
            except Exception as e:
                commission_reports_data["Merchant Name"].append("N/A")

        # Create DataFrame
        df = pd.DataFrame(commission_reports_data)

        # Define file path
        base_dir = os.path.join(app.config['SITE_ROOT'], "media/commission_reports", "users")
        os.makedirs(base_dir, exist_ok=True)

        relative_temp_excel_file_name = os.path.join("media/commission_reports", "users", fileName)
        full_file_name = os.path.join(app.config['SITE_ROOT'], relative_temp_excel_file_name)

        # Save DataFrame to Excel
        df.to_excel(full_file_name, index=False)

        # Send the file as a downloadable attachment
        response = send_file(
            full_file_name,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            download_name=fileName,
            as_attachment=True
        )

        return response
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return {"error": "Unable to generate the report"}

@admin_reports.route("/admin_download_commission_reports_list_excel_reports", methods=["POST", "GET"])
@adminid_access_token_required
def admin_download_commission_reports_list_excel_reports():
    try:
        # transactionId = request.args.get("transactionId", "")
        startDate = request.args.get("startDate","")
        endDate = request.args.get("endDate","")
        merchantId = request.args.get("merchantId", "")

        print(merchantId,"((((((merchantId))))))")

        date_format = "%d-%m-%Y"

        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format)
                startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
            else:
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

            if endDate:
                endDate = datetime.datetime.strptime(endDate, date_format)
                endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
            else:
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
       

        # commission_transactions_queryset = UserCommissions.objects.order_by("-createdOn").all()
        query = Q(createdOn__gte=startDate,createdOn__lte=endDate)

        # if orderId:
        #   commission_transactions_queryset = commission_transactions_queryset.filter(merchantReferenceNumber=orderId)

        if merchantId:
            # commission_transactions_queryset = commission_transactions_queryset.filter(userId__in=[merchantId])
            query  &= Q(userId__in=[merchantId])
        commission_transactions_queryset = UserCommissions.objects(query).order_by("-createdOn").all()

        # if merchantId:
        #     user_ids = Users.objects(merchantUniqueNumber__icontains=merchantId).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)

        # print(merchantEmail,"((((((((((((((((merchantEmail))))))))))))))))")
        # if merchantEmail:
        #     user_ids = Users.objects(email__icontains=merchantEmail).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)

        # if merchantPhone:
        #     user_ids = Users.objects(phoneNumber__icontains=merchantPhone).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)
        
        # if merchantType:
        #         user_ids = Users.objects(merchantType__icontains=merchantType).values_list('id')
        #         user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)
            
        # if patternId:
        #     user_ids = Users.objects(patternId__icontains=patternId).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)
        
        # if parentId:
        #     user_ids = Users.objects(parentId__icontains=parentId).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)
        
        # if siteTitle:
        #     user_ids = Users.objects(siteTitle__icontains=siteTitle).values_list('id')
        #     user_kycs_queryset = user_kycs_queryset.filter(userId__in=user_ids)

        
        return admin_download_commission_reports_list_excel_reports_data(commission_transactions_queryset)

    except Exception as e:
        app.logger.error(traceback.format_exc())
        return {"responseStatus": 0, "result": "Unable to download commission report data!"}
    

def generate_invoice_pdf2(invoice_template_list,company_invoice_templates_dict):
    try:
        pdf = FPDF()
        pdf.set_font("Arial", size=12)  
        for each_template in invoice_template_list:
            pdf.add_page()
            template_content = company_invoice_templates_dict.get(each_template.get("paymentGatewayId",""),"Empty") or "Empty"

            content = remove_html_tags(template_content)
            content = re.sub(r'\n\s*\n', '\n', content)
            content = content.replace('“', '"').replace('”', '"').replace('‘', "'").replace('’', "'")
            content=content.strip()

            pdf_width = pdf.w - 10  # PDF width minus margins
            pdf_height = pdf.h - 20  # PDF height minus margins

            # Define the width of the text area
            text_width = 190  # Adjust as needed (PDF width - margins)

            pdf.set_x(10)  # Set starting x position (left margin)
            try:
                pdf.multi_cell(text_width, 10, txt = content.encode('latin-1', 'ignore').decode('latin-1'), border=0, align="L")
            except UnicodeEncodeError as e:
                print(f"Unicode error: {e}")
                return False
        media_dir = os.path.join(app.config['SITE_ROOT'], "media")
        signature_dir = os.path.join(media_dir, "invoice_template")
        os.makedirs(signature_dir, exist_ok=True)
        pdf_file_path = os.path.join(signature_dir, "output.pdf")
        pdf.output(pdf_file_path)
        print("saved file path:", pdf_file_path)

        # Send the generated PDF file directly to the user
        return send_file(pdf_file_path, as_attachment=True, download_name="output.pdf", mimetype="application/pdf")
    
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to generate the invoice!!"
        return False

def mask_and_get_value(value):
    result = '*'*(len(value)-4)
    result += value[-4:]
    return result

def generate_invoices_pdf(walletType, invoice_template_list,company_invoice_templates_dict):
    result = {"status":False, "msg":"Unable to generate the invoice!!"}
    try:
        html_content = ""
        first_template = True
        print("length===========",len(invoice_template_list))
        if not len(invoice_template_list):
            result["msg"] = "No records found !!"
            return result

        for each_template in invoice_template_list:
            template_content = company_invoice_templates_dict.get(each_template.get("paymentGatewayId",""),each_template.get("apiName") + " Template Not Found") or each_template.get("apiName") +" Template Not Found"
            template_content = template_content.replace("initial","#000000")
            template_content = template_content.replace("{#invoiceId#}",str(each_template.get("invoiceId","")) or str(each_template.get("orderId","")))
            template_content = template_content.replace("{#grandTotal#}", str(round(float(str(each_template.get("grandTotal",'0')or '0').replace(",","")),2)))
            template_content = template_content.replace("{#amount#}", str(round(float(str(each_template.get("amount",'0')or '0').replace(",","")),2)))
            template_content = template_content.replace("{#transactionId#}",each_template.get("transactionId",""))
            gstAmount = float(str(each_template.get("gstAmount",0) or 0).replace(",",""))
            chargeAmount = float(str(each_template.get("chargeAmount",0) or 0).replace(",",""))
            charges = round(chargeAmount+gstAmount,2)
            template_content = template_content.replace("{#charges#}", str(charges))

            created_on_date = each_template.get("createdOn")
            if created_on_date:
                date_format = "%d-%m-%Y %I:%M %p"
                created_on_date = datetime.datetime.strptime(created_on_date, date_format)
                new_time = created_on_date + timedelta(minutes=2)
                dueDate = created_on_date + timedelta(days=15)

                # Format the new time in 'DD-MM-YYYY HH:MM' format (24-hour clock)
                recipientDate = new_time.strftime('%d-%m-%Y %H:%M')
                createdon = created_on_date.strftime('%d-%m-%Y %H:%M')
                issuedDate = created_on_date.strftime('%d-%m-%Y')
                dueDate = dueDate.strftime('%d-%m-%Y')
                template_content = template_content.replace("{#issuedDate#}",issuedDate)
                template_content = template_content.replace("{#dueDate#}",dueDate)
                template_content = template_content.replace("{#issuedDateTime#}",createdon)
                template_content = template_content.replace("{#recipientDate#}",recipientDate)

            if walletType == "payin":
                template_content = template_content.replace("{#customerName#}",each_template.get("customerName",""))
                template_content = template_content.replace("{#customerEmail#}", each_template.get("customerEmail",""))
                template_content = template_content.replace("{#userName#}", each_template.get("merchantName",""))
                template_content = template_content.replace("{#userEmail#}", each_template.get("merchantEmail",""))
                template_content = template_content.replace("{#productName#}", str(each_template.get("productName","")))
                paymentMode = each_template.get("card_type","") + " " + each_template.get("mode","") + " " +each_template.get("cardmasked","")
                template_content = template_content.replace("{#paymentMode#}", paymentMode)

                userId = each_template.get("userId")
                if userId:
                    user_kyc_queryset = UserKYC.objects(userId=userId).first()
                    bankAccount = user_kyc_queryset.bankAccountNumber or ""
                    if bankAccount:
                        bankAccount = mask_and_get_value(bankAccount)
                    template_content = template_content.replace("{#bankAccount#}",bankAccount)
                    panNumber = user_kyc_queryset.panNumber or ""
                    if panNumber:
                        panNumber = mask_and_get_value(panNumber)
                    template_content = template_content.replace("{#panNumber#}",panNumber)
 
            else:
                template_content = template_content.replace("{#customerName#}", each_template.get("beneficiaryName", "") or "")
                template_content = template_content.replace("{#customerEmail#}", each_template.get("beneficiaryMail","") or "")
            
            if first_template:
                html_content += f"""
                <div style="font-family:Arial, Helvetica, sans-serif">
                    {template_content}
                </div>
                """
                first_template = False
            else:
                html_content += f"""
                <div style="page-break-before: always; font-family:Arial, Helvetica, sans-serif">
                    {template_content}
                </div>
                """
        media_dir = os.path.join(app.config['SITE_ROOT'], "media")
        signature_dir = os.path.join(media_dir, "invoice_template")
        os.makedirs(signature_dir, exist_ok=True)
        pdf_file_path = os.path.join(signature_dir, "output.pdf")
 
        with open(pdf_file_path, "w+b") as pdf_file:
            pisa_status = pisa.CreatePDF(html_content, dest=pdf_file)
 
        if pisa_status.err:
            print("Error in PDF generation")
            return result
        else:
            print("PDF generated successfully")
 
        print("saved file path:", pdf_file_path)
 
        # Send the generated PDF file directly to the user
        return send_file(pdf_file_path, as_attachment=True, download_name="output.pdf", mimetype="application/pdf")
   
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return result
 
 
    # # Send the generated PDF file as a response for download
    # return send_file(pdf_output, as_attachment=True)

class ReportsDownloadInvoices(FlaskForm):
    walletType = SelectField('', choices=[('', 'Select Wallet Type'),('payin', 'Pay In'), 
                                 ('payout', 'Pay Out')],validate_choice=True , validators=[DataRequired(message="Wallet Type is required")])
    option = RadioField('', 
                        choices=[('all', 'All'), 
                                 ('partial', 'Partial')],
                        validators=[InputRequired()])
    startDate = StringField('',validators=[Optional(),Regexp( r"^\d{2}-\d{2}-\d{4}$", message="Date must be in DD-MM-YYYY format")])
    endDate = StringField('', validators=[ Optional(), Regexp( r"^\d{2}-\d{2}-\d{4}$", message="Date must be in DD-MM-YYYY format")])
    searchId = TextAreaField('', validators=[])
    pgId = SelectField('', choices=[],validate_choice=False , validators=[DataRequired(message="PG is required")])

            
    def validate_pgId(self, field):
        if field.data:
            if not ObjectId.is_valid(field.data): 
                raise ValidationError("Invalid PG")

    class Meta:
        csrf = False


@admin_reports.route("/download_invoices", methods=["GET", "POST"])
@adminid_access_token_required
@csrf_protect
def download_invoices():
    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
    payinList = []
    merchantsList = []
    invoices_list = []
    form = ReportsDownloadInvoices()

    company_invoice_templates_dict=""
    transactionIds = ""
    option = "all"
    pgId = ""
    walletType = ""
    result = ""
    csrf_token = request.form.get("csrf_token")
    print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
    if not session.get("adminId"):
        return redirect("admin_login")
    
    permissionsList = check_permissions(session.get("adminId"),"downloadInvoicesPermission")
    if "view" in permissionsList:
        try:
            adminId = session.get("adminId")
            date_format = "%d-%m-%Y"
            pgList = []
            # Set default date format
            
            pg_queryset = TransactionAPI.objects(status__in=[0,1]).order_by("-id")
            for each_pg in pg_queryset:
                pgDict = fetching_transaction_api_details(each_pg)
                pgList.append(pgDict)

            if request.method == "GET":
                return render_template("super_admin_templates/download_invoices.html",
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).strftime(date_format),
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999).strftime(date_format),
                form=form,
                pgList = pgList,
                option="all"
                )
            

            startDate = request.form.get("startDate","")
            endDate = request.form.get("endDate","")
            option = request.form.get("option","all")
            transactionIds = request.form.get("searchId","")
            pgId=request.form.get("pgId","")
            walletType = request.form.get("walletType","")
            transactionIds = transactionIds.strip()
            transactionIdList = transactionIds.split(",")
            transactionIdList = [id.strip() for id in transactionIdList] 

            try:
                if startDate:
                    startDate = datetime.datetime.strptime(startDate, date_format)
                    startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
                else:
                    startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

                if endDate:
                    endDate = datetime.datetime.strptime(endDate, date_format)
                    endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
                else:
                    endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            except Exception as ve:
                app.logger.error("Date parsing error: %s", ve)
                startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)

            if form.validate():
                if walletType == "payin":
                    payin_wallet_transaction_queryset = WalletTransactions.objects().order_by("-createdOn").all()
                    if pgId:
                        payin_wallet_transaction_queryset = payin_wallet_transaction_queryset.filter(paymentGatewayId=pgId)
                elif walletType == "payout":
                    payout_fund_transfer_queryset = FundTransfers.objects().order_by("-createdOn").all()
                    if pgId:
                        payout_fund_transfer_queryset = payout_fund_transfer_queryset.filter(transactionAPIId=pgId)
                
                if walletType=="payin" and option == "all":
                    payin_wallet_transaction_queryset = payin_wallet_transaction_queryset.filter(createdOn__gte=startDate,createdOn__lte=endDate)
                elif walletType == "payin" and option == "partial":
                    payin_wallet_transaction_queryset = payin_wallet_transaction_queryset.filter(Q(transactionId__in=transactionIdList) | Q(orderId__in=transactionIdList) | Q(pgOrderId__in=transactionIdList))
                elif walletType == "payout" and option == "all":
                    payout_fund_transfer_queryset = payout_fund_transfer_queryset.filter(createdOn__gte=startDate,createdOn__lte=endDate)
                elif walletType == "payout" and option == "partial":
                    payout_fund_transfer_queryset = payout_fund_transfer_queryset.filter(Q(transactionUniqueId__in=transactionIdList) | Q(pgOrderId__in=transactionIdList))

                if walletType == "payin":
                    invoices_list = []
                    for each_record in payin_wallet_transaction_queryset:
                        invoices_list.append(fetching_payin_details(each_record))
                else:
                    invoices_list = []
                    for each_record in payout_fund_transfer_queryset:
                        invoices_list.append(fetch_payout_fund_transfer_details(each_record))
                # if option =="all":
                company_invoice_templates_dict = fetch_company_invoice_details()

                result = generate_invoices_pdf(walletType,invoices_list, company_invoice_templates_dict)

                print(result,"((((((((((((((((((((((((((result))))))))))))))))))))))))))")
                if not isinstance(result, dict):
                    return result
                else:
                    error = result.get("msg") or "Unable to generate the invoice!!"
                    return render_template("super_admin_templates/download_invoices.html", 
                        error=error,
                        startDate=startDate.strftime(date_format),
                        endDate=endDate.strftime(date_format),
                        searchId = transactionIds,
                        option = option,
                        form = form,
                        pgId=pgId,
                        pgList = pgList,
                        walletType = walletType
                    )
            else:
                 return render_template("super_admin_templates/download_invoices.html", 
                        error="",
                        startDate=startDate.strftime(date_format),
                        endDate=endDate.strftime(date_format),
                        searchId = transactionIds,
                        option = option,
                        form = form,
                        pgId=pgId,
                        pgList = pgList,
                        walletType = walletType
                    )
        except Exception as e:
            app.logger.error(traceback.format_exc())
            error = "Unable to generate the invoice!!"
            return render_template("super_admin_templates/download_invoices.html", 
                error=error,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                searchId = transactionIds,
                option = option,
                form = form,
                pgId=pgId,
                pgList = pgList,
                walletType = walletType
                )
    else:
        flash("The staff member does not have permission to view Download invoice details.", "danger")
        return redirect(url_for("admin.dashboard"))

# @admin_reports.route("/download_invoices", methods=["GET", "POST"])
# @adminid_access_token_required
# @csrf_protect
# def download_invoices():
#     csrf_token = request.form.get("csrf_token")
#     print(csrf_token,"((((((((((((((csrf_token))))))))))))))")
#     if not session.get("adminId"):
#         return redirect("admin_login")
    
#     permissionsList = check_permissions(session.get("adminId"),"payinLedgerReportPermissions")
#     if "view" in permissionsList:
#         try:
#             adminId = session.get("adminId")
#             payinList = []
#             merchantsList = []
#             # pgList = []
#             # Set default date format
#             date_format = "%d-%m-%Y"
            
#             # pg_queryset = TransactionAPI.objects(status__in=[0,1]).order_by("-id")
#             # for each_pg in pg_queryset:
#             #     pgDict = fetching_transaction_api_details(each_pg)
#             #     pgList.append(pgDict)

#             if request.method == "GET":
#                 return render_template("super_admin_templates/download_invoices.html",
#                 startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).strftime(date_format),
#                 endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999).strftime(date_format),
#                 # pgList = pgList,
#                 option="all"
#                 )
            

#             startDate = request.form.get("startDate","")
#             endDate = request.form.get("endDate","")
#             option = request.form.get("option","all")
#             transactionIds = request.form.get("searchId","")
#             pgId=request.form.get("pgId","")
#             walletType = request.form.get("walletType","")
#             transactionIds = transactionIds.strip()
#             transactionIdList = transactionIds.split(",")
#             transactionIdList = [id.strip() for id in transactionIdList] 


#             try:
#                 if startDate:
#                     startDate = datetime.datetime.strptime(startDate, date_format)
#                     startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
#                 else:
#                     startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

#                 if endDate:
#                     endDate = datetime.datetime.strptime(endDate, date_format)
#                     endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
#                 else:
#                     endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
#             except Exception as ve:
#                 app.logger.error("Date parsing error: %s", ve)
#                 startDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
#                 endDate = datetime.datetime.now().replace(hour=23, minute=59, second=59, microsecond=999999)
            
#             if walletType == "payin":
#                 payin_wallet_transaction_queryset = WalletTransactions.objects().order_by("-createdOn").all()
#                 if pgId:
#                     payin_wallet_transaction_queryset = payin_wallet_transaction_queryset.filter(paymentGatewayId=pgId)
#             elif walletType == "payout":
#                 payout_fund_transfer_queryset = FundTransfers.objects().order_by("-createdOn").all()
#                 if pgId:
#                     payout_fund_transfer_queryset = payout_fund_transfer_queryset.filter(transactionAPIId=pgId)
            
#             if walletType=="payin" and option == "all":
#                 payin_wallet_transaction_queryset = payin_wallet_transaction_queryset.filter(createdOn__gte=startDate,createdOn__lte=endDate)
#             elif walletType == "payin" and option == "partial":
#                 payin_wallet_transaction_queryset = payin_wallet_transaction_queryset.filter(Q(transactionId__in=transactionIdList) | Q(orderId__in=transactionIdList) | Q(pgOrderId__in=transactionIdList))
#             elif walletType == "payout" and option == "all":
#                 payout_fund_transfer_queryset = payout_fund_transfer_queryset.filter(createdOn__gte=startDate,createdOn__lte=endDate)
#             elif walletType == "payout" and option == "partial":
#                 payout_fund_transfer_queryset = payout_fund_transfer_queryset.filter(Q(transactionUniqueId__in=transactionIdList) | Q(pgOrderId__in=transactionIdList))

#             if walletType == "payin":
#                 invoices_list = []
#                 for each_record in payin_wallet_transaction_queryset:
#                     invoices_list.append(fetching_payin_details(each_record))
#             else:
#                 invoices_list = []
#                 for each_record in payout_fund_transfer_queryset:
#                     invoices_list.append(fetch_payout_fund_transfer_details(each_record))
#             # if option =="all":
#             company_invoice_templates_dict = fetch_company_invoice_details()

#             result = generate_invoices_pdf(walletType,invoices_list, company_invoice_templates_dict)
#             if not isinstance(result, dict):
#                 return result
#             else:
#                 error = result.get("msg") or "Unable to generate the invoice!!"
#                 return render_template("super_admin_templates/download_invoices.html", 
#                 error=error,
#                 startDate=startDate.strftime(date_format),
#                 endDate=endDate.strftime(date_format),
#                 searchId = transactionIds,
#                 option = option,
#                 pgId=pgId,
#                 # pgList = pgList,
#                 walletType = walletType
#                 )
        
#         except Exception as e:
#             app.logger.error(traceback.format_exc())
#             error = "Unable to generate the invoice!!"
#             return render_template("super_admin_templates/download_invoices.html", 
#                 error=error,
#                 startDate=startDate.strftime(date_format),
#                 endDate=endDate.strftime(date_format),
#                 searchId = transactionIds,
#                 option = option,
#                 pgId=pgId,
#                 # pgList = pgList,
#                 walletType = walletType
#                 )


@admin_reports.route("/admin_download_commissions_settlement_excel_reports",methods=["POST","GET"])
@adminid_access_token_required
@csrf_protect
def admin_download_commissions_settlement_excel_reports():
    data_status={"responseStatus":0,"result":""}
    try:
        commissionsList = []
        startMonthYear = None
        selectYear = None
        selectMonth = None
        current_year = None
        last_year = None
        tdsChargePer=0
        tdsLimitAmount=0


        selectYear = request.args.get("selectYear", default=str(datetime.datetime.now().year))
        selectMonth = request.args.get("selectMonth", default=datetime.datetime.now().strftime("%B"))

        tdsStartDate, tdsEndDate  = get_financial_year_dates(selectMonth, int(selectYear))
        # Get the month number from the month name
        month_number = datetime.datetime.strptime(selectMonth, "%B").month

        current_year = datetime.datetime.now().year
        last_year = current_year - 1

        # Construct startMonthYear and endMonthYear
        startMonthYear = datetime.datetime(int(selectYear), month_number, 1)
        endMonthYear = datetime.datetime(int(selectYear), month_number, monthrange(int(selectYear), month_number)[1])

        if startMonthYear and endMonthYear:
            startMonthYear = startMonthYear.replace(hour=0, minute=0, second=0, microsecond=0)
            endMonthYear = endMonthYear.replace(hour=23, minute=59, second=59, microsecond=999999)

        pipeline = [
            {
                "$lookup": {
                    "from": "users",
                    "localField": "userId",
                    "foreignField": "_id",
                    "as": "userDetails"
                }
            },
            {
                "$match": {
                    "createdOn": {
                        "$gte": startMonthYear,
                        "$lte": endMonthYear
                    },
                    "settlementStatus": 1
                }
            },
            {
                "$unwind": "$userDetails"
            },
            {
                "$group": {
                    "_id": {"userId": "$userId"},
                    "totalUserParentCommissionAmount": {"$sum": "$parrentCommissionAmount"},
                    "totalUserParentGstAmount": {"$sum": "$parrentGstAmount"},
                    "totalUserParentTdsAmount": {"$sum": "$parrentTdsAmount"},
                    "usertotalAmount": {"$sum": "$totalAmount"}
                }
            }
        ]

        merchant_wise_commission_transactions = list(UserCommissions.objects.aggregate(*pipeline))
        print(merchant_wise_commission_transactions, "**********merchant_wise_commission_transactions***********")

        commission_tds_setup_queryset = CommissionTdsSetup.objects(status=1).first()
        if commission_tds_setup_queryset:
            tdsLimitAmount = commission_tds_setup_queryset.tdsLimitAmount
            tdsChargePercent = commission_tds_setup_queryset.tdsChargePer
        

        for each_commission in merchant_wise_commission_transactions:
            # print(each_commission, "(((((((((((each_commission)))))))))))")
            tdsValue=0
            tdsTotal=0
            netCommissionAmount=0
            diffCommissionAmount=0
            temp_end_date = tdsEndDate
                
            netCommissionAmount = float(each_commission.get("totalUserParentCommissionAmount"))
            totalUserParentGstAmount = float(each_commission.get("totalUserParentGstAmount"))
            totalUserParentTdsAmount = float(each_commission.get("totalUserParentTdsAmount"))
            usertotalAmount = float(each_commission.get("usertotalAmount"))
            CommissionAmount=netCommissionAmount

            commission_transaction_queryset = UserCommissions.objects(userId=each_commission.get("_id").get("userId")).first()
            totalOverallCommission = UserCommissions.objects(userId=each_commission.get("_id").get("userId"),createdOn__gte=tdsStartDate,createdOn__lte=tdsEndDate).sum("parrentCommissionAmount")

            # print("totalOverallCommission >= tdsLimitAmount", totalOverallCommission >= tdsLimitAmount, totalOverallCommission, tdsLimitAmount)
            
            if totalOverallCommission >= tdsLimitAmount:
                ### to check if it crosssed this month or prev month change date to 1 month before
                if temp_end_date.month !=4:
                    temp_end_date = temp_end_date - relativedelta(months=1)
                    totalOverallCommissionPreviousMonth = UserCommissions.objects(userId=each_commission.get("_id").get("userId"),createdOn__gte=tdsStartDate,createdOn__lte=temp_end_date).sum("parrentCommissionAmount")
                    ###### if it crossed prev month only cal tds for current month diff
                    if totalOverallCommissionPreviousMonth >= tdsLimitAmount:
                        print("prev month tds eligible for ",commission_transaction_queryset.userId.fullName)
                        tdsValue = tdsChargePercent
                        # diffCommissionAmount = totalOverallCommission - totalOverallCommissionPreviousMonth
                        tdsTotal = round(float((netCommissionAmount / 100) * tdsChargePercent),2) ### tds amount calculated
                        CommissionAmount = netCommissionAmount -   tdsTotal #### doubt
                    else:
                        print("curr month tds eligible for ",commission_transaction_queryset.userId.fullName)
                        tdsValue = tdsChargePercent
                        tdsTotal = round(float((totalOverallCommission / 100) * tdsChargePercent),2)   ### tds amount calculated 
                        CommissionAmount = netCommissionAmount -   tdsTotal

            commissionDict = {
                "id": str(commission_transaction_queryset.id),
                "merchantId": str(commission_transaction_queryset.userId.id),
                "merchantName": commission_transaction_queryset.userId.fullName,
                "merchantType": commission_transaction_queryset.userId.merchantType,
                "totalAmount": round(usertotalAmount,2),
                "totalUserParentCommissionAmount": round(netCommissionAmount,2),
                "commissionAmount": round(CommissionAmount,2),
                "totalOverallCommission": round(totalOverallCommission,2),
                "tdsValue": round(tdsValue,2),
                "tdsTotal": round(tdsTotal,2)
            }
            commissionsList.append(commissionDict)


        # # Execute the aggregation pipeline
        # merchant_wise_commission_transactions = list(UserCommissions.objects.aggregate(*pipeline))
        # print(merchant_wise_commission_transactions, "**********merchant_wise_commission_transactions***********")
        fileName = str(selectMonth)+ "_"+str(selectYear) +"_commission_settlements.xlsx"
        reportData = admin_download_commissions_settlement_excel_reports_data(commissionsList,fileName)
        return reportData
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to download Commissions Settlement ledger report data!!"
        return data_status

def  admin_download_commissions_settlement_excel_reports_data(merchant_wise_commission_transactions,fileName):
    # downloadPayoutExcelReportsList = []
    relative_temp_excel_file_name = ""
    try:

        commissions_settlement_data = {
            "Merchant Name": [],
            "Merchant Type": [],
            "TXN Amount(₹)": [],
            "Overal Commission(₹)": [], #######
            "Net Commission(₹)": [], #######
            "Tds (%)": [], #######
            "Tds Amount(₹)": [], #######
            "Commission Amount(₹)": [], #######
        }
        for each_record in merchant_wise_commission_transactions:
            print("id check",each_record)

            try:
                name_number = str(each_record.get("merchantName")) + " - "+  str(each_record.get("merchantPhoneNumber"))
                commissions_settlement_data["Merchant Name"].append(name_number)
            except Exception as e:
                commissions_settlement_data["Merchant Name"]=""
                pass
            try:
                commissions_settlement_data["Merchant Type"].append(each_record.get("merchantType"))
            except Exception as e:
                commissions_settlement_data["Merchant Type"]=""
                pass
            try:
                commissions_settlement_data["TXN Amount(₹)"].append(each_record.get("totalAmount"))
            except Exception as e:
                commissions_settlement_data["TXN Amount(₹)"]="0"
                pass
            try:
                commissions_settlement_data["Tds (%)"].append(each_record.get("tdsValue"))
            except Exception as e:
                commissions_settlement_data["Tds (%)"]="0"
                pass
            try:
                commissions_settlement_data["Tds Amount(₹)"].append(each_record.get("tdsTotal"))
            except Exception as e:
                commissions_settlement_data["Tds Amount(₹)"]="0"
                pass
            try:
                commissions_settlement_data["Commission Amount(₹)"].append(each_record.get("commissionAmount"))
            except Exception as e:
                commissions_settlement_data["Commission Amount(₹)"]="0"
                pass
            try:
                commissions_settlement_data["Net Commission(₹)"].append(each_record.get("totalUserParentCommissionAmount"))
            except Exception as e:
                commissions_settlement_data["Net Commission(₹)"]="0"
                pass
            try:
                commissions_settlement_data["Overal Commission(₹)"].append(each_record.get("totalOverallCommission"))
            except Exception as e:
                commissions_settlement_data["Overal Commission(₹)"]="0"
                pass
            

        # Create DataFrame
        df = pd.DataFrame(commissions_settlement_data)

        # Define file path
        base_dir = os.path.join(app.config['SITE_ROOT'], "media/admin_reports", "commission_settlements")
        if not os.path.exists(base_dir):
            os.makedirs(base_dir)

        relative_temp_excel_file_name = os.path.join("media/admin_reports", "commission_settlements", fileName)
        os.makedirs(base_dir, exist_ok=True)
        full_file_name = os.path.join(app.config['SITE_ROOT'], relative_temp_excel_file_name)

        # Save DataFrame to Excel
        df.to_excel(full_file_name, index=False)

        # Send the file as a downloadable attachment
        return send_file(
            full_file_name,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            download_name=fileName,
            as_attachment=True
        )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return relative_temp_excel_file_name




@admin_reports.route("/bbpspaymentretry",methods=["POST","GET"])
@adminid_access_token_required
@csrf.exempt
def bbpspaymentretry():
    data_status={"responseStatus":0,"result":""}
    try:
        billPaymentRequestData=[]
        billPaymentResponseData=[]
        data = request.get_json()
        transactionId=data.get("transactionId")
        print("--------------",data,transactionId)
        if not transactionId:
            data_status["result"]="Required field is missing!!" 
            return data_status

        transaction_query_set = Transactions.objects(id=transactionId).first()
        if not transactionId:
            data_status["result"]="Invalid transaction Id!!" 
            return data_status
        payload=transaction_query_set.payload
        headers=transaction_query_set.headers
        print(payload,"=============",headers)
        authtokenresp=getBbpsAuthorizationToken()
        authorizationToken=authtokenresp.get('accessToken')

        headers = {
            "content-type": "application/json",
            "authorization": "Bearer "+str(authorizationToken),
            }
        print(headers,"---------headers===========")
        headerdata=transaction_query_set.update(headers=headers)
        timestamp=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        payload["timeStamp"]=timestamp
        user_queryset = Users.objects(id=str(transaction_query_set.userId.id),status__in=[1]).first()
        if not user_queryset:
            data_status["result"]="Invalid User Id!!" 
            return data_status
       
        # billPaymentRequestData.append(payload)
        # billPaymentRequestData.append(headers)
        # billpaymentresult=payuBillPayment(payload,headers)#live that Why Commented
        # if billpaymentresult.get('responseStatus')==1:
        #     billpaymentresponse=billpaymentresult.get('result')
        #     billPaymentResponseData.append(billpaymentresponse)
        #     bbpsoperatorReference=billpaymentresponse.get('payload').get('refId')
        #     if billpaymentresponse.get('status')=="SUCCESS":
        #         print('bbps success')
        #         status=1
        #         errorMessage=billpaymentresponse.get('status')
        #         bbpsPaymentStatus=1
        #         refundStatus=1
        #         transaction_query_set.update(bbpsPaymentStatus=bbpsPaymentStatus,refundStatus=refundStatus,status=status)
        #         try:
        #             merchantName = str(user_queryset.fullName)
        #             phoneNumber = str(user_queryset.phoneNumber)
        #             merchantEmail = str(user_queryset.email)
        #             tramount=formatINR("{:.2f}".format(float(transaction_query_set.amount)))
        #             smsResponse=send_sms(phoneNumber,"Bill_Payment_Success","","",str(tramount),str(transaction_query_set.serviceName),str(transactionId))
        #             createdOn=transaction_query_set.createdOn
        #             trnsactionDate = datetime.datetime.now().strftime("%d-%m-%Y %I:%M %p")
        #             mail_subject = "Bill Payment of "+str(tramount)+" was successful for "+str(transaction_query_set.serviceName)
        #             recipients_list = [merchantEmail]
        #             template_name = "emails/billpayment.html"
        #             customeParamsList=transaction_query_set.customeParamsList
        #             billerNumber = list(customeParamsList.values())[0]
        #             print(billerNumber,"billerNumber")
        #             mail_data = {
        #             "merchantName":merchantName,
        #             "billservicename":str(transaction_query_set.serviceName),
        #             "billername":str(transaction_query_set.operatorName),
        #             "billerNumber":str(billerNumber),
        #             "amount":tramount,
        #             "orderId":str(transactionId),
        #             "transactionDate":trnsactionDate,
        #             }
        #             mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
        #             data_status["responseStatus"]=1
        #             data_status["result"]="BBPS Payment Successfully."
        #         except Exception as e:
        #             app.logger.error(traceback.format_exc())
        #             pass
        #     elif billpaymentresponse.get('status')=="FAILURE":
        #         status=0
        #         errorMessage="Payment Failed."
        #         bbpsPaymentStatus=0
        #         refundStatus=0
        #         transaction_query_set.update(bbpsPaymentStatus=bbpsPaymentStatus,refundStatus=refundStatus,status=status)
        #         data_status["responseStatus"]=0
        #         data_status["result"]=errorMessage
        # 	transaction_query_set.update(billPaymentRequestData=billPaymentRequestData,billPaymentResponseData=billPaymentResponseData,operatorReference=bbpsoperatorReference,errorMessage=errorMessage)
        # else:
        # 	data_status["responseStatus"]=0
        # 	data_status["result"]="Invalid Payment Request"

        data_status["responseStatus"]=0#dummy this line for testing
        data_status["result"]="BBPS Payment Failed"
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to Retry BBPS Payment!!"
        return data_status




@admin_reports.route("/bbpspaymentrefund",methods=["POST"])
@adminid_access_token_required
@csrf.exempt
def bbpspaymentrefund():
    data_status={"responseStatus":0,"result":""}
    try:
        data = request.get_json()
        print("--------------",data)
        txnId=data.get("txnId")
        amount=data.get("amount")
        if not txnId and not amount:
            data_status["result"]="Required Field Missing."
            return data_status
        payin_transactions= Transactions.objects(id=str(txnId)).first()
        if not payin_transactions:
            data_status["result"]="Invalid Request."
            return data_status
        payin_gate_way_queryset= TransactionAPI.objects(id=str(payin_transactions.transactionAPIId.id),status=1).first()
        if not payin_gate_way_queryset:
            data_status["result"]="Invalid Request."
            return data_status
        paymentGateWayCode = payin_gate_way_queryset.code
        print(paymentGateWayCode,"==paymentGateWayCode==",payin_gate_way_queryset.paramsList)

        original_txnId=payin_transactions.transactionData[0]["mihpayid"]
        if not original_txnId:
            data_status["result"]="Invalid Request."
            return data_status
        transaction_id= random_digit_generate(15)
        callback_url= "https://www.abc.com"

        for each_key in payin_gate_way_queryset.paramsList: 
            get_key = each_key.get("key")
            if get_key == "api_key":
                get_api_key = each_key.get("value")
                print(get_api_key,"get_api_key")
            if get_key == "base_url":
                get_base_url = each_key.get("value")
                print(get_base_url,"get_base_url")
            if get_key == "salt":
                get_salt = each_key.get("value")
                print(get_salt,"get_salt")
            
        get_base_url="https://test.payu.in/merchant/postservice.php"
        
        response = payu_refund(get_api_key,get_salt,get_base_url,original_txnId,transaction_id,amount,callback_url)
        print(response,"response",type(response))
        # responsedata=json.loads(response.text)
        refundResponseStatus={}
        if response["responseStatus"]==1:	
            status=1
            bbpsPaymentStatus=0
            refundStatus=5 #Refund
            payin_transactions.update(bbpsPaymentStatus=bbpsPaymentStatus,refundStatus=refundStatus,status=status,refundResponse=response,refundResponseStatus=refundResponseStatus)
            data_status["responseStatus"]=1
            data_status["result"]="Refund Successfully"
            print(data_status)
            return data_status

        elif response["responseStatus"]==0:
            status=0
            bbpsPaymentStatus=0
            refundStatus=0 #Refund
            print(response,"=======response========response========")
            payin_transactions.update(bbpsPaymentStatus=bbpsPaymentStatus,refundStatus=refundStatus,status=status,refundResponse=response,refundResponseStatus=refundResponseStatus)
            data_status["responseStatus"]=0
            data_status["result"]="Refund Failed"
            print(data_status)
            return data_status		

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to Refund BBPS Payment !!"
        return data_status




@admin_reports.route("/bbpspaymentrefundstatus",methods=["POST"])
# @adminid_access_token_required
@csrf.exempt
def bbpspaymentrefundstatus():
    data_status={"responseStatus":0,"result":""}
    try:
        data = request.get_json()
        txnId=data.get("refundId")
        print(txnId,"=======")

        if not txnId:
            data_status["result"]="Required Field Missing."
            return data_status
        payin_transactions= Transactions.objects(id=str(txnId)).first()
        if not payin_transactions:
            data_status["result"]="Invalid Request."
            return data_status
        payin_gate_way_queryset= TransactionAPI.objects(id=str(payin_transactions.transactionAPIId.id),status=1).first()
        if not payin_gate_way_queryset:
            data_status["result"]="Invalid Request."
            return data_status
        paymentGateWayCode = payin_gate_way_queryset.code
        print(paymentGateWayCode,"==paymentGateWayCode==",payin_gate_way_queryset.paramsList)

        request_id=payin_transactions.refundResponse["mihpayid"]
        if not request_id:
            data_status["result"]="Invalid Transaction Id."
            return data_status
        

        for each_key in payin_gate_way_queryset.paramsList: 
            get_key = each_key.get("key")
            if get_key == "api_key":
                get_api_key = each_key.get("value")
                print(get_api_key,"get_api_key")
            if get_key == "base_url":
                get_base_url = each_key.get("value")
                print(get_base_url,"get_base_url")
            if get_key == "salt":
                get_salt = each_key.get("value")
                print(get_salt,"get_salt")
            
        get_base_url="https://test.payu.in/merchant/postservice.php"
        response = payu_refund_status(get_api_key,get_salt,get_base_url,request_id)
        print(response,"response",type(response))

        if response.get("responseStatus")==0:
            data_status["responseStatus"]=0
            data_status["result"]="Our banking partner server is down please try after sometime!!"
            return data_status
        

        def stringify_keys(d):
            if isinstance(d, dict):
                return {str(k): stringify_keys(v) for k, v in d.items()}
            elif isinstance(d, list):
                return [stringify_keys(i) for i in d]
            return d
        transaction_details=response.get("transaction_details",{})
        transaction_details = stringify_keys(transaction_details)
        print(transaction_details,"=========transaction_details=======",type(transaction_details))

        
        refundResponseStatus=payin_transactions.refundResponseStatus
        print(refundResponseStatus,"====refundResponseStatus====",type(refundResponseStatus))
        resStatus=payin_transactions.update(refundResponseStatus=transaction_details)
        responsedict={}
        responsedict={
            "transactionId": response.get("transactionId",""),
            "bankRefNum":response.get("bankRefNum",""),
            "amount":response.get("amount",""),
            "mode":response.get("mode",""),
            "refundStatus":response.get("refundStatus",""),
            "action":response.get("action",""),
            "UTR_No":response.get("UTR_No","")	
        }
        
        data_status["responseData"]=responsedict
        data_status["responseStatus"]=1
        data_status["result"]="Transaction Record Fetch Successfully"
        return data_status
    
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable To Fetch Transaction Record !!"
        return data_status





@admin_reports.route('/gettransactionrefundStatus', methods=['POST'])
@adminid_access_token_required
@csrf.exempt
def gettransactionrefundStatus():
    data_status={"responseStatus":0,"result":""}
    try:
        data = request.get_json()
        refund_id=data.get("refundId")
        print(data,"***************data8******************")

        if not refund_id:
            data_status["result"]="Required Field Missing."
            return data_status

        print(refund_id,"====refund_id")

        payin_transactions= Transactions.objects(id=str(refund_id)).first()
        if not payin_transactions:
            data_status["result"]="Invalid Request."
            return data_status
        responseDict={}
        if payin_transactions.refundStatus == 0 or payin_transactions.refundStatus == 1 :
            if len(payin_transactions.refundResponse)==0:
                data_status["responseStatus"]=1
                data_status["responseDict"]=responseDict
                data_status["result"]="Refund Transactions Not Initiate Yet"
            else:
                status=""
                transactionId=""
                bankRefNo=""
                refundMassage=""
                errorCode=""
                status=payin_transactions.refundResponse.get('status')
                transactionId= payin_transactions.refundResponse.get('mihpayid')
                bankRefNo= payin_transactions.refundResponse.get('bankRefNo')
                response_data = payin_transactions.refundResponse.get('responseData', {})
                refundMassage=response_data.get('msg')
                errorCode=response_data.get('error_code')

                responseDict={
                    "status":status,
                    "transactionId":transactionId,
                    "bankRefNo":bankRefNo,
                    "refundMassage":refundMassage,
                    "errorCode":errorCode,
                }
                data_status["responseStatus"]=1
                data_status["result"]="Refund Transactions fetch Successfully"
                data_status["responseDict"]=responseDict
        else:
            data_status["responseStatus"]=0
            data_status["result"]="Refund Status Not Found"
        return data_status
    except Exception as e:
        data_status["responseStatus"]=0
        data_status["result"]="Unable To Get Refund Status"
        return data_status


@admin_reports.route("/bbps_payment_status_check_admin", methods=["POST"])
@adminid_access_token_required
@csrf.exempt
def bbps_payment_status_check_admin():
    data_status = {"responseStatus":0,"result":""}
    id = request.form.get("id","")
    print(id,"id")
    responseDict = {}
    payinPaymentstatusResponseDict = {}
    try:
        if not session.get("adminId"):
            return redirect("admin_login")

        if not id:
            data_status["result"]="Required fields are missing!!"
            return data_status
        
        bbps_transactions_queryset =Transactions.objects(id=id).first()
        if not bbps_transactions_queryset:
            data_status["result"]="Invalid Order Id!!"
            return data_status

   
        pgOrderId = str(bbps_transactions_queryset.pgOrderId)
        payInPaymentGatewayId = str(bbps_transactions_queryset.transactionAPIId.id)
        payin_gate_way_queryset = TransactionAPI.objects(id=str(payInPaymentGatewayId)).first()
        if not payin_gate_way_queryset:
            data_status["result"]="Invalid request found!!"
            return data_status
        paymentGateWayCode = payin_gate_way_queryset.code
        paramsList = payin_gate_way_queryset.paramsList
        txnDate = payin_gate_way_queryset.createdOn.strftime("%d-%m-%Y")

        ############################################## Slab Calculation for Payin #########################################################################
        # payment_mode_queryset = PaymentMode.objects(paymentMode="UPI").first()
        # paymentModeId = str(payment_mode_queryset.id)
        # sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType="UPI").first()
        # subPaymentModeId = str(sub_payment_mode_queryset.id)
        patternId = str(bbps_transactions_queryset.userId.patternId.id)

        ###################################################################################################################################################
        
        if paymentGateWayCode == "AccurePay_PayIn":
            get_api_key = ""
            get_salt = ""
            get_base_url=''
            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                if get_key == "api_key":
                    get_api_key = each_key.get("value")
                    
                if get_key == "salt":
                    get_salt = each_key.get("value")

                if get_key == "base_url":
                    get_base_url = each_key.get("value")
            
            ######################################################### Check Accurepay Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_accurepay_payin_paymentstatus(get_api_key,get_salt,get_base_url,pgOrderId)
            ########################################################################################################################################################

        elif paymentGateWayCode == "WowPe_Payin":
            get_api_key = ""
            get_secret_key = ""
            get_base_url=''
            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                if get_key == "api_key":
                    get_api_key = each_key.get("value")
                    
                if get_key == "secret_key":
                    get_secret_key = each_key.get("value")

                if get_key == "base_url":
                    get_base_url = each_key.get("value")


            ######################################################### Check Wowpe Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_wowpe_payin_paymentstatus(get_api_key,get_secret_key,get_base_url,pgOrderId)
            ########################################################################################################################################################

        elif paymentGateWayCode == "Fstac_Payin":
            get_api_key = ""
            get_secret_key = ""
            get_base_url=''
            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                if get_key == "api_key":
                    get_api_key = each_key.get("value")
                    
                if get_key == "secret_key":
                    get_secret_key = each_key.get("value")

                if get_key == "base_url":
                    get_base_url = each_key.get("value")


            ######################################################### Check Fstac Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_fstac_payin_paymentstatus(get_api_key,get_secret_key,get_base_url,pgOrderId)
            ########################################################################################################################################################

        elif paymentGateWayCode == "Payu_Payin":
            get_api_key = ""
            get_secret_key = ""
            get_base_url = ""
            get_client = ""
            get_salt = ""

            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                if get_key == "api_key":
                    get_api_key = each_key.get("value")
                    
                if get_key == "secret_key":
                    get_secret_key = each_key.get("value")

                if get_key == "base_url":
                    get_base_url = each_key.get("value")

                if get_key == "client_id":
                    get_client = each_key.get("value")

                if get_key == "salt":
                    get_salt = each_key.get("value")


            print(get_api_key,"get_api_key1")
            print(get_secret_key,"get_secret_key1")
            print(get_base_url,"get_base_url1")
            print(get_client,"get_client1")
            print(get_salt,"get_salt1")
            ######################################################### Check PayU Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_payu_payin_paymentstatus(get_api_key,get_salt,get_base_url,pgOrderId)
            ########################################################################################################################################################
        elif paymentGateWayCode == "Lyra_Payin":
            user_name = ""
            get_base_url = ""
            password = ""

            for each_key in paramsList:
                
                get_key = each_key.get("key")
                
                get_key = each_key.get("key")
                if get_key == "base_url":
                    get_base_url = each_key.get("value")
                if get_key == "user_name":
                    user_name = each_key.get("value")
                if get_key == "password":
                    password = each_key.get("value")
            ######################################################### Check Lyra Payin Payment Status #############################################################
            payinPaymentstatusResponseDict = check_lyra_payin_paymentstatus(get_base_url,str(bbps_transactions_queryset.transactionId),user_name,password)
            print(payinPaymentstatusResponseDict,"(((((((((payinPaymentstatusResponseDict)))))))))")
            ########################################################################################################################################################

        elif paymentGateWayCode == "Getepay_Payin":
            mid = ""
            get_base_url = ""
            callback_url = ""
            return_url=""
            encryption_key = ""
            encryption_iv = ""
            terminalId = ""
            vpa = ""
            for each_key in paramsList:
                get_key = each_key.get("key")
                if get_key == "mid":
                    mid = each_key.get("value")
                if get_key == "get_base_url":
                    get_base_url = each_key.get("value")
                if get_key == "callback_url":
                    callback_url = each_key.get("value")
                if get_key == "return_url":
                    return_url = each_key.get("value")
                if get_key == "encryption_key":
                    encryption_key = each_key.get("value")
                if get_key == "encryption_iv":
                    encryption_iv = each_key.get("value")
                if get_key == "terminalId":
                    terminalId = each_key.get("value")
                if get_key == "vpa":
                    vpa = each_key.get("value")
           
            print(mid, str(bbps_transactions_queryset.transactionId), terminalId,"((((((((((((((((((((((KEYS FOR GETEPAY))))))))))))))))))))))")
            # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+"TPSL"+str(orderId)
            # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+str(orderId)
            transactionType="single"
            ###################################################################### Get Payin Code ############################################################################
            payinPaymentstatusResponseDict = getepay_status_check(mid, str(bbps_transactions_queryset.statusCheckId), terminalId, encryption_key, encryption_iv, get_base_url)
            ##################################################################################################################################################################
            print(payinPaymentstatusResponseDict,"((((((((((((((((((payinPaymentstatusResponseDict in get epayin))))))))))))))))))")
        elif paymentGateWayCode == "Worldline_Payin":
            get_base_url = ""
            callback_url = ""
            api_key = ""
            secret_key = ""
            merchantIdentifier = ""
            api_encryption_key = ""
            requestType = ""
            transactionType = ""
            encryption_iv = ""
            graampay_check = ""
            for each_key in paramsList:
                get_key = each_key.get("key")
                get_key = each_key.get("key")
                if get_key == "get_base_url":
                    get_base_url = each_key.get("value")
                if get_key == "merchantIdentifier":
                    merchantIdentifier = each_key.get("value")
                if get_key == "callback_url":
                    callback_url = each_key.get("value")
                if get_key == "encryption_key":
                    api_encryption_key = each_key.get("value")
                if get_key == "encryption_iv":
                    encryption_iv = each_key.get("value")
                if get_key == "transactionType":
                    transactionType = each_key.get("value")
                if get_key == "requestType":
                    requestType = each_key.get("value")
        
            print(mid, str(bbps_transactions_queryset.transactionId),"((((((((((((((((((((((KEYS FOR world))))))))))))))))))))))")
            # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+"TPSL"+str(orderId)
            # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+str(orderId)
            ###################################################################### Get Payin Code ############################################################################
            payinPaymentstatusResponseDict = worldline_status_check(bbps_transactions_queryset.statusCheckId, txnDate, merchantIdentifier, api_encryption_key, encryption_iv, get_base_url)
            ##################################################################################################################################################################
            print(payinPaymentstatusResponseDict,"((((((((((((((((((payinPaymentstatusResponseDict in get epayin))))))))))))))))))")

        else:
            data_status["result"]="Please contact to admin to enable payin option!!"
            return data_status
        if payinPaymentstatusResponseDict.get("responseStatus") == 1:
            if payinPaymentstatusResponseDict.get("bankRefNo"):
                bank_reference_number = payinPaymentstatusResponseDict.get("bankRefNo")
            else:
                bank_reference_number = bbps_transactions_queryset.bankRefId


            transactionstatus = payinPaymentstatusResponseDict.get("paymentStatus","")
            paymentMode=payinPaymentstatusResponseDict.get('payment_mode',"")
            transactionData = payinPaymentstatusResponseDict.get("transactionData")
            customerVpa = str(payinPaymentstatusResponseDict.get('customerVpa'))
            currency=str(payinPaymentstatusResponseDict.get('currency'))
            cardmasked=str(payinPaymentstatusResponseDict.get('cardmasked'))

            order_queryset =Transactions.objects(pgOrderId=pgOrderId).first()
            
            paymentStatus=order_queryset.paymentStatus
            bbpsPaymentStatus=order_queryset.bbpsPaymentStatus
            refundStatus=order_queryset.refundStatus
            status=order_queryset.status
            if transactionstatus==1:
                if order_queryset.bbpsPaymentStatus==1:
                    paymentStatus=1,
                else:
                    bbpsPaymentStatus=0
            else:
                paymentStatus=0
                bbpsPaymentStatus=0
                refundStatus=0
                status=0

            order_queryset.update(
                checkPaymentRespons=payinPaymentstatusResponseDict,
                bbpsPaymentStatus=bbpsPaymentStatus,
                paymentStatus=paymentStatus,
                refundStatus=refundStatus,
                status=status
            )
            responseDict={
            'message':payinPaymentstatusResponseDict.get("message"),
            'payment_mode':payinPaymentstatusResponseDict.get("payment_mode"),
            'response_code':payinPaymentstatusResponseDict.get("response_code"),
            'transaction_id':bbps_transactions_queryset.transactionId,
            "bank_reference_number":bank_reference_number,
            "status":payinPaymentstatusResponseDict.get("status")
            }
            data_status["responseStatus"]=1
            data_status['result']=responseDict
            print(data_status,"-------a------")
            return data_status
        else:
            responseDict={
            "status":"failed",
            "message":payinPaymentstatusResponseDict.get("message")
            }
            
            data_status["result"]=responseDict
            print(data_status,"-----b--------")
            return data_status

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get payin payment status data!!"
        print(data_status,"-------c------")
        return data_status



@admin_reports.route('/adminhtmltopdfconvert',methods=['POST','GET'])
def adminhtmltopdfconvert():
    print("adminhtmltopdfconvert")
    data_status={'count':0,"result":""}
    try:
        #payuinvoices ##"test14.csv"
        fileName=request.args.get('fileName')
        outputFile=request.args.get('outputFile')
        temp_csv_file_name = os.path.join(app.config['SITE_ROOT'], 'media','courses',fileName)
        data_status={"responseStatus":0,"result":""}
        app.logger.info(f"Processing CSV file: {temp_csv_file_name}")
        request_count = 0 
        # return data_status
        count=1
        with open(temp_csv_file_name, mode='r', encoding='utf-8') as csvfile:
            csvreader = csv.DictReader(csvfile)
            for row in csvreader:
                print(f"Processing row123: {row}") 
                CustomerName = row.get("CustomerName", "").strip()
                Email = row.get("Email", "").strip()
                invoiceId = row.get("InvoiceId", "").strip()
                TransectionId = row.get("TransectionId", "").strip()
                Amount = row.get("Amount", "").strip()
                # Corrected 'Item' in invoice table to use 'courseName'
                # courseName = row.get("courseName", "Online Course: Generic").strip() # Default if empty
                # Using datetime.date.today() as fallback for missing dates
                InvoiceDate = row.get("TransactionDate", datetime.date.today().strftime("%B %d, %Y")).strip()
                TransactionDate = row.get("TransactionDate", datetime.date.today().strftime("%B %d, %Y")).strip()
                print(TransectionId,"TransectionId")
                productName="Online course"
                if TransectionId:
                    print(TransectionId,"TransectionId")
                    if float(Amount) <=5000:
                        productName="Advanced PHP knowledge with JS to make smart web application course"
                    elif float(Amount)>5000 and float(Amount)<=10000:
                        productName="Learn Figma – UI/UX Design Essential Training"
                    elif float(Amount)>10000 and float(Amount)<=15000:
                        productName="The Complete 2024 Web Development Bootcamp"
                    elif float(Amount)>15000 and float(Amount)<=20000:
                        productName="Node JS FullStack"
                    elif float(Amount)>20000 and float(Amount)<=25000:
                        productName="Oracle/PostgreSql"
                    elif float(Amount)>25000 and float(Amount)<=30000:
                        productName="The Comprehensive Android App Development Masterclass"
                    elif float(Amount)>30000 and float(Amount)<=35000:
                        productName="Angular – The Complete Guide (2024 Edition)"
                    elif float(Amount)>35000 and float(Amount)<=40000:
                        productName="Complete Python Bootcamp From Zero to Hero in Python (2023 Edition)"
                    elif float(Amount)>40000:
                        productName="Salesforce Technical Architect"
                    returnresponse = generate_sample_pdf(CustomerName,Email,TransectionId,Amount,invoiceId,InvoiceDate,TransactionDate,productName,outputFile)
                    count=count+1;
        data_status['count']=count
        data_status['result']="success"
    except Exception as e:
        print(traceback.format_exc(),"exception error1")
    return data_status


def generate_sample_pdf(CustomerName,Email,TransectionId,Amount,invoiceId,InvoiceDate,TransactionDate,productName,outputFile):
    result = {"status":False, "msg":"Unable to generate the invoice!!"}
    try:
        invoiceId=invoiceId[-5:]
        template_content = render_template('sendmailtemplates/email_invoice_template.html',invoiceId=invoiceId,invoiceDate=InvoiceDate,transectionId=TransectionId,transactionDate=TransactionDate,customerName=CustomerName,customerEmail=Email,amount=Amount,productName=productName)
        # print(template_content,"html_content")
        html_content=""
        html_content += f"""
        <div style="font-family:Arial, Helvetica, sans-serif">
            {template_content}
        </div>
        """

        # print(html_content,"html_content2")
        media_dir = os.path.join(app.config['SITE_ROOT'], "media")
        signature_dir = os.path.join(media_dir, "invoice_template")
        os.makedirs(signature_dir, exist_ok=True)
        outputfilename=str(TransectionId)+".pdf"
        pdf_file_path = os.path.join(signature_dir,outputFile, outputfilename)
 
        with open(pdf_file_path, "w+b") as pdf_file:
            pisa_status = pisa.CreatePDF(html_content, dest=pdf_file)
 
        if pisa_status.err:
            print("Error in PDF generation")
            return result
        else:
            print("PDF generated successfully")
 
        print("saved file path:", pdf_file_path)
 
        # Send the generated PDF file directly to the user
        return send_file(pdf_file_path, as_attachment=True, download_name=outputfilename, mimetype="application/pdf")
    except Exception as e:
        print(traceback.format_exc(),"exception error1")
        return result