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.v1.controllers.payout_apis import *



admin_reports = Blueprint("admin_reports",__name__)


@admin_reports.route("/settlement_ledger_reports",methods=["POST","GET"])
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"])
def payout_ledger_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")
            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","")

            # 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)

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

            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 transactionUniqueId:
                fund_transfer_queryset = fund_transfer_queryset.filter(transactionUniqueId=transactionUniqueId)

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

            if pgId:
                fund_transfer_queryset = fund_transfer_queryset.filter(transactionAPIId__in=[pgId])

            if searchId:
                fund_transfer_queryset = fund_transfer_queryset.filter(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId))

            # 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_ledger_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                pagination=pagination,
                payoutsList=payoutsList,
                transactionUniqueId=transactionUniqueId,
                merchantsList=merchantsList,
                merchantId=merchantId,
                orderId=orderId,
                pgId=pgId,
                pgList=pgList,
                searchId=searchId
                )
        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,
                pagination=pagination,
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                payoutsList=payoutsList,
                transactionUniqueId=transactionUniqueId,
                merchantsList=merchantsList,
                merchantId=merchantId,
                orderId=orderId,
                pgList=pgList,
                pgId=pgId,
                searchId=searchId
                )
    else:
        flash("Staff member does not have given view payout ledger reports permissions!!")
        return render_template("super_admin_templates/payout_ledger_reports_list.html")



@admin_reports.route("/payin_ledger_reports",methods=["POST","GET"])
def payin_ledger_reports():
    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 = []

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

            # Set default date format
            date_format = "%d-%m-%Y"
            pagination = None
            pgList = []
            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)

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

            payin_ledger_reports = WalletTransactions.objects(status__in=[1,2,4,5],createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()

            if orderId:
                payin_ledger_reports = payin_ledger_reports.filter(orderId=orderId)

            if pgOrderId:
                payin_ledger_reports = payin_ledger_reports.filter(pgOrderId=pgOrderId)

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

            if pgId:
                payin_ledger_reports = payin_ledger_reports.filter(paymentGatewayId__in=[pgId])

            if searchId:
                payin_ledger_reports = payin_ledger_reports.filter(Q(orderId__icontains=searchId) | Q(pgOrderId__icontains=searchId))
            


            # 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 = payin_ledger_reports.count()

            start = (page - 1) * per_page

            end = min(start + per_page, total_count)

            total_payins= payin_ledger_reports[start:end]
            
            snoCount = start
            for each_payin in total_payins:
                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")

            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,
                orderId=orderId
                )
        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,
                orderId=orderId,
                pgId=pgId,
                pgList=pgList,
                searchId=searchId
                )
    else:
        flash("Staff member does not have given view payin ledger reports permissions!!")
        return render_template("super_admin_templates/payin_ledger_reports_list.html")


@admin_reports.route("/auto_collect_ledger_reports",methods=["POST","GET"])
def auto_collect_ledger_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    permissionsList = check_permissions(session.get("adminId"),"autocollectLedgerReportPermissions")
    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)


            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)

            # 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="auto_collect_ledger")

            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
                )
        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
                )
    else:
        flash("Staff member does not have given view auto collect ledger reports permissions!!")
        return render_template("super_admin_templates/payin_ledger_reports_list.html")


@admin_reports.route("/live_transaction_reports",methods=["POST","GET"])
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"])
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"])
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"])
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"])
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"])
def update_transaction_reports():
    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:
            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
            total_debit_sucess_amount=0.0

            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","")
            status = []
            merchantsList = []
            pgList = []

            # 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)
            
            pg_queryset = TransactionAPI.objects(transactionType="Payout",status__in=[0,1]).order_by("-id")
            for each_pg in pg_queryset:
                pgDict = fetching_transaction_api_details(each_pg)
                pgList.append(pgDict)

            if selectStatus == "All" or selectStatus == "":
                status = [0,1,2,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 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 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])

            if pgId:
                payouts_queryset = payouts_queryset.filter(transactionAPIId__in=[pgId])

            if searchId:
                payouts_queryset = payouts_queryset.filter(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId))


            # 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
            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 each_payout in total_payouts:
                snoCount +=1
                payoutDict = fetching_payouts_details(each_payout)
                payoutDict["snoCount"]=snoCount
                payoutsList.append(payoutDict)
            
            overall_payouts_queryset = FundTransfers.objects()
            overall_credit_amount = round(overall_payouts_queryset.filter(transferType="Credit").sum("amount") or 0.0,2)
            overall_debit_amount = round(overall_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="payouts")
            

            

            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,
                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
                )
        else:
            flash("Staff member does not have given view all transactions permissions!!")
            return render_template("super_admin_templates/update_transaction_reports_list.html")
    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,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            selectStatus=selectStatus,
            merchantName=merchantName,
            merchantRefNo=merchantRefNo,
            merchantsList=merchantsList,
            merchantId=merchantId,
            pgId=pgId,
            orderId=orderId,
            searchId=searchId
            )

@admin_reports.route("/admin_download_all_transactions_csv_reports",methods=["POST","GET"])
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"])
def success_transaction_reports():
    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

            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","")

            # 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)


            payouts_queryset = FundTransfers.objects(createdOn__gte=startDate,createdOn__lte=endDate,status=1).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 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])
            if searchId:
                payouts_queryset = payouts_queryset.filter(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId))


            # 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
            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)
            for each_payout in total_payouts:
                # 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)
            
            # 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")

            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,
                merchantRefNo=merchantRefNo,
                totalCreditAmount=total_credit_amount,
                totalDebitAmount=total_debit_amount,
                refundAmount=refund_amount,
                processingAmount=processing_amount,
                overAllCreditAmount=overall_credit_amount,
                overAllDebitAmount=overall_debit_amount,
                
                )
        else:
            flash("Staff member does not have given view success transactions permissions!!")
            return render_template("super_admin_templates/success_transaction_reports_list.html")
    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,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            merchantName=merchantName,
            orderId=orderId,
            searchId=searchId,
            merchantId=merchantId,
            merchantsList=merchantsList,
            merchantRefNo=merchantRefNo
            )

@admin_reports.route("/admin_download_payout_success_transactions_csv_reports",methods=["POST","GET"])
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"])
def pending_payout_transactions():
    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", "")

            status = []
            pendingPayoutsList = []
            merchantsList = []
            total_pending_amount = 0.0
            overall_credit_amount = 0.0
            overall_debit_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)

            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, 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 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])

            if searchId:
                print(searchId,"((((((((((((((((((searchId)))))))))))))))))))")
                payouts_queryset = payouts_queryset.filter(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId))

            # 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

            total_debit_amount = round(total_payouts.filter(transferType="Debit").sum("amount",) or 0.0,2)
            for each_payout in total_payouts:
                snoCount +=1
                payoutDict = fetching_payouts_details(each_payout)
                payoutDict["snoCount"]=snoCount
                pendingPayoutsList.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/pending_payout_transactions.html",
                                   pagination=pagination,
                                   pendingPayoutsList=pendingPayoutsList,
                                   selectStatus=selectStatus,
                                   orderId=orderId,
                                   searchId=searchId,
                                   merchantId=merchantId,
                                   merchantsList=merchantsList,
                                   startDate=startDate.strftime(date_format),
                                   endDate=endDate.strftime(date_format),
                                   merchantName=merchantName,
                                   totalPendingAmount=total_debit_amount
                                   )
        else:
            flash("Staff member does not have given view pending payout transactions permissions!!")
            return render_template("super_admin_templates/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/pending_payout_transactions.html",
                               error=error,
                               pagination=pagination,
                               pendingPayoutsList=pendingPayoutsList,
                               selectStatus=selectStatus,
                               orderId=orderId,
                               searchId=searchId,
                               merchantId=merchantId,
                               merchantsList=merchantsList,
                               startDate=startDate.strftime(date_format),
                               endDate=endDate.strftime(date_format),
                               merchantName=merchantName)


@admin_reports.route("admin_download_pending_payout_transactions_csv_reports",methods=["POST","GET"])
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("/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"])
def auto_collect_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","")
        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
            )

@admin_reports.route("/search_transaction_reports",methods=["POST","GET"])
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"])
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"])
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("/download_payout_reports",methods=["POST","GET"])
def download_payout_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","")

        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
            )


@admin_reports.route("/payout_download_csv_list",methods=["POST","GET"])
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"])
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"])
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"])
def gst_tds_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        year = request.form.get("year","")
        month = request.form.get("month","")
        merchantMail = request.form.get("merchantMail","")
        startMonthYear = None
        selectYear = None
        selectMonth = None
        endMonthYear=None
        current_year = None
        last_year = None
        pagination = None
        usersList=[]
        userDict={}

        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

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

        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))))))))))")

        userId = request.args.get("userId", "")
        
        user_queryset = Users.objects(status=1).order_by("-id")
        for each_user in user_queryset:
            userDict = fetching_user_details(each_user)
            usersList.append(userDict)

        # users = Users.objects(id__ne=userId,status=1).order_by("-id")
        # for each_user in users:
        #     user = {
        #     'id': str(each_user.id),
        #     'fullName': each_user.fullName,
        #     }
        #     usersList.append(user)

        # 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/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,
            usersList=usersList

            )
    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,
            usersList=usersList
            )

@admin_reports.route("/withdrawal_reports",methods=["POST","GET"])
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"])
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"])
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"])
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"])
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"])
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"])
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"])
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"])
def update_manual_payout_status():
    data_status={'status':0,'result':"failed."}
    status=request.form.get('status')
    orderId=request.form.get('orderId')
    print("orderId=",orderId,"status=",status)
    try:
        if orderId and status:
            fund_transfer_queryset = FundTransfers.objects(merchantReferenceNumber=orderId).first()
            if fund_transfer_queryset:
                user_queryset = Users.objects(id=str(fund_transfer_queryset.userId.id)).first()
                actuallBalance = user_queryset.payoutBalance
                payout_balance_queryset = PayoutBalances.objects(userId=str(fund_transfer_queryset.userId.id),transactionAPIId=str(fund_transfer_queryset.transactionAPIId.id)).first()
                previousBalance=payout_balance_queryset.currentBalance
                transaction_amount = float(fund_transfer_queryset.grandTotal)
                if status == "SUCCESS":
                    updateAmount = float(actuallBalance)-float(transaction_amount)
                    payoutCurrentBalance=float(previousBalance)-float(transaction_amount)
                    if fund_transfer_queryset.status==0:
                        fund_transfer_queryset.update(
                        responseCallBackTime=datetime.datetime.now(),
                        previousBalance=actuallBalance,
                        currentBalance=updateAmount,
                        errorMessage = status,
                        status=1
                        )
                        user_queryset.update(payoutBalance = updateAmount)
                        payout_balance_queryset.update(previousBalance=previousBalance,currentBalance=payoutCurrentBalance,updatedOn=datetime.datetime.now())
                    else:
                        fund_transfer_queryset.update(
                        responseCallBackTime=datetime.datetime.now(),
                        errorMessage = status,
                        status=1
                        )
                elif status == "PROCESSING":
                    updateAmount = float(actuallBalance)-float(transaction_amount)
                    payoutCurrentBalance=float(previousBalance)-float(transaction_amount)
                    if fund_transfer_queryset.status!=0:
                        fund_transfer_queryset.update(
                            responseCallBackTime=datetime.datetime.now(),
                            errorMessage = status,
                            status=2
                            )
                    else:
                        fund_transfer_queryset.update(
                            responseCallBackTime=datetime.datetime.now(),
                            previousBalance=actuallBalance,
                            currentBalance=updateAmount,
                            errorMessage = status,
                            status=2
                            )
                        user_queryset.update(payoutBalance = updateAmount)
                        payout_balance_queryset.update(previousBalance=previousBalance,currentBalance=payoutCurrentBalance,updatedOn=datetime.datetime.now())

                else:
                    updateAmount = float(actuallBalance)+float(transaction_amount)
                    payoutCurrentBalance=float(previousBalance)+float(transaction_amount)
                    if fund_transfer_queryset.status==0:
                        fund_transfer_queryset.update(
                            responseCallBackTime=datetime.datetime.now(),
                            errorMessage = response_json["data"].get("error_message"),
                            status=0
                            )
                    else:
                        fund_transfer_queryset.update(
                            responseCallBackTime=datetime.datetime.now(),
                            previousBalance=actuallBalance,
                            currentBalance=updateAmount,
                            errorMessage = response_json["data"].get("error_message"),
                            status=0
                            )
                        user_queryset.update(payoutBalance = updateAmount)
                        payout_balance_queryset.update(previousBalance=previousBalance,currentBalance=payoutCurrentBalance,updatedOn=datetime.datetime.now())
                data_status['status']=1
                data_status['result']="status successfully updated."
                return data_status
            else:
                data_status['result']="Server Connection Error!."
                return data_status
        else:
            data_status['result']="Server Connection Error!."
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status['result']="Unable to fetched payment buttons data!!"
        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"])
def payin_settlement_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        permissionsList = check_permissions(session.get("adminId"),"payinSettlementPermissions")
        if "view" in permissionsList:
            payinList = []
            merchantsList = []

            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]).order_by("-createdOn")
            for each_merchant in merchants_queryset:
                merchantDict = fetching_user_details(each_merchant)
                merchantsList.append(merchantDict)

            payin_settlement_reports = WalletTransactions.objects(
                createdOn__gte=startDate,createdOn__lte=endDate,userType="admin").order_by("-createdOn")

            if orderId:
                payin_settlement_reports = payin_settlement_reports.filter(orderId=orderId)

            if merchantId:
                payin_settlement_reports = payin_settlement_reports.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 = payin_settlement_reports.count()

            start = (page - 1) * per_page

            end = min(start + per_page, total_count)

            total_payins= payin_settlement_reports[start:end]
            
            snoCount = start
            for each_payin in total_payins:
                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")

            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
                )
        else:
            flash("Staff member does not have given view payin settlement reports permissions!!")
            return render_template("super_admin_templates/payin_settlement_reports_list.html")
    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
            )


@admin_reports.route("/payout_settlement_reports",methods=["POST","GET"])
def payout_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:
            payoutsList = []
            merchantsList = []

            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]).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
                )
        else:
            flash("Staff member does not have given view payout settlement reports permissions!!")
            return render_template("super_admin_templates/payout_settlement_reports_list.html")
    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,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            payoutsList=payoutsList,
            merchantsList=merchantsList,
            merchantId=merchantId,
            orderId=orderId
            )

######################################## 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"])
def admin_overall_balances_reports():
    if not session.get("adminId"):
        return redirect("admin_login")
    permissionsList = check_permissions(session.get("adminId"),"virtualAdminBalancePermissions")
    if "view" in permissionsList:
        try:
            adminId = session.get("adminId")
            adminBalanceLogsList = []

            startDate = request.args.get("startDate","")
            endDate = request.args.get("endDate","")
            walletType = request.args.get("walletType","") # "Credit" or "Debit"
            transferType = request.args.get("transferType","") # "Payin" or "Payout"

            # 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)

            admin_log_balances_queryset = AdminLogBalances.objects(createdOn__gte=startDate,createdOn__lte=endDate).order_by("-createdOn").all()

            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)

            # 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 = admin_log_balances_queryset.count()

            start = (page - 1) * per_page

            end = min(start + per_page, total_count)

            total_admin_balance_logs = admin_log_balances_queryset[start:end]
            
            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 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/admin_overall_balances_reports_list.html",
                startDate=startDate.strftime(date_format),
                endDate=endDate.strftime(date_format),
                pagination=pagination,
                adminBalanceLogsList=adminBalanceLogsList,
                walletType=walletType,
                transferType=transferType
                )
        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
                )
    else:
        flash("Staff member does not have given view admin overall balances reports permissions!!")
        return render_template("super_admin_templates/admin_overall_balances_reports_list.html")


@admin_reports.route("/generate_new_report",methods=["POST","GET"])
def generate_new_report():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        # permissionsList = check_permissions(adminId,"bankPermissions")
        # 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 reportType and walletType and startDate and endDate and userId:
                try:
                    generate_report_table = PayoutDownloadReports(
                        userId=userId,
                        reportType=reportType,
                        dateRange="",
                        walletType=walletType,
                        userType="admin",
                        createdOn=datetime.datetime.now(),
                        status=0
                        )
                    save_table=generate_report_table.save()

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

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

                    flash("Generate new report successfully!")
                    return redirect(url_for("admin_reports.admin_payout_download_reports_list"))
                except Exception as e:
                    flash("Unable to generate new report details!!")
                    app.logger.error(traceback.format_exc())
                    return redirect(url_for("admin_reports.admin_payout_download_reports_list"))
            else:
                flash("Required fields are missing!!")
                return redirect(url_for("admin_reports.admin_payout_download_reports_list"))
        # else:
        #     flash("Staff member does not have given create bank permissions!!")
        #     return redirect(url_for("admin_reports.admin_payout_download_reports_list",redirectTo="masterIfscBank"))
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to generate new report details!!"
        return render_template("super_admin_templates/admin_generated_reports.html",error=error)

@admin_reports.route("/admin_payout_download_reports_list",methods=["POST","GET"])
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"
    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)

        payout_download_reports_queryset = PayoutDownloadReports.objects(userType="admin").order_by("-createdOn").all()
        for each_report in payout_download_reports_queryset:
            downloadReportDict = fetching_payout_download_reports(each_report)
            downloadReportsList.append(downloadReportDict)
        return render_template("super_admin_templates/admin_generated_reports.html",downloadReportsList=downloadReportsList,merchantsList=merchantsList)
    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)

@admin_reports.route("/admin_payout_download_report_status",methods=["POST","GET"])
def admin_payout_download_report_status():
    if not session.get("adminId"):
        return redirect("admin_login")
    # permissionsList = check_permissions(session.get("adminId"),"bankPermissions")
    # if "edit" in permissionsList:
    payoutDownloadReportId = request.args.get("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 status update bank permissions!!")
    #     return redirect(url_for("admin_reports.admin_payout_download_reports_list",redirectTo="masterIfscBank"))

@admin_reports.route("/update_admin_payout_download_report",methods=["POST","GET"])
def update_admin_payout_download_report():
    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:
            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!")
                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())
            flash("Unable to update payout download report data!!")
            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"))



@admin_reports.route("/charge_backs_reports",methods=["POST","GET"])
def charge_backs_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")
        chargeBackList = []
        merchantsList = []

        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"
        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)

        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,
            )
    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
            )
    # else:
    #     flash("Staff member does not have given view payout ledger reports permissions!!")
    #     return render_template("super_admin_templates/charge_backs_reports_list.html")


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}")

@admin_reports.route("/upload_csv_data", methods=["POST", "GET"])
def upload_csv_data():
    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"))

    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)

        # 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!!"
        return render_template("super_admin_templates/charge_backs_reports_list.html", error=error)



@admin_reports.route("/usdt_transactions_reports",methods=["POST","GET"])
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"])
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,
        "charge":"",
        "margin":"",
        "channel":"",
        "requestedDate":"",
        "updatedDate":"",
        }
        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"])
def utility_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:
            utilityList = []

            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]

            transactions_reports_queryset = Transactions.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]

                transactions_reports_queryset = transactions_reports_queryset.filter(userId__in=merchantIds)

            if merchantId:
                transactions_reports_queryset = transactions_reports_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 = transactions_reports_queryset.count()

            start = (page - 1) * per_page

            end = min(start + per_page, total_count)

            total_utility_transactions = transactions_reports_queryset[start:end]
            
            snoCount = start
            for each_utility in total_utility_transactions:
                snoCount +=1
                utilityDict = fetch_transaction_reports_details(each_utility)
                utilityDict["snoCount"]=snoCount
                utilityList.append(utilityDict)

            # 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/utility_transaction_reports_list.html",
                pagination=pagination,
                utilityList=utilityList,
                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/utility_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/utility_transaction_reports_list.html", 
            error=error,
            pagination=pagination,
            utilityList=utilityList,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            selectStatus=selectStatus,
            orderId=orderId,
            merchantId=merchantId,
            merchantsList=merchantsList,
            merchantName=merchantName
            )


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
    

@admin_reports.route("/payin_settlement",methods=["POST","GET"])
def payin_settlement():
    if not session.get("adminId"):
        return redirect("admin_login")
    payinSettlementMerchantsList = []
    error=""
    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
        try:
            if startDate:
                startDate = datetime.datetime.strptime(startDate, date_format).strftime(date_format)
            else:
                startDate =""
            
        except Exception as ve:
            app.logger.error("Date parsing error: %s", ve)
            startDate = ""
        
        print(startDate,"startDate")
        print(endDate,"endDate")

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

        if request.method == "POST":
            action = request.form.get("action", "HI").strip()
            data = request.form.to_dict()
            # Step 1: Handle OTP Generation
            if action == "generate":
                mail_type = data.get("mailType", "").strip()
                print(mail_type,"((((((((((((((((mail_type))))))))))))))))")
                if not mail_type:
                    return jsonify({"responseStatus": 0, "result": "mailType is required!"}), 400


                return jsonify(generate_otp_helper(mail_type))



            # tep 2: Handle OTP Verification
            elif action == "verify":
                otp_check_id = request.form.get("otpCheckId","SAI")
                otp_code = request.form.get("otpCode","K")

                print(otp_check_id,"((((((((OTP CHECK ID????????????))))))))")
                print(otp_code,"((((((((OTP CODE????????????))))))))")

                if not otp_check_id or not otp_code:
                    return jsonify({"responseStatus": 0, "result": "Required fields are missing!"})

                return jsonify(verify_otp_helper(otp_check_id, otp_code))

            # Step 3: Ensure OTP is Verified Before Updating Service Charges
            elif action == "update":
                otp_check_id = request.form.get("otpCheckId", "")
                otp_record = OtpChecks.objects(id=otp_check_id, status=1).first()
                admin_id = request.form.get("adminId", "")

                otpcheck_queryset = OtpChecks.objects(adminId=str(admin_id), 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 startDate=="" or endDate=="" or paymentGatewayId=="":
                print("required error")
                error = "Required Fields are missing."
                return render_template("super_admin_templates/payin_settlement_list.html", 
                    error=error,
                    payinSettlementMerchantsList=payinSettlementMerchantsList,
                    startDate=startDate,
                    total_amount=total_amount,
                    endDate=endDate,
                    paymentGatewayId=ObjectId(paymentGatewayId),
                    paymentgatewayList=paymentgateway_queryset
                    # 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": datetime.datetime.strptime(startDate, date_format),
                        "$lte": datetime.datetime.strptime(endDate, date_format)
                    }
                }},
                {"$unwind": "$userDetails"},
                {"$group": {"_id": {"userId": "$userId"},"totalAmount": {"$sum": "$grandTotal"}}},
                {"$sort": {"totalAmount": -1}}
            ]
            print(pipeline,"*********pipeline*********")
            # Execute the aggregation pipeline
            payins_settlement_merchants = list(WalletTransactions.objects.aggregate(*pipeline))
            print(payins_settlement_merchants,"**********payins_settlement_merchants***********")

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

            print(f"Grand Total amount of unsettled transactions: {total_amount}")

            payinSettlementMerchantsList = []
            totalSettlementAmount = 0
            get_paymentgateway_queryset = TransactionAPI.objects(id=str(paymentGatewayId)).first()
            for each_merchant in payins_settlement_merchants:
                print(each_merchant.get("totalAmount"),"((((((((Total Amount))))))))")
                print(each_merchant.get("_id").get("userId"),"User ID")
                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)

            return render_template("super_admin_templates/payin_settlement_list.html",
                payinSettlementMerchantsList=payinSettlementMerchantsList,
                total_amount=totalSettlementAmount,
                error=error,
                startDate=startDate,
                paymentGatewayId=ObjectId(paymentGatewayId),
                endDate=endDate,
                paymentgatewayList=paymentgateway_queryset
                # 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=total_amount,
            payinSettlementMerchantsList=payinSettlementMerchantsList,
            startDate=startDate,
            endDate=endDate,
            paymentGatewayId=str(paymentGatewayId),
            paymentgatewayList=paymentgateway_queryset
            # yesterday_datetime=yesterday_datetime
            )

@admin_reports.route("/payin_merchant_settlement",methods=["POST","GET"])
def payin_merchant_settlement():
    if not session.get("adminId"):
        return redirect("admin_login")
    date_format = "%d-%m-%Y %H:%M"
    payinSettlementMerchantsList = []

    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
        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 = ""

        print(settlement_startDate,"settlement_startDate")
        print(type(settlement_startDate),"settlement_startDate Type")
        print(settlement_endDate,"settlement_endDate")
        print(payInPaymentGatewayId,"payInPaymentGatewayId")
        print(merchantIdList,"merchantIdList")

        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"))

        for each_merchant in merchantIdList:
            userId=each_merchant
            print(userId,"(((((((((((UserId)))))))))))")
            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)

            print(payins_settlement_merchant,"(((((((((((((((((PAYIN settlement)))))))))))))))))")
            grandtotal=0
            if payins_settlement_merchant:
                grandtotal=payins_settlement_merchant.sum('grandTotal')
                print(grandtotal,"((((((((((((Grand Total))))))))))))")
            if float(grandtotal)<=0:
                print("Merchant PAYOUT PG !!!!")
                continue
            merchant_queryset = Users.objects(id=userId,status=1).first()
            print(str(merchant_queryset.id),"MERCHANT QUERYSET")
            if not merchant_queryset.patternId.payoutPaymentGatewayId:
                print("Merchant PAYOUT PG")
                continue
            print(grandtotal,"((((((((grandtotal))))))))")
            amount = round(float(grandtotal),2)
            patternId = str(merchant_queryset.patternId.id)
            payOutPaymentGatewayId = str(merchant_queryset.patternId.payoutPaymentGatewayId.id)

            print(amount,"((((((((amount))))))))")
            print(patternId,"((((((((PATTERN ID))))))))")

            print(payOutPaymentGatewayId,"((((((((payOutPaymentGatewayId ID))))))))")

            check_wallet_balance = round(float(merchant_queryset.walletBalance),2)
            print(check_wallet_balance,"((((((((((((check_wallet_balance))))))))))))")
            print(amount,"((((((((((((amount check_wallet_balance))))))))))))")

            if check_wallet_balance < amount:
                continue

            # Settlement Functionality For Payin
            balanceResult=user_payin_balance_update(userId,amount,"Debit",payInPaymentGatewayId)
            print(balanceResult.get('responseStatus'),"(((((((((((balanceResult.get('responseStatus'))))))))))))")
            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()
                print(get_paymentgateway_queryset,"((((((((((((((#####################))))))))))))))")
                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
                print(sendermailsList,"(((((((((((sendermailsList)))))))))))")
                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")
 
                # 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 = "",
                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 = "",
                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!!")
        return redirect(url_for("admin_reports.payin_settlement"))
       
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to settlement merchant!!"
        return render_template("super_admin_templates/payin_settlement_list.html", 
            error=error,
            payinSettlementMerchantsList=payinSettlementMerchantsList
            )



@admin_reports.route("/commission_reports_list",methods=["POST","GET"])
def commission_reports_list():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        permissionsList = check_permissions(session.get("adminId"),"commissionReportsPermissions")
        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).order_by("-createdOn").all()

            # 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_reports_list.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_reports_list.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_reports_list.html", 
            error=error,
            pagination=pagination,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            commissionsList=commissionsList,
            merchantsList=merchantsList,
            merchantId=merchantId
            )


@admin_reports.route("/admin_download_payin_settlement_csv_reports",methods=["POST","GET"])
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)
       
        payins_queryset = WalletTransactions.objects(
                createdOn__gte=startDate,createdOn__lte=endDate,userType="admin").order_by("-createdOn")
        if orderId:
            payins_queryset = payins_queryset.filter(orderId=orderId)

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

        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"])
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"

        permissionsList = check_permissions(session.get("adminId"),"payoutSettlementPermissions")
        if "view" in permissionsList:
            commissionsList = []
            merchantsList = []
            pagination = None
            startMonthYear = None
            selectYear = None
            selectMonth = None
            current_year = None
            last_year = None

            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(merchantId,"(((((((((merchantId)))))))))")
            # print(gstValue,"(((((((((gstValue)))))))))")
            # print(type(gstValue),"((((((((( TYpe gstValue)))))))))")
            # print(tdsValue,"(((((((((tdsValue)))))))))")

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

            # 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"},
                        "totalUserParentTdsAmount": {"$sum": "$parrentTdsAmount"}
                    }
                }
            ]


            # 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]

            snoCount = start
            for each_commission in total_commissions:
                # print(each_commission, "(((((((((((each_commission)))))))))))")
                
                netCommissionAmount = float(each_commission.get("totalUserParentCommissionAmount"))
                totalUserParentGstAmount = float(each_commission.get("totalUserParentGstAmount"))
                totalUserParentTdsAmount = float(each_commission.get("totalUserParentTdsAmount"))
                
                # netCommissionAmount = float(totalUserParentGstAmount+totalUserParentTdsAmount+netCommissionAmount)
                # print(netCommissionAmount,"netCommissionAmount")
                # print(gstAmount,"gstAmount")
                # print(tdsAmount,"tdsAmount")
                # print(commissionAmount,"commissionAmount")

                commission_transaction_queryset = UserCommissions.objects(userId=each_commission.get("_id").get("userId")).first()


                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(commission_transaction_queryset.totalAmount,2),
                    "totalUserParentCommissionAmount": round(netCommissionAmount,2),
                    "commissionAmount": round(netCommissionAmount,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,
                )
        else:
            flash("Staff member does not have given view commissions settlement reports permissions!!")
            return render_template("super_admin_templates/commission_settlements_new.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_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
            )


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

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

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

        
        # Get the month number from the month name
        month_number = datetime.datetime.strptime(selectMonth, "%B").month
        print(selectYear,"(((((((selectYear)))))))")
        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)))))))")

        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")

            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")

            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=totalTxnAmount,
                netCommissionAmount=netCommissionAmount,
                gstAmount=gstAmount,
                gstValue=gstValue,
                tdsAmount=tdsAmount,
                tdsValue=tdsValue,
                commissionAmount=commissionAmount,
                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"])
def generate_commissions_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    try:
        redirectTo = request.args.get("redirectTo","GenerateCommission")
        if redirectTo:
            redirectval = redirectTo
        else:
            redirectval = "GenerateCommission"

        pagination = None
        startMonthYear = None
        endMonthYear = None
        selectYear = None
        selectMonth = None
        current_year = None
        last_year = None
        generatedCommissionsList = []

        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")

        # 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 = generated_commissions_queryset.count()

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

        # 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)

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

        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
            )
    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
            )


@admin_reports.route("/update_generated_commission",methods=["POST","GET"])
def update_generated_commission():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    try:
        generatedCommissionId = request.args.get("generatedCommissionId","")
        gstValue = request.form.get("gstValue")
        tdsValue = request.form.get("tdsValue")

        print(generatedCommissionId,"((((((generatedCommissionId))))))")
        print(type(gstValue),"((((((gstValue))))))")
        print(gstValue,"((((((gstValue))))))")
        print(tdsValue,"((((((tdsValue))))))")

        if generatedCommissionId and gstValue and tdsValue:
            generated_commission_queryset = GeneratedCommissions.objects(id=generatedCommissionId,status=1).first()
            if not generated_commission_queryset:
                flash("Invaild Generate Commission Id!!")
                return redirect(url_for("admin_reports.generate_commissions_list"))

            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("Generatee commission updated 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 update generate commission data!!"
        return redirect(url_for("admin_reports.generate_commissions_list"))

@admin_reports.route("/settlement_commissions_list",methods=["POST","GET"])
def settlement_commissions_list():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    try:
        redirectTo = request.args.get("redirectTo","SettlementCommission")
        if redirectTo:
            redirectval = redirectTo
        else:
            redirectval = "SettlementCommission"

        pagination = None
        startMonthYear = None
        endMonthYear = None
        selectYear = None
        selectMonth = None
        current_year = None
        last_year = None
        settlementCommissionsList = []

        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")

        # 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 = settlement_commissions_queryset.count()

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

        # 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")

        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
            )
    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
            )

@admin_reports.route("/merchant_settlement",methods=["POST","GET"])
def merchant_settlement():
    if not session.get("adminId"):
        return redirect("admin_login")
    adminId = session.get("adminId")
    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:
                    userId = str(generated_commission_queryset.userId.id)
                    print(userId,"(((((((((((Merchant Id)))))))))))")
                    netCommissionAmount = float(generated_commission_queryset.netCommissionAmount)
                    user_queryset = Users.objects(id=userId,status=1).first()
                    if user_queryset:
                        updateCommissionBalance = float(user_queryset.commissionBalance) - float(netCommissionAmount)
                        print(updateCommissionBalance,"((((((((updateCommissionBalance))))))))")

                        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=3)

                        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"])
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("/admin_download_payout_settlement_csv_reports", methods=["POST", "GET"])
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)

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

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

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

        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"])
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]

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

        if orderId:
            utility_queryset = utility_queryset.filter(orderId=orderId)

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

        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"])
def payin_balance_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")

        payinsList = []

        selectedDate = request.form.get("payin_selectedDate", "")
        merchantType = request.form.get("payin_merchantType", "")
        merchantId = request.form.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,
        )

@admin_reports.route("/payout_balance_reports", methods=["POST", "GET"])
def payout_balance_reports():
    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)

        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
        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
        )
    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,
        )


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

        payoutsList = []

        startDate = request.args.get("startDate","")
        endDate = request.args.get("endDate","")
        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)
        

        pagination = None

     
        cummulative_reports_queryset = Transactions.objects(createdOn__gte=startDate, createdOn__lte=endDate)

        final_transaction_Data = []
        category_totals = {}

        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)    


        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

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

        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),
        )
    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),
        )


@admin_reports.route("/account_summary_transactions", methods=["POST", "GET"])
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"
            
        permissionsList = check_permissions(session.get("adminId"), "payoutSettlementPermissions")
        if "view" in permissionsList:
            merchantsList = []
            pagination = None

            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])

            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)

                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)

                
                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
                    )
            else:
                flash("Invalid date range provided.")
                return render_template("super_admin_templates/account_summary_transaction_list.html")

        else:
            flash("Staff member does not have the permission to view commissions settlement reports!")
            return render_template("super_admin_templates/account_summary_transaction_list.html")

    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
        )

@admin_reports.route("/payin_transaction_reports",methods=["POST","GET"])
def payin_transaction_reports():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")
        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","")
            status = []
            merchantsList = []
            pgList = []

            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


            # 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)
            
            pg_queryset = TransactionAPI.objects(transactionType="PaymentGateway",status__in=[0,1]).order_by("-id")
            for each_pg in pg_queryset:
                pgDict = fetching_transaction_api_details(each_pg)
                pgList.append(pgDict)

            if selectStatus == "All" or selectStatus == "":
                status = [0,1,2,4,5]
            elif selectStatus == "Success":
                status = [1]
            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 merchantRefNo:
                payin_queryset = payin_queryset.filter(merchantReferenceNumber__icontains=merchantRefNo)

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

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

            if pgId:
                payin_queryset = payin_queryset.filter(paymentGatewayId__in=[pgId])

            if searchId:
                payin_queryset = payin_queryset.filter(Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId))


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

            per_page = 20 

            total_count = payin_queryset.count()

            start = (page - 1) * per_page

            end = min(start + per_page, total_count)

            total_payins = payin_queryset[start:end]
            
            snoCount = start

            total_credit_amount = round_last_digits(total_payins.filter(creditType="Credit", status=1).sum("amount") or 0.0)
            total_debit_amount = round_last_digits(total_payins.filter(creditType="Debit").sum("amount",) or 0.0)
            processing_amount = round_last_digits(total_payins.filter(status=2).sum("amount") or 0.0)
            refund_amount = round_last_digits(total_payins.filter(creditType="Refund",).sum("amount") or 0.0)
            total_success_credit_amount=round_last_digits(total_payins.filter(creditType="Credit",status=1).sum("amount") or 0.0)
            total_failed_amount = round_last_digits(total_payins.filter(status=0).sum("amount") or 0.0)

            total_settled_amount = round_last_digits(payin_queryset.filter(status=1, settlementStatus=2).sum("amount") or 0.0)
            total_unsettled_amount = round_last_digits(payin_queryset.filter(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 total_payins:
                snoCount +=1
                payInDict = fetching_payin_details(each_pay_in)
                payInDict["snoCount"]=snoCount
                payinList.append(payInDict)
            
            overall_payins_queryset = WalletTransactions.objects(status__in=[1,2])
            overall_credit_amount = round(overall_payins_queryset.filter(creditType="Credit").sum("amount") or 0.0,2)
            overall_debit_amount = round(overall_payins_queryset.filter(creditType="Debit").sum("amount") or 0.0,2)


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

            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,
                pgId=pgId,
                pgList=pgList,
                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,
                )
        else:
            flash("Staff member does not have given view all transactions permissions!!")
            return render_template("super_admin_templates/payin_all_transactions.html")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to fetched all transaction reports data!!"
        return render_template("super_admin_templates/payin_all_transactions.html", 
            error=error,
            pagination=pagination,
            payinList=payinList,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
            selectStatus=selectStatus,
            merchantName=merchantName,
            merchantRefNo=merchantRefNo,
            merchantsList=merchantsList,
            merchantId=merchantId,
            pgId=pgId,
            pgList=pgList,
            orderId=orderId
            )
# @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"])
def payin_success_transaction_reports():
    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

            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","")

            # 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)


            payin_queryset = WalletTransactions.objects(createdOn__gte=startDate,createdOn__lte=endDate,status=1).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]

                payin_queryset = payin_queryset.filter(userId__in=merchantIds)

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

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

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

            if searchId:
                payin_queryset = payin_queryset.filter(Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId))


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

            per_page = 20 

            total_count = payin_queryset.count()

            start = (page - 1) * per_page

            end = min(start + per_page, total_count)

            total_payins = payin_queryset[start:end]
            
            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 each_pay_in in total_payins:
                snoCount +=1
                payInDict = fetching_payin_details(each_pay_in)
                payInDict["snoCount"]=snoCount
                payinList.append(payInDict)
            
            overall_payouts_queryset = WalletTransactions.objects()
            overall_credit_amount = round(overall_payouts_queryset.filter(creditType="Credit").sum("amount") or 0.0,2)
            overall_debit_amount = round(overall_payouts_queryset.filter(creditType="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")

            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,
                )
        else:
            flash("Staff member does not have given view success transactions permissions!!")
            return render_template("super_admin_templates/payin_success_transaction_reports_list.html")
    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
            )

@admin_reports.route("/pending_payin_transactions", methods=["POST", "GET"])
def pending_payin_transactions():
    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", "")

            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)

            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, 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(merchantReferenceNumber__icontains=orderId)

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

            if searchId:
                payin_queryset = payin_queryset.filter(Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId))

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

            per_page = 20

            total_count = payin_queryset.count()

            start = (page - 1) * per_page

            end = min(start + per_page, total_count)

            total_payins = payin_queryset[start:end]
            
            snoCount = start

            

            total_pending_amount = round(total_payins.filter(status=0).sum("amount",) or 0.0,2)
            for each_pay_in in total_payins:
                snoCount +=1
                payInDict = fetching_payin_details(each_pay_in)
                payInDict["snoCount"]=snoCount
                pendingPayinList.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="payouts")

            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,
                                   )
        else:
            flash("Staff member does not have given view pending payout transactions permissions!!")
            return render_template("super_admin_templates/pending_payin_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/pending_payin_transactions.html",
                               error=error,
                               pagination=pagination,
                               pendingPayinList=pendingPayoutsList,
                               selectStatus=selectStatus,
                               orderId=orderId,
                               searchId=searchId,
                               merchantId=merchantId,
                               merchantsList=merchantsList,
                               startDate=startDate.strftime(date_format),
                               endDate=endDate.strftime(date_format),
                               merchantName=merchantName)


@admin_reports.route("admin_download_pending_payin_transactions_csv_reports",methods=["POST","GET"])
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"])
def payin_initiated_transactions():
    try:
        if not session.get("adminId"):
            return redirect("admin_login")
        adminId = session.get("adminId")

        permissionsList = check_permissions(session.get("adminId"), "payinInitiatedTransactionsPermissions")
        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", "")

            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)

            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)

            # Set status to 3 for initiated transactions
            status = [3]

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

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

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

            if searchId:
                payin_queryset = payin_queryset.filter(Q(orderId__icontains=searchId) | Q(transactionId__icontains=searchId))

            # 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 = payin_queryset.count()

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

            total_payins = payin_queryset[start:end]
            
            snoCount = start
            for each_pay_in in total_payins:
                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")

            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)
        else:
            flash("Staff member does not have the required permissions to view initiated transactions!!")
            return render_template("super_admin_templates/initiated_transactions.html")
    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)
    

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

        operator_report_data = []

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

        # 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)
        

        pagination = None

     
        operator_income_reports_queryset = Transactions.objects(createdOn__gte=startDate, createdOn__lte=endDate)

        final_transaction_Data = []
        unique_operators = set()

        for transaction in operator_income_reports_queryset:
            
            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

            
            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 = {
                "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": transactions
            }

            # Ensure unique entries for each operator
            if category_dict not in final_transaction_Data:
                final_transaction_Data.append(category_dict) 


        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

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

        

        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),
        )
    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,
            startDate=startDate.strftime(date_format),
            endDate=endDate.strftime(date_format),
        )




@admin_reports.route("/admin_check_payin_status", methods=["POST"])
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

        ############################################## 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)))))))))")
            ########################################################################################################################################################

        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

def fetching_beneficiary_details(each_beneficiary):
    beneficiaryDict = {}
    try:
        beneficiaryDict = {
        "id":str(each_beneficiary.id),
        "userId":str(each_beneficiary.userId.id),
        "merchantName":each_beneficiary.userId.fullName,
        "name":each_beneficiary.name,
        "creditorAccountNumber":each_beneficiary.creditorAccountNumber,
        "transactionReferenceNumber":each_beneficiary.transactionReferenceNumber,
        "creditorName":each_beneficiary.creditorName,
        "ifscCode":each_beneficiary.ifscCode,
        "status":each_beneficiary.status,
        "createdOn":each_beneficiary.createdOn.astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p")
        }
        try:
            if each_beneficiary.bankId:
                beneficiaryDict["bankId"]=str(each_beneficiary.bankId.id)
                beneficiaryDict["bankName"]=each_beneficiary.bankId.bankName
            else:
                beneficiaryDict["bankId"]=""
                beneficiaryDict["bankName"]=""
        except Exception as e:
            beneficiaryDict["bankId"]=""
            beneficiaryDict["bankName"]=""
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return beneficiaryDict

@admin_reports.route("/beneficiary_list",methods=["POST","GET"])
def beneficiary_list():
    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:
            beneficiaryList = []
            
            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","")
            
            merchantsList = []

            # Set default date format
            
            pagination = None

            beneficiaries_queryset = BenificiaryAccounts.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(creditorAccountNumber__icontains=creditorAccountNumber)

            if creditorName:
                beneficiaries_queryset = beneficiaries_queryset.filter(creditorName__icontains=creditorName)
            
            
            if searchId:
                beneficiaries_queryset = beneficiaries_queryset.filter(Q(name__icontains=searchId) | Q(creditorName__icontains=searchId))

            if merchantId:
                beneficiaries_queryset = beneficiaries_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 = 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 total_payouts:
                snoCount +=1
                beneficiaryDict = fetching_beneficiary_details(each_beneficiary)
                beneficiaryDict["snoCount"]=snoCount
                beneficiaryList.append(beneficiaryDict)
            

            # 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")
                 

            return render_template("super_admin_templates/beneficiary_list.html",
                pagination=pagination,
                beneficiaryList=beneficiaryList,
                creditorAccountNumber=creditorAccountNumber, 
                merchantName=merchantName,
                transactionReferenceNumber=transactionReferenceNumber,
                merchantsList=merchantsList,
                searchId=searchId,
                creditorName=creditorName,

                )
        else:
            flash("Staff member does not have given view all transactions permissions!!")
            return render_template("super_admin_templates/beneficiary_list.html")
    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,
            transactionReferenceNumber=transactionReferenceNumber,
            searchId=searchId,
            creditorName=creditorName,
            )

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

def admin_download_payout_excel_transaction_reports_data(startDate, endDate, payouts_queryset):
    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"payout_transactions_{start_date_str}_{end_date_str}.xlsx"

        payout_transaction_data = {
            "User Type": [],
            "PG Name": [],
            "Merchant Name": [],
            "Order ID": [],
            "Txn ID": [],
            "Amount(₹)": [],
            "Grand Total(₹)": [],
            "Type": [],
            "Account Number": [],
            "UTR": [],
            "Charge Amount(₹)": [],
            "GST Amount(₹)": [],
            "TDS Amount(₹)": [],
            "Transaction Date": [],
            "Transaction Status": []
        }
        for each_record in payouts_queryset:
            payout_transaction_data["User Type"].append(each_record.userType)
            payout_transaction_data["PG Name"].append(each_record.transactionAPIId.apiName)
            payout_transaction_data["Merchant Name"].append(each_record.userId.fullName)
            payout_transaction_data["Order ID"].append(each_record.merchantReferenceNumber)
            payout_transaction_data["Txn ID"].append(each_record.transactionUniqueId)
            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"])
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","")
    merchantId = request.args.get("merchantId","")
    pgId = request.args.get("pgId","")

    try:
        status = []
        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])

        if pgId:
            payouts_queryset = payouts_queryset.filter(transactionAPIId__in=[pgId])

        reportData = admin_download_payout_excel_transaction_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 transaction report data!!"
        return data_status

@admin_reports.route("/admin_download_payin_ledger_xlsx_reports",methods=["POST","GET"])
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","")
    orderId = request.args.get("orderId","")
    merchantId = request.args.get("merchantId","")
    pgId = request.args.get("pgId","")

    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()

        if orderId:
            payin_ledger_reports = payin_ledger_reports.filter(orderId=orderId)

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

        if pgId:
            payin_ledger_reports = payin_ledger_reports.filter(paymentGatewayId__in=[pgId])

        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 = {
            "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)

            # 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"])
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","")

        # 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)

        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 transactionUniqueId:
            fund_transfer_queryset = fund_transfer_queryset.filter(transactionUniqueId=transactionUniqueId)

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

        if pgId:
            fund_transfer_queryset = fund_transfer_queryset.filter(transactionAPIId__in=[pgId])

        if searchId:
            fund_transfer_queryset = fund_transfer_queryset.filter(Q(merchantReferenceNumber__icontains=searchId) | Q(transactionUniqueId__icontains=searchId))

        reportData = admin_download_payout_ledger_xlsx_reports_data(startDate,endDate,fund_transfer_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

def admin_download_payout_ledger_xlsx_reports_data(startDate, endDate, fund_transfer_queryset):
    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"payout_{start_date_str}_{end_date_str}.xlsx"

        payout_ledger_data = {
            "User Type": [],
            "PG Name": [],
            "Order ID": [],
            "Txn ID": [],
            "Merchant Name": [],
            "Opening Balance(₹)": [],
            "CrDrType": [],
            "Credit Amount(₹)": [],
            "Debit Amount(₹)": [],
            "Closing Balance(₹)": [],
            "Amount(₹)": [],
            "Charge Amount(₹)": [],
            "GST Amount(₹)": [],
            "TDS Amount(₹)": [],
            "Transaction Date": [],
            "Transaction Status": []
        }
        
        for each_record in fund_transfer_queryset:
            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["Merchant Name"].append(each_record.userId.fullName)
            payout_ledger_data["Opening Balance(₹)"].append(each_record.previousBalance)
            payout_ledger_data["CrDrType"].append(each_record.transferType)
            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["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"])
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","")
    orderId = request.args.get("orderId","")
    merchantId = request.args.get("merchantId","")
    pgId = request.args.get("pgId","")

    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]

        payin_transaction_reports = WalletTransactions.objects(
            status__in=[0, 1, 2, 4, 5],createdOn__gte=startDate,createdOn__lte=endDate
            ).order_by("-createdOn")

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

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

        if pgId:
            payin_transaction_reports = payin_transaction_reports.filter(paymentGatewayId__in=[pgId])

        reportData = admin_download_payin_transactions_excel_reports_data(startDate,endDate,payin_transaction_reports)
        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):
    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 = {
            "User Type": [],
            "PG Name": [],
            "Order ID": [],
            "Txn ID": [],
            "Merchant Name": [],
            "Opening Balance(₹)": [],
            "CrDrType": [],
            "Credit Amount(₹)": [],
            "Debit Amount(₹)": [],
            "Closing Balance(₹)": [],
            "Amount(₹)": [],
            "Charge Amount(₹)": [],
            "GST Amount(₹)": [],
            "TDS Amount(₹)": [],
            "Transaction Date": [],
            "Status": []
        }
        for each_record in payin_transaction_reports:
            payin_transactions_data["User Type"].append(each_record.userType)
            payin_transactions_data["PG Name"].append(each_record.paymentGatewayId.apiName)
            payin_transactions_data["Order ID"].append(each_record.orderId)
            payin_transactions_data["Txn ID"].append(each_record.pgOrderId)
            payin_transactions_data["Merchant Name"].append(each_record.userId.fullName)
            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["GST Amount(₹)"].append(0.00)
                payin_transactions_data["TDS Amount(₹)"].append(0.00)
            else:
                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")

        # 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