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.idfc_payment_gateways import *
from appservices.common.payment_gateways.axis_payment_gateways import *

third_party_apis = Blueprint("third_party_apis",__name__)


@third_party_apis.route("/payoutfundtransfer",methods=["POST"])
def payoutfundtransfer():
    data_status = {"responseStatus":0,"result":""}
    # if SERVER_STATUS == "DOWN":
    #     data_status["result"]= SERVER_MAINTAINCE_MESSAGE
    #     return data_status

    api_key = request.headers.get("Api-Key","")
    encryption_data = request.json.get("encryption_data","")
    iv = request.json.get("iv","")

    responseDict = {}
    paymentgatewayresponseDict = {}

    # secretKey = "f51085df02812201344f6f0cb6959647"
    # encryption_key = bytes(secretKey, 'utf-8')
    # responseEncrypt = encrypt(sample_wowpe_static_data,encryption_key)
    # encryption_data = responseEncrypt.get('encryption_data')
    # iv = responseEncrypt.get('iv')

    # 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

    print(request.headers,"?????????????")

    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]

    payOutPaymentGatewayId = ""
    userId = ""
    bank_reference_number = ""
    requestData = [request.json]

    # Here Create Client Logs Table
    # save_client_table = save_third_party_client_logs_data(userId,"payout","fund_transfer","payoutFunds",None,requestData,client_ip,"api")

    try:
        if api_key and encryption_data and iv:
            merchant_queryset = ThirdPartyMerchants.objects(apiKey=api_key,status=1).first()
            if not merchant_queryset:
                data_status["result"]="Invalid Api Key!!"
                return data_status

            userId = str(merchant_queryset.id)

            if (merchant_queryset.payoutPaymentGatewaysList == []) or (merchant_queryset.enablePayout==False):
                data_status["result"]="Payout option is disabled please contact admin!!"
                return data_status

            # payOutPaymentGatewayId = str(merchant_queryset.payoutPaymentGatewayId.id)


            try:
                secretKey = merchant_queryset.secretKey
                encryption_key = bytes(secretKey, 'utf-8')

                jsonData = decrypt(encryption_data,encryption_key,iv)
                print(jsonData,"jsonData")
                decryptResponse = json.loads(jsonData)
            except Exception as e:
                app.logger.error(traceback.format_exc())
                data_status["result"]="Invalid encryption data!!"
                return data_status

            # save_client_table.update(userId=str(userId),transactionAPIId=ObjectId(payOutPaymentGatewayId))
            
            ################################ Check api keys Code ##############################

            req_api_key = decryptResponse.get("api_key")
            bank_name=decryptResponse.get("bank_name")
            merchant_reference_number=decryptResponse.get("merchant_reference_number")
            bank_branch=decryptResponse.get("bank_branch")
            account_number=decryptResponse.get("account_number")
            ifsc_code=decryptResponse.get("ifsc_code")
            account_name=decryptResponse.get("account_name")
            amount=decryptResponse.get("amount")
            customer_email=decryptResponse.get("customer_email")
            customer_phone=decryptResponse.get("customer_phone")
            transfer_type=decryptResponse.get("transfer_type")
            remark=decryptResponse.get("remark")
            beneCode = decryptResponse.get("beneCode","")
            graampay_check = decryptResponse.get("graampay_check","")
            # benecode = "41732785397908"

            if not req_api_key and not merchant_reference_number and not bank_name and not account_number and not ifsc_code and not account_name and not amount and not customer_email and not customer_phone and not transfer_type and not graampay_check:
                data_status['result']="Required Fields are missing!!"
                return data_status


            payoutPaymentGatewaysList = [str(each_payout_pg.id) for each_payout_pg in merchant_queryset.payoutPaymentGatewaysList]

            payout_gate_way_queryset = TransactionAPI.objects(id__in=payoutPaymentGatewaysList,code=graampay_check,status=1).first()
            if not payout_gate_way_queryset:
                data_status["result"]="Payout option is disabled please contact to admin!!!!"
                return data_status

            paymentGateWayCode = payout_gate_way_queryset.code
            payOutPaymentGatewayId = str(payout_gate_way_queryset.id)
                
            if api_key == req_api_key:
                if decryptResponse.get('merchant_reference_number')=="":
                    data_status['result']="Merchant Reference Number missing"
                    return data_status

                amount = float(decryptResponse.get("amount"))
                
                if amount <= 0:
                    data_status['result']="Transaction amount is insufficient!!"
                    return data_status

                checkorder_queryset = ThirdPartyFundTransfers.objects(merchantReferenceNumber=decryptResponse.get('merchant_reference_number'),userId=str(userId)).first()
                if checkorder_queryset:
                    data_status['result']="Duplicate Merchant Reference Number!!"
                    return data_status

                userbalance_queryset = ThirdPartyMerchants.objects(id=str(userId)).modify(dec__payoutBalance=float(amount),new=True)
                userCurrentBalance = userbalance_queryset.payoutBalance
                userPreviousBalance = float(userCurrentBalance)+float(amount)

                transactionUniqueId = str(random_digit_generate(15))
                clientOrderId=decryptResponse.get("merchant_reference_number")
                fund_transfer_table = ThirdPartyFundTransfers(
                    userId=str(merchant_queryset.id),
                    transactionAPIId=payOutPaymentGatewayId,
                    bankId=None,
                    bankName=decryptResponse.get("bank_name"),
                    merchantReferenceNumber=decryptResponse.get("merchant_reference_number"),
                    pgOrderId=decryptResponse.get("merchant_reference_number"),
                    fundTransferType="instant",
                    accountType="bank",
                    apiType="api",
                    transferType="Debit",
                    bankBranch=decryptResponse.get("bank_branch"),
                    accountNumber=decryptResponse.get("account_number"),
                    accountIFSCCode=decryptResponse.get("ifsc_code"),
                    beneficiaryName=decryptResponse.get("account_name"),
                    uniqueRequestNumber=None,
                    amount=round(float(decryptResponse.get("amount")),2),
                    grandTotal=round(float(amount),2),
                    previousBalance = round(float(userPreviousBalance),2),
                    currentBalance = round(float(userCurrentBalance),2),
                    beneficiaryMail=decryptResponse.get("customer_email"),
                    beneficiaryPhone=decryptResponse.get("customer_phone"),
                    paymentMode=decryptResponse.get("transfer_type"),
                    narration=decryptResponse.get("remark"),
                    createdOn=datetime.datetime.now(),
                    userType="user",
                    status=2,
                    clientIp=client_ip,
                    statusCheckId=clientOrderId,
                    transactionUniqueId = transactionUniqueId
                    )
                save_table = fund_transfer_table.save()
                instantTransferId = str(save_table.id)
                fund_transfer_queryset = ThirdPartyFundTransfers.objects(id=instantTransferId).first()
                print(paymentGateWayCode,"paymentGateWayCode")
                if paymentGateWayCode == "AccurePay_Payout":
                    get_api_key = ""
                    get_salt = ""
                    for each_key in payout_gate_way_queryset.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")

                    ###################### Accurepay Payout Fundtransfer Functionality Code #####################################
                    paymentgatewayresponseDict = accurepay_payout_fundtransfer(get_api_key,get_salt,get_base_url,None,payOutPaymentGatewayId,client_ip,amount,transfer_type,account_name,account_number,ifsc_code,bank_name,clientOrderId,"api")
                    ##########################################################################################################

                elif paymentGateWayCode == "WowPe_Payout":
                    get_client = ""
                    get_secret = ""
                    get_base_url = ""

                    for each_key in payout_gate_way_queryset.paramsList:
                        get_key = each_key.get("key")        
                        if get_key == "api_key":
                            get_client = each_key.get("value").strip()
                        if get_key == "secret_key":
                            get_secret = each_key.get("value").strip()
                        if get_key == "base_url":
                            get_base_url = each_key.get("value").strip()
                    
                    ########################################################## Wowpe Payout Fundtransfer Functionality Code #######################################################
                    paymentgatewayresponseDict = wowpe_payout_fundtransfer(get_client,get_secret,get_base_url,customer_phone,amount,transfer_type,account_number,ifsc_code,account_name,clientOrderId,None,payOutPaymentGatewayId,client_ip,"api")
                    ################################################################################################################################################################

                elif paymentGateWayCode == "PAYAID_PAYOUT":
                    get_api_key = ""
                    get_salt = ""
                    get_base_url = ""
                    for each_key in payout_gate_way_queryset.paramsList:
                        get_key = each_key.get("key")        
                        if get_key == "api_key":
                            get_api_key = each_key.get("value").strip()
                        if get_key == "salt":
                            get_salt = each_key.get("value").strip()
                        if get_key == "base_url":
                            get_base_url = each_key.get("value").strip()
                    
                    ########################################################## PayAid Payout Fundtransfer Functionality Code #######################################################
                    paymentgatewayresponseDict = payaid_payout_fundtransfer(get_api_key,get_salt,get_base_url,clientOrderId,account_name,amount,account_number,ifsc_code,bank_name,transfer_type,bank_branch,payOutPaymentGatewayId,client_ip,None,"api")
                    ################################################################################################################################################################

                elif paymentGateWayCode == "Idfc_Payout":
                    client_id = ""
                    secretKey = ""
                    kid = ""
                    get_base_url = ""
                    aud_url = ""
                    auth_url = ""
                    grant_type = ""
                    scope = ""
                    source = ""
                    client_assertion_type = ""
                    debitAcountNumber = ""
                    remitterName = ""

                    for each_key in payout_gate_way_queryset.paramsList:
                        get_key = each_key.get("key")        
                        if get_key == "client_id":
                            client_id = each_key.get("value").strip()
                        if get_key == "secret_key":
                            secretKey = each_key.get("value").strip()
                        if get_key == "base_url":
                            get_base_url = each_key.get("value").strip()
                        if get_key == "kid":
                            kid = each_key.get("value").strip()
                        if get_key == "aud_url":
                            aud_url = each_key.get("value").strip()
                        if get_key == "auth_url":
                            auth_url = each_key.get("value").strip()
                        if get_key == "scope":
                            scope = each_key.get("value").strip()
                        if get_key == "grant_type":
                            grant_type = each_key.get("value").strip()
                        if get_key == "source":
                            source = each_key.get("value").strip()
                        if get_key == "client_assertion_type":
                            client_assertion_type = each_key.get("value").strip()
                        if get_key == "debit_acount_number":
                            debitAcountNumber = each_key.get("value").strip()
                        if get_key == "remitter_name":
                            remitterName = each_key.get("value").strip()

                    
                    ########################################################## Idfc Payout Fundtransfer Functionality Code #######################################################
                    paymentgatewayresponseDict = idfc_payout_fundtransfer(client_id,secretKey,kid,get_base_url,aud_url,auth_url,grant_type,scope,source,client_assertion_type,debitAcountNumber,remitterName,customer_phone,str(amount),transfer_type,account_number,ifsc_code,account_name,bank_branch,clientOrderId,None,payOutPaymentGatewayId,client_ip,"api",remark,customer_email)
                    ################################################################################################################################################################
                elif paymentGateWayCode == "Axis_Payout":
                    client_id = ""
                    client_secret = ""
                    get_api_key=""
                    channelId=""
                    serviceRequestId=""
                    corpCode=""
                    serviceRequestVersion=""
                    get_base_url=""
                    corp_account_number=""

                    for each_key in payout_gate_way_queryset.paramsList:
                        get_key = each_key.get("key")
                        if get_key=="client_id":
                            client_id=each_key.get("value")
                        if get_key=="client_secret":
                            client_secret=each_key.get("value")
                        if get_key=="encryption_key":
                            get_api_key=each_key.get("value")
                        if get_key=="channel_id":
                            channelId=each_key.get("value")
                        if get_key=="service_request_id":
                            serviceRequestId=each_key.get("value")
                        if get_key=="service_request_version":
                            serviceRequestVersion=each_key.get("value")
                        if get_key=="corp_code":
                            corpCode=each_key.get("value")
                        if get_key=="get_base_url":
                            get_base_url=each_key.get("value")
                        if get_key=="corp_account_number":
                            corp_account_number=each_key.get("value")


                    requestUUID = str(random_digit_generate(15))

                    ########################################################## Axis Payout Fundtransfer Functionality Code #######################################################
                    paymentgatewayresponseDict = axis_payout_fundtransfer(client_id,client_secret,get_api_key,channelId,get_base_url,requestUUID,serviceRequestId,serviceRequestVersion,corpCode,corp_account_number,amount,account_name,userId,ifsc_code,transfer_type,beneCode,clientOrderId,account_number,bank_name)
                    ################################################################################################################################################################
                else:
                    data_status["result"]="Invalid Request!!"
                    return data_status
                    # save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())

                ################################## Common Code For All Payout Payment Gateways ######################################################
                print(paymentgatewayresponseDict,"paymentgatewayresponseDict")
                print(paymentgatewayresponseDict.get("responseStatus"),"responseStatus")
                if paymentgatewayresponseDict.get("responseStatus") == 1:
                    print("hiiii")
                    if paymentgatewayresponseDict.get("bank_reference_number"):
                        bank_reference_number = paymentgatewayresponseDict.get("bank_reference_number")
                    else:
                        bank_reference_number =""
                    transactionData = paymentgatewayresponseDict.get("transactionData")

                    latest_fund_transfer_queryset = ThirdPartyFundTransfers.objects(id=instantTransferId).first()
                    previousstatus=latest_fund_transfer_queryset.status

                    if paymentgatewayresponseDict.get("transactionstatus")==0 or paymentgatewayresponseDict.get("transactionstatus")==4:
                        getrefund_record=ThirdPartyFundTransfers.objects(transactionUniqueId=latest_fund_transfer_queryset.merchantReferenceNumber,userId=str(merchant_queryset.id)).count()
                        if (previousstatus==1 or previousstatus==2) and getrefund_record==0:
                            userbalance_queryset = ThirdPartyMerchants.objects(id=str(userId)).modify(inc__payoutBalance=float(amount),new=True)
                            userCurrentBalance = userbalance_queryset.payoutBalance
                            userPreviousBalance = float(userCurrentBalance)-float(amount)

                            merchantReferenceNumber=random_digit_generate(15)
                            refund_transfer_table = ThirdPartyFundTransfers(
                                userId=str(merchant_queryset.id),
                                transactionAPIId=payOutPaymentGatewayId,
                                bankId=None,
                                bankName=decryptResponse.get("bank_name"),
                                merchantReferenceNumber=merchantReferenceNumber,
                                transactionUniqueId=decryptResponse.get("merchant_reference_number"),
                                pgOrderId='',
                                fundTransferType="instant",
                                accountType="bank",
                                apiType="api",
                                transferType="Refund",
                                bankBranch=decryptResponse.get("bank_branch"),
                                accountNumber=decryptResponse.get("account_number"),
                                accountIFSCCode=decryptResponse.get("ifsc_code"),
                                beneficiaryName=decryptResponse.get("account_name"),
                                bankReferenceNumber=bank_reference_number,
                                uniqueRequestNumber=None,
                                fundTransferId=str(instantTransferId),
                                amount=decryptResponse.get("amount"),
                                grandTotal=round(float(amount),2),
                                previousBalance = round(float(userPreviousBalance),2),
                                currentBalance = round(float(userCurrentBalance),2),
                                beneficiaryMail=decryptResponse.get("customer_email"),
                                beneficiaryPhone=decryptResponse.get("customer_phone"),
                                paymentMode=decryptResponse.get("transfer_type"),
                                narration=decryptResponse.get("remark"),
                                createdOn=datetime.datetime.now(),
                                userType="user",
                                status=5,
                                transactionData=transactionData,
                                transactionDate=paymentgatewayresponseDict.get("transactionDate"),
                                requestData=paymentgatewayresponseDict.get("requestData"),
                                clientIp=client_ip,
                                statusCheckId=latest_fund_transfer_queryset.statusCheckId
                                )
                            save_table = refund_transfer_table.save()


                    latest_fund_transfer_queryset.update(
                        transactionData=transactionData,
                        errorMessage=paymentgatewayresponseDict.get("messages"),
                        transactionUniqueId=paymentgatewayresponseDict.get("transaction_id"),
                        bankReferenceNumber=bank_reference_number,
                        status=paymentgatewayresponseDict.get("transactionstatus"),
                        transactionDate=paymentgatewayresponseDict.get("transactionDate"),
                        requestData=paymentgatewayresponseDict.get("requestData"),
                        )

                    responseDict = {
                    "status":paymentgatewayresponseDict.get("status"),
                    "merchant_reference_number":decryptResponse.get("merchant_reference_number"),
                    "account_name":decryptResponse.get('account_name'),
                    "amount":decryptResponse.get('amount'),
                    "account_number":decryptResponse.get('account_number'),
                    "ifsc_code":decryptResponse.get('ifsc_code'),
                    "bank_name":decryptResponse.get('bank_name'),
                    "bank_reference_number":bank_reference_number,
                    "transfer_type":decryptResponse.get('transfer_type'),
                    "bank_branch":decryptResponse.get('bank_branch'),
                    "customer_email":decryptResponse.get('customer_email'),
                    "customer_phone":decryptResponse.get('customer_phone'),
                    "remark":decryptResponse.get('remark'),
                    "errorMessage":paymentgatewayresponseDict.get("messages"),
                    "transaction_id":paymentgatewayresponseDict.get("transaction_id")
                    }
                    data_status["responseStatus"]=1
                    data_status["result"]="Success"
                    data_status["responseBody"]=responseDict
                    return data_status

                    # For count update number of success in routing switch counts table
                    if routing_switch_counts_queryset:
                        existingSuccessCount = routing_switch_counts_queryset.numberOfSuccess
                        updateSuccessCount = existingSuccessCount+1

                        existingSuccessAmount = float(routing_switch_counts_queryset.maxVolume)
                        updateSuccessAmount = float(existingSuccessAmount)+float(decryptResponse.get('amount'))

                        routing_switch_counts_queryset.update(numberOfSuccess=updateSuccessCount,maxVolume=updateSuccessAmount)
                    else:
                        save_routing_switch_table.update(numberOfSuccess=1,maxVolume=float(decryptResponse.get('amount')))

                    return data_status
                else:
                    data_status["responseStatus"]=paymentgatewayresponseDict.get("responseStatus")
                    data_status["result"]=paymentgatewayresponseDict.get("result")
                    # save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
                    return data_status
            else:
                data_status["result"]="Mis-matched api keys!!"
                # save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
                return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            # save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get payout data!!"
        # save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
        exceptionData = [traceback.format_exc()]
        exception_log_table = save_exception_logs_data(None,"payout","fund_transfer","payoutFunds",exceptionData,client_ip,"api")
        return data_status

@third_party_apis.route("/getpayoutfundtransferstatus",methods=["POST"])
def getpayoutfundtransferstatus():
    print(request.headers,'*****request.headers******')
    data_status = {"responseStatus":0,"result":""}
    # if SERVER_STATUS == "DOWN":
    #     data_status["result"]= SERVER_MAINTAINCE_MESSAGE
    #     return data_status
    api_key = request.headers.get("Api-Key","")
    order_id = request.json.get("order_id","")

    # 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

    print(client_ip,"CLIENT IP")

    try:
        if not order_id and not api_key:
            data_status["result"]="Required fields are missing!!"
            return data_status
        merchant_queryset = ThirdPartyMerchants.objects(apiKey=api_key,status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid Api Key!!"
            return data_status
        userId = str(merchant_queryset.id)
    
        # if client_ip not in api_security_queryset.ipAddressList:
        #     data_status["result"]="Your ip adress is not whitelisted please contact admin!!"
        #     return data_status

        

        get_fundtransfer_status = get_payout_fundtransfer_payment_status(order_id,userId,client_ip)

        print(get_fundtransfer_status,"((((((((((((GET FundTransfer Status))))))))))))")

        data_status["responseStatus"]=1
        data_status["result"]="Success"
        data_status["responseBody"]=get_fundtransfer_status
        return data_status

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get fundtransfer status data!!"
        return data_status

def get_payout_fundtransfer_payment_status(statusCheckId,userId,client_ip):
    responseBody = {}
    paymentgatewayResponseStatusDict = {}
    try:
        fund_transfer_queryset = ThirdPartyFundTransfers.objects(pgOrderId=statusCheckId,userId=str(userId)).first()
        if fund_transfer_queryset:
            if fund_transfer_queryset.csvFileUpload=="manual":
                responseBody = {
                "status":"SUCCESS",
                "merchant_reference_number":"",
                "statusCheckId":statusCheckId,
                "bankReferenceNumber":str(fund_transfer_queryset.bankReferenceNumber),
                "error_message":"Success",
                "transaction_id":str(fund_transfer_queryset.transactionUniqueId)
                }
                return responseBody
            user_queryset = ThirdPartyMerchants.objects(id=str(fund_transfer_queryset.userId.id),status=1).first()
            if not user_queryset:
                responseBody["error"]="Invalid merchant id!!"
                return responseBody
            transaction_amount=0
            apiId = str(fund_transfer_queryset.transactionAPIId.id)
            transaction_amount = float(fund_transfer_queryset.grandTotal)
            if fund_transfer_queryset.statusCount:
                previousStatusCount = fund_transfer_queryset.statusCount
            else:
                previousStatusCount=0

            api_queryset = TransactionAPI.objects(id=apiId).first()

            if fund_transfer_queryset.pgOrderId:
                statusCheckId = fund_transfer_queryset.pgOrderId
            else:
                statusCheckId = fund_transfer_queryset.merchantReferenceNumber

            if api_queryset.code == "AccurePay_Payout":
                get_api_key = ""
                get_salt = ""
                get_base_url = ""

                for each_key in api_queryset.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")

                ##################################### Accurepay Payout Fundtransfer Check Status Code ##############################################
                paymentgatewayResponseStatusDict = accurepay_payout_fundtransfer_status(get_api_key,get_salt,statusCheckId,get_base_url,fund_transfer_queryset)
                ####################################################################################################################################

            elif api_queryset.code == "WowPe_Payout":
                get_api_key = ""
                get_secret = ""
                get_base_url = ""

                for each_key in api_queryset.paramsList:
                    get_key = each_key.get("key")        
                    if get_key == "api_key":
                        get_api_key = each_key.get("value").strip()
                    if get_key == "secret_key":
                        get_secret = each_key.get("value").strip()
                    if get_key == "base_url":
                        get_base_url = each_key.get("value").strip()

                ##################################### Wowpe Payout Fundtransfer Check Status Code ##############################################
                paymentgatewayResponseStatusDict = wowpe_payout_fundtransfer_status(get_api_key,get_secret,get_base_url,statusCheckId,fund_transfer_queryset)
                ################################################################################################################################

            elif api_queryset.code == "PAYAID_PAYOUT":
                get_api_key = ""
                get_salt = ""
                get_base_url = ""

                for each_key in api_queryset.paramsList:
                    get_key = each_key.get("key")        
                    if get_key == "api_key":
                        get_api_key = each_key.get("value").strip()
                    if get_key == "salt":
                        get_salt = each_key.get("value").strip()
                    if get_key == "base_url":
                        get_base_url = each_key.get("value").strip()

                ##################################### PAYAID Payout Fundtransfer Check Status Code ##############################################
                pgCheckStatusResponseDict = payaid_payout_fundtransfer_check_status(get_api_key,statusCheckId,get_salt,get_base_url)
                ################################################################################################################################

            elif api_queryset.code == "Idfc_Payout":
                client_id = ""
                secretKey = ""
                kid = ""
                get_base_url = ""
                aud_url = ""
                auth_url = ""
                grant_type = ""
                scope = ""
                source = ""
                client_assertion_type = ""
                debitAcountNumber = ""
                remitterName = ""

                for each_key in api_queryset.paramsList:
                    get_key = each_key.get("key")        
                    if get_key == "client_id":
                        client_id = each_key.get("value").strip()
                    if get_key == "secret_key":
                        secretKey = each_key.get("value").strip()
                    if get_key == "base_url":
                        get_base_url = each_key.get("value").strip()
                    if get_key == "kid":
                        kid = each_key.get("value").strip()
                    if get_key == "aud_url":
                        aud_url = each_key.get("value").strip()
                    if get_key == "auth_url":
                        auth_url = each_key.get("value").strip()
                    if get_key == "scope":
                        scope = each_key.get("value").strip()
                    if get_key == "grant_type":
                        grant_type = each_key.get("value").strip()
                    if get_key == "source":
                        source = each_key.get("value").strip()
                    if get_key == "client_assertion_type":
                        client_assertion_type = each_key.get("value").strip()
                    if get_key == "debit_acount_number":
                        debitAcountNumber = each_key.get("value").strip()
                    if get_key == "remitter_name":
                        remitterName = each_key.get("value").strip()

                
                ########################################################## Idfc Payout Fundtransfer Functionality Code #######################################################
                paymentgatewayResponseStatusDict = idfc_payout_fundtransfer_status(source,kid,aud_url,auth_url,grant_type,scope,client_id,client_assertion_type,fund_transfer_queryset,secretKey,get_base_url)
                ################################################################################################################################################################
            elif api_queryset.code == "Axis_Payout":
                client_id = ""
                client_secret = ""
                get_api_key=""
                channelId=""
                serviceRequestId=""
                corpCode=""
                serviceRequestVersion=""
                get_base_url=""
                corp_account_number=""

                for each_key in api_queryset.paramsList:
                    get_key = each_key.get("key")
                    if get_key=="client_id":
                        client_id=each_key.get("value")
                    if get_key=="client_secret":
                        client_secret=each_key.get("value")
                    if get_key=="encryption_key":
                        get_api_key=each_key.get("value")
                    if get_key=="channel_id":
                        channelId=each_key.get("value")
                    if get_key=="service_request_id":
                        serviceRequestId=each_key.get("value")
                    if get_key=="service_request_version":
                        serviceRequestVersion=each_key.get("value")
                    if get_key=="corp_code":
                        corpCode=each_key.get("value")
                    if get_key=="get_base_url":
                        get_base_url=each_key.get("value")
                    if get_key=="corp_account_number":
                        corp_account_number=each_key.get("value")

                requestUUID = str(random_digit_generate(15))
                ########################################################## Axis Payout Fundtransfer Status Functionality Code #######################################################
                paymentgatewayResponseStatusDict = axis_payout_fundtransfer_check_status(client_id, client_secret, get_api_key, channelId, get_base_url, requestUUID, serviceRequestId, serviceRequestVersion, corpCode,statusCheckId,fund_transfer_queryset)
                ##################################################################################################
            else:
                responseBody["error"]="Unable to connect to the server!!"
                return responseBody

            if paymentgatewayResponseStatusDict.get("responseStatus") == 2:
                if fund_transfer_queryset.status==1:
                    textStatus="SUCCESS"
                elif fund_transfer_queryset.status==0:
                    textStatus="FAILED"
                elif fund_transfer_queryset.status==4:
                    textStatus="REVERSAL"
                else:
                    textStatus="PROCESSING"

                responseBody = {
                "status":textStatus,
                "merchant_reference_number":"",
                "statusCheckId":statusCheckId,
                "bankReferenceNumber":"",
                "error_message":textStatus,
                "transaction_id":paymentgatewayResponseStatusDict.get("transaction_id")
                }
                return responseBody
            elif paymentgatewayResponseStatusDict.get("responseStatus") == 1:
                if paymentgatewayResponseStatusDict.get("transactionStatus")==0 or paymentgatewayResponseStatusDict.get("transactionStatus")==4:
                    latest_fund_transfer_queryset=ThirdPartyFundTransfers.objects(id=str(fund_transfer_queryset.id)).first()
                    getrefund_record=ThirdPartyFundTransfers.objects(transactionUniqueId=latest_fund_transfer_queryset.merchantReferenceNumber,userId=str(fund_transfer_queryset.userId.id)).count()
                    if (latest_fund_transfer_queryset.status==1 or latest_fund_transfer_queryset.status==2) and getrefund_record==0:

                        userbalance_queryset = ThirdPartyMerchants.objects(id=str(fund_transfer_queryset.userId.id)).modify(inc__payoutBalance=float(transaction_amount),new=True)
                        userCurrentBalance = userbalance_queryset.payoutBalance
                        userPreviousBalance = float(userCurrentBalance)-float(transaction_amount)

                        merchantReferenceNumber=str(random_digit_generate(15))
                            
                        fund_transfer_table = ThirdPartyFundTransfers(
                            userId=str(fund_transfer_queryset.userId.id),
                            transactionAPIId=str(fund_transfer_queryset.transactionAPIId.id),
                            bankId=None,
                            transactionUniqueId=str(fund_transfer_queryset.merchant_reference_number),
                            bankName=str(fund_transfer_queryset.bankName),
                            merchantReferenceNumber=str(merchantReferenceNumber),
                            fundTransferId=str(fund_transfer_queryset.id),
                            pgOrderId='',
                            fundTransferType="instant",
                            accountType="bank",
                            apiType="api",
                            transferType="Refund",
                            bankBranch=str(fund_transfer_queryset.bankBranch),
                            accountNumber=str(fund_transfer_queryset.accountNumber),
                            accountIFSCCode=str(fund_transfer_queryset.accountIFSCCode),
                            beneficiaryName=str(fund_transfer_queryset.beneficiaryName),
                            uniqueRequestNumber=str(fund_transfer_queryset.beneficiaryName),
                            amount=round(float(fund_transfer_queryset.amount),2),
                            grandTotal=round(float(fund_transfer_queryset.grandTotal),2),
                            beneficiaryMail=str(fund_transfer_queryset.beneficiaryMail),
                            beneficiaryPhone=str(fund_transfer_queryset.beneficiaryPhone),
                            paymentMode=str(fund_transfer_queryset.paymentMode),
                            narration=str(fund_transfer_queryset.narration),
                            commissionCharges=fund_transfer_queryset.commissionCharges,
                            transactionData=paymentgatewayResponseStatusDict.get("transactionData"),
                            currentBalance=round(float(userCurrentBalance),2),
                            previousBalance=round(float(userPreviousBalance),2),
                            createdOn=datetime.datetime.now(),
                            statusCount = int(previousStatusCount)+1,
                            errorMessage="Refunded",
                            clientIp=client_ip,
                            statusCheckId=str(fund_transfer_queryset.statusCheckId),
                            status=5
                            )
                        save_table = fund_transfer_table.save()

                updatePreviousStatusCount = int(previousStatusCount)+1
                if fund_transfer_queryset.responseCallBackTime:
                    responseCallBackTime=fund_transfer_queryset.responseCallBackTime
                else:
                    responseCallBackTime=datetime.datetime.now()

                fund_transfer_queryset.update(
                    responseCallBackTime=responseCallBackTime,
                    errorMessage = paymentgatewayResponseStatusDict.get("error_message"),
                    transactionUniqueId=paymentgatewayResponseStatusDict.get("transaction_id"),
                    bankReferenceNumber=paymentgatewayResponseStatusDict.get("bankReferenceNumber"),
                    statusCount = updatePreviousStatusCount,
                    status=paymentgatewayResponseStatusDict.get("transactionStatus")
                    )

                if fund_transfer_queryset.payoutResponseCallBackData == []:
                    fund_transfer_queryset.update(payoutResponseCallBackData=paymentgatewayResponseStatusDict.get("transactionData"))

                responseBody = {
                "status":paymentgatewayResponseStatusDict.get("textStatus"),
                "merchant_reference_number":"",
                "statusCheckId":statusCheckId,
                "bank_reference_number":paymentgatewayResponseStatusDict.get("bankReferenceNumber"),
                "error_message":paymentgatewayResponseStatusDict.get("error_message"),
                "transaction_id":paymentgatewayResponseStatusDict.get("transaction_id")
                }
                return responseBody
            else:
                responseBody["error"]=paymentgatewayResponseStatusDict.get("result")
                return responseBody
        else:
            responseBody["error"]="Invalid merchant reference number!!"
            return responseBody
    except Exception as e:
        app.logger.error(traceback.format_exc())
        responseBody["error"]="Unable to connect to the server!!"
        return responseBody

# @payout_apis.route("/getaxisbanktoken",methods=["POST"])
# def getaxisbanktoken():
#   data_status = {"responseStatus":0,"result":""}
#     print(request.json,"axis payout call back url request.json response result")
#     print(request.form,"axis payout call back url request.form response result")
#     return data_status

# @payout_apis.route("/axisbanktokenvalidation",methods=["POST"])
# def axisbanktokenvalidation():
#   data_status = {"responseStatus":0,"result":""}
#     print(request.json,"axis payout call back url request.json response result")
#     print(request.form,"axis payout call back url request.form response result")
#     return data_status

# sample_axis_beni_crea_static_data = {
#     "api_key":"66c43d14b131cbb3c5aba543-8bf0a73fda352bcc0da5509ae4372bd7",
#     # "merchant_reference_number":str(random_digit_generate(15)),
#     "account_name":"Sai Krishna",
#     # "amount":"204",
#     "account_number":"159502971443",
#     "ifsc_code":"INDB0000226",
#     "bank_name":"Indusind Bank",
#     "bene_code":"Testing1234",
#     # "transfer_type":"NEFT",
#     # "bank_branch":"MADHAPUR",
#     # "customer_email":"sai.kerla@apptrinity.com",
#     # "customer_phone":"9988776655",
#     # "remark":"Testing remark",
# }

sample_axis_beni_crea_static_data = {
    "api_key":"qFhZRXyXf1GV",
    "account_name":"Sai Krishna",
    "account_number":"159502971443",
    "ifsc_code":"INDB0000226",
    "bank_name":"Indusind Bank",
    "bene_code":"Testing1234567890"
}

@third_party_apis.route("/beneficiarycreation",methods=["POST"])
def beneficiarycreation():
    data_status = {"responseStatus":0,"result":""}
    if SERVER_STATUS == "DOWN":
        data_status["result"] = SERVER_MAINTAINCE_MESSAGE
        return data_status
    # merchant_id = request.headers.get("Merchant-Id","")
    api_key = request.headers.get("Api-Key","")
    encryption_data = request.json.get("encryption_data","")
    iv = request.json.get("iv","")


    print(request.json,"((((((((JSON))))))))")
    # secretKey = "8d169331584408076ed69b3c"
    # encryption_key = bytes(secretKey, 'utf-8')
    # responseEncrypt = encrypt(request.json,encryption_key)
    # encryption_data = responseEncrypt.get('encryption_data')
    # iv = responseEncrypt.get('iv')

    print(encryption_data,"(((((((((((encryption DaTA)))))))))))")
    print(iv,"iv DaTA")
    print(api_key,"api_key DaTA")
    responseDict = {}
    paymentgatewayResponseStatusDict = {}

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

    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]

    payOutPaymentGatewayId = ""
    userId=""
    requestData = [{"encryptionData":encryption_data,"iv":iv}]

    # Here Create client Logs Table 
    save_client_table = save_client_logs_data(userId,"payout","beneficiarycreation","beneficiarycreation",None,requestData,client_ip,"api")

    print(client_ip,"CLIENT IP")

    try:
        if not encryption_data and not iv and not api_key:
            data_status["result"] =  "required fields are missing!!!"
            return data_status

        merchant_queryset = ThirdPartyMerchants.objects(apiKey=api_key,status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid Api Key!!"
            return data_status

        userId = str(merchant_queryset.id)

        try:
            secretKey = merchant_queryset.secretKey
            encryption_key = bytes(secretKey,'utf-8')
            # print(encryption_data,"((((((((((((encryption data))))))))))))")
            # print(iv,"((((((((((((iv data))))))))))))")
            jsonData = decrypt(encryption_data,encryption_key,iv)
            print(jsonData,"(((((((((JSON DATA)))))))))")
            decryptResponse = json.loads(jsonData)
            print(decryptResponse,"(((((((((((((decryptResponse)))))))))))))")
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] =  "Invalid encryption data!!"
            return data_status

        payoutPaymentGatewaysList = [str(each_payin_pg.id) for each_payin_pg in merchant_queryset.payoutPaymentGatewaysList]

        graampay_check = decryptResponse.get("graampay_check","")

        payout_gate_way_queryset = TransactionAPI.objects(id__in=payoutPaymentGatewaysList,code=graampay_check,status=1).first()
        if not payout_gate_way_queryset:
            data_status["result"]="Payout option is disabled please contact to admin!!"
            return data_status

        paymentGateWayCode = payout_gate_way_queryset.code
        payOutPaymentGatewayId = str(payout_gate_way_queryset.id)

        save_client_table.update(userId=ObjectId(userId),transactionAPIId=ObjectId(payOutPaymentGatewayId))

        
        errorList =[]
        # mid_extracted = merchantUniqueNumber[1:].lstrip("0")
        # beneficiaryCode = str(mid_extracted) + str(get_epoch_milli_time())
        # beneficiaryCode = str(get_epoch_milli_time())
        req_bank_name=decryptResponse.get("bank_name")
        req_bene_code=decryptResponse.get("bene_code")
        req_account_number = decryptResponse.get("account_number")
        req_ifsc_code = decryptResponse.get("ifsc_code")
        req_account_name = decryptResponse.get("account_name")
        req_customer_email = decryptResponse.get("customer_email","")
        req_customer_phone = decryptResponse.get("customer_phone","")

         ######### check for required fields for each record
        if not (req_account_number and req_ifsc_code and req_account_name and req_bene_code ):
            data_status["result"] = "Required Fields are missing!!!!"
            return data_status
        
        if len(req_account_number) < 11 or len(req_account_number) > 15:
                errorList.append("Invalid length for Account number for ",req_account_number)
            
        if len(req_ifsc_code) != 11:
            errorList.append("Invalid length for IFSC code for ", req_account_number)
        
        if not validate_alphanumeric(req_account_name):
            errorList.append("Special characters not allowed in account name, use only alpha numeric", req_account_number)
        
        if len(errorList) > 0:
            data_status["result"] = "Invalid request"
            data_status["errors"] = errorList
            return data_status
        
        check_beneficiary = ThirdPartyBeneficiaries.objects(beneficiaryId=req_bene_code,userId=str(merchant_queryset.id)).first()
        if check_beneficiary:
            for each_bene in check_beneficiary.beneCodeList:
                if str(each_bene.get("transactionApiId")) == str(payout_gate_way_queryset.id):
                    data_status["result"] = "Beneficiary Code already Registered!!"
                    return data_status
        
        save_api_request_data_table = ApiRequestData(
            userId=str(merchant_queryset.id),
            userOrderId="",
            orderId="",
            requestData=[decryptResponse],
            createdOn=datetime.datetime.now(),
            status=1)

        save_table=save_api_request_data_table.save()

        uuid=random_alphanumeric_generate(20)
        
        if payout_gate_way_queryset:
            if payout_gate_way_queryset.code == "Axis_Payout":
                client_id = ""
                client_secret = ""
                get_api_key=""
                channelId=""
                serviceRequestId=""
                corpCode=""
                serviceRequestVersion=""
                get_base_url=""
                corp_account_number=""

                for each_key in payout_gate_way_queryset.paramsList:
                    get_key = each_key.get("key")
                    if get_key=="client_id":
                        client_id=each_key.get("value")
                    if get_key=="client_secret":
                        client_secret=each_key.get("value")
                    if get_key=="encryption_key":
                        get_api_key=each_key.get("value")
                    if get_key=="channel_id":
                        channelId=each_key.get("value")
                    if get_key=="service_request_id":
                        serviceRequestId=each_key.get("value")
                    if get_key=="service_request_version":
                        serviceRequestVersion=each_key.get("value")
                    if get_key=="corp_code":
                        corpCode=each_key.get("value")
                    if get_key=="get_base_url":
                        get_base_url=each_key.get("value")
                    if get_key=="corp_account_number":
                        corp_account_number=each_key.get("value")
                
                requestUUID = str(random_alphanumeric_generate(15))
                
                ###################### Axis Beneficiary Creation Functionality Code #####################################
                paymentgatewayResponseStatusDict = axis_beneficiary_registration(
                                            client_id=client_id,
                                            client_secret=client_secret,
                                            get_api_key=get_api_key,
                                            channelId=channelId,
                                            serviceRequestId=serviceRequestId,
                                            serviceRequestVersion=serviceRequestVersion,
                                            corpCode=corpCode,
                                            userId=userId,
                                            get_base_url=get_base_url,
                                            requestUUID=requestUUID,
                                            apiVersion="1.0",
                                            beneCode=req_bene_code,
                                            beneName=req_account_name,
                                            beneAccNum=req_account_number,
                                            beneIfscCode=req_ifsc_code,
                                            beneBankName=req_bank_name,
                                            beneEmailAddr1=req_customer_email,
                                            beneMobileNo=req_customer_phone)
                        ##########################################################################################################
            else:
                data_status["error"]="Unable to connect to the server!!"
                return data_status
            ##################  Common code for Bene Creations #####################

            if paymentgatewayResponseStatusDict.get("responseStatus") == 1:
                transactionData = paymentgatewayResponseStatusDict.get("transactionData")
                beneList = paymentgatewayResponseStatusDict.get("beneList")
                responseList = paymentgatewayResponseStatusDict.get("responseList")
                beneList[0]["beneCode"] = req_bene_code


                beneficiary_queryset = ThirdPartyBeneficiaries.objects(beneficiaryId=req_bene_code,userId=str(merchant_queryset.id)).first()

                new_bene_code_entry = {
                    "beneCode": responseList[0].get("beneCode"),
                    "transactionApiId": str(payout_gate_way_queryset.id),
                    "status": "Pending",
                }
                if beneficiary_queryset and responseList:
                    existing_entry = None
                    for entry in beneficiary_queryset.beneCodeList:
                        if entry.get("transactionApiId") == str(payout_gate_way_queryset.id):
                            existing_entry = entry
                            break
                    
                    if existing_entry:
                        print("Entry with the same bankId already exists. Skipping append.")
                    else:
                        existingBenecodesList = beneficiary_queryset.beneCodeList
                        existingBenecodesList.append(new_bene_code_entry)
                        beneficiary_queryset.update(beneCodeList=existingBenecodesList)
                else:
                    beneficary_creation_table =  ThirdPartyBeneficiaries(
                        userId=ObjectId(merchant_queryset.id),
                        masterBankId=None,
                        remitterId=None,
                        beneficiaryId=req_bene_code,
                        fullName=responseList[0].get("beneName"),
                        mobileNumber="",
                        verifyStatus="Pending",
                        accountNumber=responseList[0].get("beneAccNum"),
                        ifscCode=beneList[0].get("bene_ifsc_code"),
                        transactionAPIId=ObjectId(payout_gate_way_queryset.id),
                        createdOn=datetime.datetime.now(),
                        beneCodeList=[new_bene_code_entry],
                        status = 1
                    ).save()


                responseBody = {
                "status": paymentgatewayResponseStatusDict.get("result"),
                "BeneData": beneList[0],
                "error_message":paymentgatewayResponseStatusDict.get("message"),
                }

                data_status["responseStatus"]=1
                data_status["result"]="Benificary created successfully!"
                data_status["beniDetails"]=responseBody
                return data_status

            elif paymentgatewayResponseStatusDict.get("responseStatus") == 0:
                responseBody = {
                "status": paymentgatewayResponseStatusDict.get("result"),
                "error_message":paymentgatewayResponseStatusDict.get("message"),
                }
                data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                return data_status
            else:
                data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                return data_status
        else:
            data_status["result"]="Please contact to admin to enable payout option!!"
            save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
            return data_status

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get required data!!"
        save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
        exceptionData = [traceback.format_exc()]
        exception_log_table = save_exception_logs_data(None,"payout","beneficiary_creation","beneficiary_creation",exceptionData,client_ip,"api")
        return data_status

fromDate=(datetime.datetime.now() - timedelta(days=15)).strftime("%Y-%m-%d")
toDate=datetime.datetime.now().strftime("%Y-%m-%d")
sample_axis_beni_enquiry_static_data = {
    "api_key":"qFhZRXyXf1GV",
    "beneCodesList":["Testing1234567890"],
    "fromDate": fromDate,
    "toDate": toDate
}
@third_party_apis.route("/beneficiaryenquiry",methods=["POST"])
def beneficiaryenquiry():
    data_status = {"responseStatus":0,"result":""}
    if SERVER_STATUS == "DOWN":
        data_status["result"] = SERVER_MAINTAINCE_MESSAGE
        return data_status
    
    api_key = request.headers.get("Api-Key","")
    encryption_data = request.json.get("encryption_data","")
    iv = request.json.get("iv","")

    # secretKey = "8d169331584408076ed69b3c"
    # encryption_key = bytes(secretKey, 'utf-8')
    # responseEncrypt = encrypt(sample_axis_beni_enquiry_static_data,encryption_key)
    # encryption_data = responseEncrypt.get('encryption_data')
    # iv = responseEncrypt.get('iv')

    responseDict = {}
    paymentgatewayResponseStatusDict = {}

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

    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]

    payOutPaymentGatewayId = ""
    userId=""
    requestData = [{"encryptionData":encryption_data,"iv":iv}]

    # Here Create client Logs Table 
    save_client_table = save_client_logs_data(userId,"payout","beneficiary_enquiry","beneficiary_enquiry",None,requestData,client_ip,"api")

    try:
        if not encryption_data and not api_key:
            data_status["result"] =  "required fields are missing!!"
            return data_status

        merchant_queryset = ThirdPartyMerchants.objects(apiKey=api_key,status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid Api Key!!"
            return data_status

        userId = str(merchant_queryset.id)

        try:
            secretKey = merchant_queryset.secretKey
            encryption_key = bytes(secretKey,'utf-8')

            jsonData = decrypt(encryption_data,encryption_key,iv)
            decryptResponse = json.loads(jsonData)
            print(decryptResponse,"(((((((((decryptResponse)))))))))")
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] =  "Invalid encryption data!!"
            return data_status

        graampay_check = decryptResponse.get("graampay_check","")

        payoutPaymentGatewaysList = [str(each_payin_pg.id) for each_payin_pg in merchant_queryset.payoutPaymentGatewaysList]

        payout_gate_way_queryset = TransactionAPI.objects(id__in=payoutPaymentGatewaysList,code=graampay_check,status=1).first()
        if not payout_gate_way_queryset:
            data_status["result"]="Payout option is disabled please contact to admin!!"
            return data_status

        paymentGateWayCode = payout_gate_way_queryset.code
        payOutPaymentGatewayId = str(payout_gate_way_queryset.id)


        save_client_table.update(userId=ObjectId(userId),transactionAPIId=ObjectId(payOutPaymentGatewayId))
        beneList=[]
    
        req_to_date=decryptResponse.get("toDate")
        req_from_date = decryptResponse.get("fromDate")
        req_benecodes_List = decryptResponse.get("beneCodesList")

        for each_bene in req_benecodes_List:
            bene_code_queryst = ThirdPartyBeneficiaries.objects(beneficiaryId = each_bene,userId=str(merchant_queryset.id)).first()
            if bene_code_queryst:
                exisitingBenecodesList=bene_code_queryst.beneCodeList
                for each_bene_code in exisitingBenecodesList:
                    if each_bene_code.get("transactionApiId") == str(payout_gate_way_queryset.id):
                        matchBenicode = each_bene_code.get("beneCode")
                        beneList.append(matchBenicode)

        if not req_to_date and not req_from_date :
            data_status["result"] = "Required Fields are missing!!"
            return data_status

        # bene_data_queryset = Beneficiaries.objects(createdOn__gte=fromDate,createdOn__lte=toDate,userId=merchant_queryset.id)
        
        # bencodesList = []
        # for each_bene in bene_data_queryset:
        #     benecodesList.append(each_bene.beneficiaryId)
        
        save_api_request_data_table = ApiRequestData(
            userId=str(merchant_queryset.id),
            userOrderId="",
            orderId="",
            requestData=[decryptResponse],
            createdOn=datetime.datetime.now(),
            status=1
            )
        save_table=save_api_request_data_table.save()
        
        if payout_gate_way_queryset:
            if payout_gate_way_queryset.code == "Axis_Payout":
                client_id = ""
                client_secret = ""
                get_api_key=""
                channelId=""
                serviceRequestId=""
                corpCode=""
                serviceRequestVersion=""
                get_base_url=""
                corp_account_number=""

                for each_key in payout_gate_way_queryset.paramsList:
                    get_key = each_key.get("key")
                    if get_key=="client_id":
                        client_id=each_key.get("value")
                    if get_key=="client_secret":
                        client_secret=each_key.get("value")
                    if get_key=="encryption_key":
                        get_api_key=each_key.get("value")
                    if get_key=="channel_id":
                        channelId=each_key.get("value")
                    if get_key=="service_request_id":
                        serviceRequestId=each_key.get("value")
                    if get_key=="service_request_version":
                        serviceRequestVersion=each_key.get("value")
                    if get_key=="corp_code":
                        corpCode=each_key.get("value")
                    if get_key=="get_base_url":
                        get_base_url=each_key.get("value")
                    if get_key=="corp_account_number":
                        corp_account_number=each_key.get("value")
                
                requestUUID = str(random_alphanumeric_generate(15))
                ###################### Axis Beneficiary Enquiry Functionality Code #####################################
                paymentgatewayResponseStatusDict = axis_beneficiary_enquiry(
                                            client_id=client_id,
                                            client_secret=client_secret,
                                            key=get_api_key,
                                            channelId=channelId,
                                            serviceRequestId=serviceRequestId,
                                            serviceRequestVersion=serviceRequestVersion,
                                            corpCode=corpCode,
                                            userId=userId,
                                            get_base_url=get_base_url,
                                            apiVersion="1.0",
                                            requestUUID=requestUUID,
                                            beneCode=beneList,
                                            toDate=req_to_date,
                                            fromDate=req_from_date,
                                            emailId=admin_recieve_email, ## assign the email to which data should be sent if records > 10k...Note the data from bank also has corpcode etc !!! not to be shared to client 
                                            status="All"
                                            )
                print(paymentgatewayResponseStatusDict,"((((((((((((((Beni Enquiry paymentgatewayResponseStatusDict))))))))))))))")
                ##########################################################################################################
            else:
                responseBody["error"]="Unable to connect to the server!!"
                return responseBody

            if paymentgatewayResponseStatusDict.get("responseStatus") == 1:
                jsondecryptResponse = paymentgatewayResponseStatusDict.get("jsondecryptResponse")
                data = jsondecryptResponse.get("data")
                beneDetails = data["beneDetails"]

                for each_bene in beneDetails:
                    beneId = each_bene.get("beneCode")
                    bene_data_queryset = ThirdPartyBeneficiaries.objects(beneCodeList__beneCode=beneId).first()

                    if bene_data_queryset:
                        if each_bene.get("status").lower() == "active":
                            # Copy the existing beneCodeList
                            existingBenecodesList = bene_data_queryset.beneCodeList
                            for each_dict in existingBenecodesList:
                                # Check if transactionAPIId matches
                                if each_dict.get("transactionApiId") == str(payout_gate_way_queryset.id):
                                    # Update the matched dictionary
                                    each_dict.update({
                                        "beneCode": each_dict.get("beneCode"),
                                        "transactionApiId": each_dict.get("transactionApiId"),
                                        "status": "Active"
                                    })
                                    break

                            # Save the updated list back to the database
                            bene_data_queryset.beneCodeList = existingBenecodesList
                            bene_data_queryset.save()

                if jsondecryptResponse:
                    beneDetails = paymentgatewayResponseStatusDict.get("beneList",[])
                    # beneDetails = jsondecryptResponse.get("data",{}).get("beneDetails",[])
                    print(beneDetails,"(((((((((((beneDetails in graamay)))))))))))")
                    status = jsondecryptResponse.get("status","")
                    message = jsondecryptResponse.get("message","")
                    if status == "S":
                        statusResponse = "Active"
                    else:
                        statusResponse = "Pending"

                    responseBody = {
                    "status": statusResponse,
                    "beneList": beneDetails,
                    "error_message":message
                    }
                    data_status["responseStatus"]=1
                    data_status["result"]="Benificary enquiry successfully!"
                    data_status["beniDetails"]=responseBody
                    return data_status
                else:
                    data_status["result"]="Invalid beneficiary enquiry please contact admin!!"
                    return data_status

            elif paymentgatewayResponseStatusDict.get("responseStatus") == 0:
                responseBody = {
                "status": paymentgatewayResponseStatusDict.get("result"),
                "error_message":paymentgatewayResponseStatusDict.get("message"),
                }
                data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                return data_status
            else:
                data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                return data_status
        else:
            data_status["result"]="Please contact to admin to enable payout option!!"
            save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get required data!!"
        save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
        exceptionData = [traceback.format_exc()]
        exception_log_table = save_exception_logs_data(None,"payout","beneficiary_enquiry","beneficiary_enquiry",exceptionData,client_ip,"api")
        return data_status

@third_party_apis.route("/bulk_fund_transfer",methods=["POST"])
def bulk_fund_transfer():
    data_status = {"responseStatus":0,"result":""}
    if SERVER_STATUS == "DOWN":
        data_status["result"]= SERVER_MAINTAINCE_MESSAGE
        return data_status

    api_key = request.headers.get("Api-Key","")
    encryption_data = request.json.get("encryption_data","")
    iv = request.json.get("iv","")

    # secretKey = "f51085df02812201344f6f0cb6959647"
    # encryption_key = bytes(secretKey, 'utf-8')
    # responseEncrypt = encrypt(sample_axis_bulk_transfer_static_data,encryption_key)
    # encryption_data = responseEncrypt.get('encryption_data')
    # iv = responseEncrypt.get('iv')

    print(api_key,"?api_key?")
    print(encryption_data,"?encryption_data?")
    print(iv,"?iv?")

    responseDict = {}
    paymentgatewayresponseDict = {}

    # 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

    print(request.headers,"?????????????")

    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]

    payOutPaymentGatewayId = ""
    userId = ""
    bank_reference_number = ""
    requestData = [{"encryption_data":encryption_data,"iv":iv}]

    # Here Create Client Logs Table
    save_client_table = save_client_logs_data(userId,"payout","fund_transfer","fundtransfer",None,requestData,client_ip,"api")

    try:
        if api_key and encryption_data and iv:
            merchant_queryset = ThirdPartyMerchants.objects(apiKey=api_key,status=1).first()
            if not merchant_queryset:
                data_status["result"]="Invalid Api Key!!"
                return data_status

            userId = str(merchant_queryset.id)
            # payoutPaymentGatewaysList = [str(each_payin_pg.id) for each_payin_pg in merchant_queryset.payoutPaymentGatewaysList]
            # print(payoutPaymentGatewaysList,"(((((((((((((payoutPaymentGatewaysList)))))))))))))")

            # try:
            #     if not merchant_queryset.payoutPaymentGatewayId:
            #         data_status["result"] = "Payout option is disabled please contact to admin!!"
            #         return data_status
            # except Exception as e:
            #     data_status["result"] = "Payout option is disabled please contact to admin!!"
            #     return data_status

            # payOutPaymentGatewayId = str(merchant_queryset.payoutPaymentGatewayId.id)

            # payout_gate_way_queryset = TransactionAPI.objects(id=payOutPaymentGatewayId,status=1).first()
            # if not payout_gate_way_queryset:
            #     data_status["result"]="Payout option is disabled please contact to admin!!"
            #     return data_status

            try:
                secretKey = merchant_queryset.secretKey
                encryption_key = bytes(secretKey, 'utf-8')

                jsonData = decrypt(encryption_data,encryption_key,iv)
                decryptResponse = json.loads(jsonData)
            except Exception as e:
                app.logger.error(traceback.format_exc())
                data_status["result"]="Invalid encryption data!!"
                return data_status

            payoutPaymentGatewaysList = [str(each_payout_pg.id) for each_payout_pg in merchant_queryset.payoutPaymentGatewaysList]
            print(payoutPaymentGatewaysList,"(((((((((((((payoutPaymentGatewaysList)))))))))))))")
            graampay_check = decryptResponse.get("graampay_check","")
            print(graampay_check,"(((((((((((((graampay_check)))))))))))))")

            payout_gate_way_queryset = TransactionAPI.objects(id__in=payoutPaymentGatewaysList,code=graampay_check,status=1).first()
            # print(payout_gate_way_queryset.id,"(((((((((****************)))))))))")
            if not payout_gate_way_queryset:
                data_status["result"]="Payout option is disabled please contact to admin!!!"
                return data_status

            paymentGateWayCode = payout_gate_way_queryset.code
            payOutPaymentGatewayId = str(payout_gate_way_queryset.id)


            save_client_table.update(userId=ObjectId(userId),transactionAPIId=ObjectId(payOutPaymentGatewayId))

            api_key = decryptResponse.get("api_key")

            if api_key == merchant_queryset.apiKey:
                ################################ Check api keys Code ##############################
                bulkFundtransfersList = decryptResponse.get("bulkFundtransfersList")
                print(bulkFundtransfersList,"((((((((((bulkFundtransfersList))))))))))")
                errorList =[]
                prepareBulkfundtransferList = []
 
                if len(bulkFundtransfersList) > 100:
                    data_status["result"] = "List size exceeded. Please provide only 100 or less Records"
                    return data_status

                # merchantUniqueNumber=merchant_id
                # mid_extracted = merchantUniqueNumber[1:].lstrip("0")
                total_amount = 0
                total_transaction_amount = 0
                total_txn_count = 0
                merchant_ref_numbers = set()
                transactionId=random_digit_generate(16)
                errorList = []
                # seen_merchant_ref_numbers = ()

                for each_fund_transfer in bulkFundtransfersList:
                    req_amount=each_fund_transfer.get("amount")
                    req_bene_code = each_fund_transfer.get("beneCode")
                    req_merchant_reference_number = each_fund_transfer.get("merchant_reference_number")
                    req_account_number = each_fund_transfer.get("beneAccNum")
                    req_account_name = each_fund_transfer.get("account_name")
                    req_ifsc_code = each_fund_transfer.get("accountIFSCCode")
                    req_transfer_type = each_fund_transfer.get("txnPaymode")
                    req_bank_name = each_fund_transfer.get("bank_name","")
                    req_customer_email = each_fund_transfer.get("customer_email","")
                    req_customer_phone = each_fund_transfer.get("customer_phone","")
                    req_remark = each_fund_transfer.get("remark","")
                    clientOrderId = each_fund_transfer.get("pgOrderId")
                    # clientOrderId = transaction_id_prefix + mid_extracted + each_bene_data.get("merchant_reference_number")

                    if not api_key and not req_merchant_reference_number and not req_account_number and not ifsc_code and not req_account_name and not req_amount and not req_transfer_type and not beneficiaryId and not clientOrderId:
                        errorList.append("Required Fields are missing for Account Number "+str(req_account_number))
                    
                    # if req_bene_code:
                    #     benecode = ThirdPartyBeneficiaries.objects(beneficiaryId=req_bene_code).first()
                    #     errorList.append("This beneficiary code already in use " +str(req_account_number))

                    if req_transfer_type not in ["NEFT","RTGS","IMPS"]:
                        errorList.append("transfer should be ones in ['NEFT','RTGS','IMPS'] " +str(req_account_number))
 
                    if req_merchant_reference_number in merchant_ref_numbers:
                        errorList.append("Two or more transactions have same Reference Number for Account Number" +str(req_account_number))
 
                    merchant_ref_numbers.add(req_merchant_reference_number)
 
                    checkorder_queryset = FundTransfers.objects(merchantReferenceNumber=decryptResponse.get('merchant_reference_number'),userId=str(userId)).first()
                    if checkorder_queryset:
                        errorList.append("Duplicate Merchant Reference Number for Account Number "+str(req_account_number))
                   
                    if len(req_account_number) < 11 or len(req_account_number) > 15:
                        errorList.append("Invalid length for Account number for " +str(req_account_number))
                   
                    if len(req_ifsc_code) != 11:
                        errorList.append("Invalid length for IFSC code for "+str(req_account_number))

                    # check_transaction_limits = merchant_transaction_limit_settings("Payout",payOutPaymentGatewayId,userId,req_amount)

                    # if check_transaction_limits.get("responseStatus") == 0:
                    #     errorList.append(check_transaction_limits.get("result")+str(account_number))
                        
                    ###################################################### Slab Calculation for payout code ###########################################################
                    payment_mode_queryset = PaymentMode.objects(paymentMode=req_transfer_type).first()
                    if not payment_mode_queryset:
                        errorList.append("Invalid transfer type!!")
                        return data_status

                    paymentModeId = str(payment_mode_queryset.id)
                    sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=req_transfer_type).first()
                    subPaymentModeId = str(sub_payment_mode_queryset.id)
                    # patternId = str(merchant_queryset.patternId.id)
                    commissionCharges={}
                    transactionAmount = req_amount
                    # commissionCharges = slab_calculation_for_payout(amount,paymentModeId,subPaymentModeId,patternId,payOutPaymentGatewayId)
                    # if commissionCharges.get("slabId") == None:
                    #     slabId = None
                    #     transactionAmount = amount
                    # else:
                    #     slabId = commissionCharges.get("slabId")
                    #     transactionAmount = float(commissionCharges.get("transactionAmount"))
                    # total_transaction_amount=total_transaction_amount+transactionAmount
                    ####################################################################################################################################################
                   
                    prepareBulkfundtransferList.append({
                        "txnPaymode": req_transfer_type,
                        "custUniqRef": clientOrderId,
                        "amount": req_amount,
                        "account_name": req_account_name,
                        "req_beneCode": req_bene_code,
                        "beneCode": req_bene_code,
                        "account_number": req_account_number,
                        "ifsc_code": req_ifsc_code,
                        # "bank_name": req_bank_name,
                        # "bank_branch": req_bank_branch,
                        "commissionCharges":commissionCharges,
                        "transactionAmount":transactionAmount,
                        "slabId":None,
                        "merchant_reference_number": req_merchant_reference_number,
                        "customer_email":req_customer_email,
                        "customer_phone": req_customer_phone,
                        "req_remark": req_remark
                    })
 
                fund_transfer_table = ThirdPartyBulkFundTransfers(
                    userId = str(merchant_queryset.id),
                    BulkTransactionId = transactionId,
                    BatchNumber = "0",
                    BulkCsvFileUpload = "",
                    status = 2,
                    totalAmount = transactionAmount,
                    totalTransactionAmount = transactionAmount,
                    totalTransactionCount = total_txn_count,
                    clientRequestData = [prepareBulkfundtransferList],
                    requestData = [decryptResponse],
                    responseData = [],
                    errorMessage = errorList,
                    ErrorType = "", # "ApiProvider" or "Internal"
                    createdOn = datetime.datetime.now(),
                    )
                save_table = fund_transfer_table.save()
                BulkTransferId = str(save_table.id)

                if len(errorList) > 0:
                    data_status['result']="Required Fields are missing!!"
                    data_status['errors']=errorList
                    fund_transfer_table.errorMessage = errorList
                    fund_transfer_table.ErrorType = "Internal"
                    fund_transfer_table.status = 0
                    fund_transfer_table.save(update_fields=["errorMessage", "ErrorType", "status"])
                    return data_status
 
                # checkamount = float(decryptResponse.get("amount"))
                checkamount = float(req_amount) ## taking total amount here
                if checkamount <= 0:
                    data_status['result']="Transaction amount is insufficient!!"
                    fund_transfer_table.errorMessage = ["Transaction amount is insufficient!!"]
                    fund_transfer_table.ErrorType = "Internal"
                    fund_transfer_table.status = 0
                    fund_transfer_table.save(update_fields=["errorMessage", "ErrorType", "status"])
                    return data_status
               
                # check_transaction_limits = merchant_transaction_limit_settings("Payout",payOutPaymentGatewayId,userId,total_amount,"bulk")
                # if check_transaction_limits.get("responseStatus") == 0:
                #     data_status['result']=check_transaction_limits.get("result")
                #     fund_transfer_table.errorMessage = [check_transaction_limits.get("result")]
                #     fund_transfer_table.ErrorType = "Internal"
                #     fund_transfer_table.status = 0
                #     fund_transfer_table.save(update_fields=["errorMessage", "ErrorType", "status"])
                #     return data_status
                

                userbalance_queryset = ThirdPartyMerchants.objects(id=str(userId)).modify(dec__payoutBalance=float(req_amount),new=True)
                userCurrentBalance = userbalance_queryset.payoutBalance
                userPreviousBalance = float(userCurrentBalance)+float(req_amount)
                    
                
                if payout_gate_way_queryset.code == "Axis_Payout":
                    client_id = ""
                    client_secret = ""
                    get_api_key=""
                    channelId=""
                    serviceRequestId=""
                    corpCode=""
                    serviceRequestVersion=""
                    get_base_url=""
                    corp_account_number=""

                    for each_key in payout_gate_way_queryset.paramsList:
                        get_key = each_key.get("key")
                        if get_key=="client_id":
                            client_id=each_key.get("value")
                        if get_key=="client_secret":
                            client_secret=each_key.get("value")
                        if get_key=="encryption_key":
                            get_api_key=each_key.get("value")
                        if get_key=="channel_id":
                            channelId=each_key.get("value")
                        if get_key=="service_request_id":
                            serviceRequestId=each_key.get("value")
                        if get_key=="service_request_version":
                            serviceRequestVersion=each_key.get("value")
                        if get_key=="corp_code":
                            corpCode=each_key.get("value")
                        if get_key=="get_base_url":
                            get_base_url=each_key.get("value")
                        if get_key=="corp_account_number":
                            corp_account_number=each_key.get("value")


                    requestUUID = str(random_alphanumeric_generate(15))

                    ########################################################## Axis Payout Fundtransfer Functionality Code #######################################################
                    paymentgatewayresponseDict = axis_payout_bulk_fundtransfer(client_id,client_secret,get_api_key,channelId,get_base_url,requestUUID,serviceRequestId,serviceRequestVersion,corpCode,corp_account_number,prepareBulkfundtransferList,bulk_transactionId=transactionId)
                    ################################################################################################################################################################

                # elif payout_gate_way_queryset.code == "Idfc_Payout":
                #     client_id = ""
                #     secretKey = ""
                #     kid = ""
                #     get_base_url = ""
                #     aud_url = ""
                #     auth_url = ""
                #     grant_type = ""
                #     scope = ""
                #     source = ""
                #     client_assertion_type = ""
                #     debitAcountNumber = ""
                #     remitterName = ""

                #     for each_key in payout_gate_way_queryset.paramsList:
                #         get_key = each_key.get("key")        
                #         if get_key == "client_id":
                #             client_id = each_key.get("value").strip()
                #         if get_key == "secret_key":
                #             secretKey = each_key.get("value").strip()
                #         if get_key == "base_url":
                #             get_base_url = each_key.get("value").strip()
                #         if get_key == "kid":
                #             kid = each_key.get("value").strip()
                #         if get_key == "aud_url":
                #             aud_url = each_key.get("value").strip()
                #         if get_key == "auth_url":
                #             auth_url = each_key.get("value").strip()
                #         if get_key == "scope":
                #             scope = each_key.get("value").strip()
                #         if get_key == "grant_type":
                #             grant_type = each_key.get("value").strip()
                #         if get_key == "source":
                #             source = each_key.get("value").strip()
                #         if get_key == "client_assertion_type":
                #             client_assertion_type = each_key.get("value").strip()
                #         if get_key == "debit_acount_number":
                #             debitAcountNumber = each_key.get("value").strip()
                #         if get_key == "remitter_name":
                #             remitterName = each_key.get("value").strip()

                #         bank_branch = ""
                    
                #     ########################################################## Idfc Bulk Payout Fundtransfer Functionality Code #######################################################
                #     paymentgatewayresponseDict = idfc_bulk_payout_fundtransfer(client_id,secretKey,kid,get_base_url,aud_url,auth_url,grant_type,scope,source,client_assertion_type,debitAcountNumber,remitterName,prepareBulkfundtransferList,bulk_transactionId=transactionId)
                #     ####################################################################################################################################################################
                else:
                    data_status["result"]="Invalid Request!!"
                    save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
                    return data_status
                bulkResponseData = []
                if paymentgatewayresponseDict.get("responseStatus") == 1:
                    if paymentgatewayresponseDict.get("bank_reference_number"):
                        bank_reference_number = paymentgatewayresponseDict.get("bank_reference_number")
                    else:
                        bank_reference_number = ""
                    
                    transactionData = paymentgatewayresponseDict.get("transactionData")

                    latest_bulk_fund_transfer_queryset = ThirdPartyBulkFundTransfers.objects(id=BulkTransferId).first()
                    for each_bulk_record in latest_bulk_fund_transfer_queryset.requestData:
                        # print(each_bulk_record,"((((((((each_bulk_record))))))))")
                        eachBulkFundtransferData = each_bulk_record.get("bulkFundtransfersList",[])
                        for each_ft_record in eachBulkFundtransferData:
                            fund_transfer_table = ThirdPartyFundTransfers(
                                bulkFundtransferId=BulkTransferId,
                                userId=str(merchant_queryset.id),
                                transactionAPIId=payOutPaymentGatewayId,
                                bankId=None,
                                bankName="",
                                merchantReferenceNumber=each_ft_record.get("merchant_reference_number"),
                                pgOrderId=each_ft_record.get("pgOrderId"), ### pgorderId starting with GP
                                fundTransferType="bulk",
                                accountType="bank",
                                apiType="api",
                                transferType="Debit",
                                bankBranch="",
                                accountNumber=each_ft_record.get("beneAccNum"),
                                accountIFSCCode=each_ft_record.get("accountIFSCCode"),
                                beneficiaryName=each_ft_record.get("beneficiaryName"),
                                uniqueRequestNumber=None,
                                amount=round(float(each_ft_record.get("amount")),2),
                                grandTotal=round(float(transactionAmount),2),
                                previousBalance = round(float(userPreviousBalance),2),
                                currentBalance = round(float(userCurrentBalance),2),
                                beneficiaryMail="",
                                beneficiaryPhone="",
                                paymentMode=each_ft_record.get("txnPaymode"),
                                narration="",
                                createdOn=datetime.datetime.now(),
                                userType="user",
                                status=2,
                                clientIp=client_ip,
                                transactionUniqueId = transactionId
                                )
                            save_table = fund_transfer_table.save()
                            instantTransferId = str(save_table.id)

                            responseDict = {
                            "status":"Processing",
                            "merchant_reference_number":each_ft_record.get("merchant_reference_number"),
                            "account_name":each_ft_record.get('beneficiaryName'),
                            "amount":each_ft_record.get('amount'),
                            "account_number":each_ft_record.get('beneAccNum'),
                            "ifsc_code":each_ft_record.get('beneAccNum'),
                            "bank_reference_number":bank_reference_number,
                            "transfer_type":each_ft_record.get('txnPaymode')
                            }
                            bulkResponseData.append(responseDict)

                    data_status["responseStatus"]=1
                    data_status["result"]="Success"
                    data_status["bulkResponseData"]=bulkResponseData
                    return data_status
                else:
                    data_status["responseStatus"]=paymentgatewayresponseDict.get("responseStatus")
                    data_status["result"]=paymentgatewayresponseDict.get("result")
                    save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
                    return data_status

            else:
                data_status["result"]="Mis-matched api keys!!"
                save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
                return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get payout data!!"
        save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
        exceptionData = [traceback.format_exc()]
        exception_log_table = save_exception_logs_data(None,"payout","fund_transfer","fundtransfer",exceptionData,client_ip,"api")
        return data_status

@third_party_apis.route("/bulk_beneficiary_statuscheck",methods=["POST"])
def bulk_beneficiary_statuscheck():
    data_status = {"responseStatus":0,"result":""}
    if SERVER_STATUS == "DOWN":
        data_status["result"] = SERVER_MAINTAINCE_MESSAGE
        return data_status
    api_key = request.headers.get("Api-Key","")
    encryption_data = request.json.get("encryption_data","")
    iv = request.json.get("iv","")

    print(api_key,"(((((((api_key)))))))")
    print(encryption_data,"(((((((api_key)))))))")
    print(iv,"(((((((api_key)))))))")
    # secretKey = "f51085df02812201344f6f0cb6959647"
    # encryption_key = bytes(secretKey, 'utf-8')
    # responseEncrypt = encrypt(sample_axis_beni_crea_static_data,encryption_key)
    # encryption_data = responseEncrypt.get('encryption_data')
    # iv = responseEncrypt.get('iv')

    responseDict = {}
    paymentgatewayResponseStatusDict = {}

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

    try:
        if not api_key and not encryption_data and not iv:
            data_status["result"] =  "required fields are missing!!"
            return data_status

        merchant_queryset = ThirdPartyMerchants.objects(apiKey=api_key,status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid Api Key!!"
            return data_status

        userId = str(merchant_queryset.id)

        
        errorList =[]
        benecodesList =[]
        transactionId=random_digit_generate(16)
        seen_merchant_ref_numbers = ()

        try:
            secretKey = merchant_queryset.secretKey
            encryption_key = bytes(secretKey,'utf-8')

            jsonData = decrypt(encryption_data,encryption_key,iv)
            decryptResponse = json.loads(jsonData)
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] =  "Invalid encryption data!!"
            return data_status

        if decryptResponse:
            # payOutPaymentGatewayId = str(merchant_queryset.payoutPaymentGatewayId.id)
            graampay_check = decryptResponse.get("graampay_check","")
            beneCodeList = decryptResponse.get("beneCodeList")
            payoutPaymentGatewaysList = [str(each_payin_pg.id) for each_payin_pg in merchant_queryset.payoutPaymentGatewaysList]

            if not graampay_check:
                data_status["result"]="Required fields are missing!!"
                return data_status

            payout_gate_way_queryset = TransactionAPI.objects(id__in=payoutPaymentGatewaysList,code=graampay_check,status=1).first()
            if not payout_gate_way_queryset:
                data_status["result"]="Payout option is disabled please contact to admin!!"
                return data_status

            paymentGateWayCode = payout_gate_way_queryset.code
            payOutPaymentGatewayId = str(payout_gate_way_queryset.id)
            print(beneCodeList,"((((((((beneCodeList In Thirdparty))))))))")


            counter = 0 
            for each_bene_code in beneCodeList:
                print(each_bene_code,"(((((((EACH each_bene_code)))))))")
                counter=counter+1
                beneCode=each_bene_code

                if beneCode != "":
                    if not beneCode:
                        data_status["result"] = "Invalid benecodes!!"
                        return data_status
                    print(beneCode,"((((((beneCode))))))")
                    benecodesList.append(beneCode)

            print(benecodesList,"((((((((((((benecodesList))))))))))))")
            if len(benecodesList) == []:
                data_status["result"] = "Invalid request!!"
                return data_status
                
            if payout_gate_way_queryset:
                if payout_gate_way_queryset.code == "Axis_Payout":
                    client_id = ""
                    client_secret = ""
                    get_api_key=""
                    channelId=""
                    serviceRequestId=""
                    corpCode=""
                    serviceRequestVersion=""
                    get_base_url=""
                    corp_account_number=""

                    for each_key in payout_gate_way_queryset.paramsList:
                        get_key = each_key.get("key")
                        if get_key=="client_id":
                            client_id=each_key.get("value")
                        if get_key=="client_secret":
                            client_secret=each_key.get("value")
                        if get_key=="encryption_key":
                            get_api_key=each_key.get("value")
                        if get_key=="channel_id":
                            channelId=each_key.get("value")
                        if get_key=="service_request_id":
                            serviceRequestId=each_key.get("value")
                        if get_key=="service_request_version":
                            serviceRequestVersion=each_key.get("value")
                        if get_key=="corp_code":
                            corpCode=each_key.get("value")
                        if get_key=="get_base_url":
                            get_base_url=each_key.get("value")
                        if get_key=="corp_account_number":
                            corp_account_number=each_key.get("value")
                    
                    requestUUID = str(random_alphanumeric_generate(15))
                    
                    fromDate=(datetime.datetime.now() - timedelta(days=25)).strftime("%Y-%m-%d")
                    toDate=datetime.datetime.now().strftime("%Y-%m-%d")

                    ###################### Axis Beneficiary Status check Functionality Code #####################################
                    paymentgatewayResponseStatusDict = axis_bulk_beneficiary_enquiry(
                        client_id=client_id,
                        client_secret=client_secret,
                        key=get_api_key,
                        channelId=channelId,
                        get_base_url=get_base_url,
                        apiVersion="1.0",
                        requestUUID=requestUUID,
                        serviceRequestId=serviceRequestId,
                        serviceRequestVersion=serviceRequestVersion,
                        corpCode=corpCode,
                        userId=userId,
                        fromDate=fromDate,
                        toDate=toDate,
                        emailId=admin_recieve_email,
                        status="All",
                        benecodesList=benecodesList
                        )
                    ##########################################################################################################
                else:
                    data_status["result"]="Unable to connect to the server!!"
                    return data_status
                ##################  Common code for Bene Status Check #####################
                if paymentgatewayResponseStatusDict.get("responseStatus") == 1:
                    transactionData = paymentgatewayResponseStatusDict.get("transactionData")
                    beneList = paymentgatewayResponseStatusDict.get("beneList")
                    responseList = paymentgatewayResponseStatusDict.get("responseList")
                    # print(paymentgatewayResponseStatusDict,"(((((((((((((paymentgatewayResponseStatusDict In Graampay Bulk beneList enq)))))))))))))")
                    # print(beneList,"(((((((((((((Bulk beneList enq)))))))))))))")
                    for each_bene in responseList:
                        beneId = each_bene.get("beneCode")
                        # print(beneId,"((((((((((((((&&&&&&&&&&&&&&&&&))))))))))))))")
                        bene_data_queryset = ThirdPartyBeneficiaries.objects(beneCodeList__beneCode=beneId).first()
                        # print(bene_data_queryset,"(((((((((((((wrwerfewfrefre)))))))))))))",each_bene.get("status").lower())
                        if bene_data_queryset:
                            if each_bene.get("status").lower() == "active":
                                # Copy the existing beneCodeList
                                existingBenecodesList = bene_data_queryset.beneCodeList
                                # print(existingBenecodesList,"(((((((((((existingBenecodesList)))))))))))")
                                # print(str(payout_gate_way_queryset.id),"(((((((((((payout_gate_way_queryset)))))))))))")
                                for each_dict in existingBenecodesList:
                                    # Check if transactionAPIId matches
                                    if each_dict.get("transactionApiId") == str(payout_gate_way_queryset.id):
                                        # Update the matched dictionary
                                        # print("MATCHED PG")
                                        each_dict.update({
                                            "beneCode": each_dict.get("beneCode"),
                                            "transactionApiId": each_dict.get("transactionApiId"),
                                            "status": "Active"
                                        })
                                        break
     
                                # Save the updated list back to the database
                                bene_data_queryset.beneCodeList = existingBenecodesList
                                bene_data_queryset.save()

                    responseData = {
                    "status":"Success",
                    "beneList":paymentgatewayResponseStatusDict.get("beneList"),
                    "message":"Success"
                    }
                    data_status["responseStatus"]=1
                    data_status["result"]="Bulk benificaries enquiries data successfully!"
                    data_status["bulkBenificiariesEnquiriesList"]=responseData
                    return data_status

                elif paymentgatewayResponseStatusDict.get("responseStatus") == 0:
                    data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                    return data_status
                else:
                    data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                    return data_status
            else:
                data_status["result"]="Please contact to admin to enable payout option!!"
                return data_status

        else:
            data_status["result"]="Our banking partner server is down, please try again later."

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get create bulk benecreation data!!"
        return data_status

@third_party_apis.route("/bulk_beneficiary_creation",methods=["POST"])
def bulk_beneficiary_creation():
    data_status = {"responseStatus":0,"result":""}
    if SERVER_STATUS == "DOWN":
        data_status["result"] = SERVER_MAINTAINCE_MESSAGE
        return data_status

    api_key = request.headers.get("Api-Key","")
    encryption_data = request.json.get("encryption_data","")
    iv = request.json.get("iv","")

    print(api_key,"(((((((api_key)))))))")
    print(encryption_data,"(((((((api_key)))))))")
    print(iv,"(((((((api_key)))))))")

    # secretKey = "f51085df02812201344f6f0cb6959647"
    # encryption_key = bytes(secretKey, 'utf-8')
    # responseEncrypt = encrypt(sample_axis_beni_crea_static_data,encryption_key)
    # encryption_data = responseEncrypt.get('encryption_data')
    # iv = responseEncrypt.get('iv')

    responseDict = {}
    paymentgatewayResponseStatusDict = {}

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

    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]

    payOutPaymentGatewayId = ""
    userId=""
    requestData = [{"encryptionData":encryption_data,"iv":iv}]

    # Here Create client Logs Table 
    save_client_table = save_client_logs_data(userId,"payout","bulk_beneficiary_creation","bulk_beneficiary_creation",None,requestData,client_ip,"api")

    print(client_ip,"CLIENT IP")

    try:
        # if not order_id and merchant_id and not api_key:
        if not encryption_data and not api_key and not iv:
            data_status["result"] =  "required fields are missing!!"
            return data_status

        merchant_queryset = ThirdPartyMerchants.objects(apiKey=api_key,status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid Api Key!!"
            return data_status

        userId = str(merchant_queryset.id)

        # payOutPaymentGatewayId = str(merchant_queryset.payoutPaymentGatewayId.id)

        # payout_gate_way_queryset = TransactionAPI.objects(id=payOutPaymentGatewayId,status=1).first()
        # if not payout_gate_way_queryset:
        #     data_status["result"] = "Payout option is disabled please contact to admin!!"
        #     return data_status

        try:
            secretKey = merchant_queryset.secretKey
            encryption_key = bytes(secretKey,'utf-8')

            jsonData = decrypt(encryption_data,encryption_key,iv)
            decryptResponse = json.loads(jsonData)
            print(decryptResponse,"((((((((((((((decryptResponse THIRDPARTY))))))))))))))")
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] =  "Invalid encryption data!!"
            return data_status

        graampay_check = decryptResponse.get("graampay_check","")
        beneficiaryCreationsList=decryptResponse.get("beneficiaryCreationsList")

        payoutPaymentGatewaysList = [str(each_payin_pg.id) for each_payin_pg in merchant_queryset.payoutPaymentGatewaysList]

        payout_gate_way_queryset = TransactionAPI.objects(id__in=payoutPaymentGatewaysList,code=graampay_check,status=1).first()
        if not payout_gate_way_queryset:
            data_status["result"]="Payout option is disabled please contact to admin!!"
            return data_status

        paymentGateWayCode = payout_gate_way_queryset.code
        payOutPaymentGatewayId = str(payout_gate_way_queryset.id)

        save_client_table.update(userId=ObjectId(userId),transactionAPIId=ObjectId(payOutPaymentGatewayId))

        errorList =[]
        beneficiariesList =[]

        
        print(beneficiaryCreationsList,"(((((IN THIRDPARTY)))))")
        if beneficiaryCreationsList == []:
            data_status["result"]="Invalid Request Data!!"
            return data_status
        # counter = 0
        for each_bene_creation in beneficiaryCreationsList:
            # counter=counter+1
            # beneficiaryCode = str(mid_extracted) + str(get_epoch_milli_time()) + counter
            beneficiaryCode=each_bene_creation.get("beneficiaryCode")
            req_bank_name=each_bene_creation.get("bank_name")
            # req_bene_code="BENI"+str(random_digit_generate(15))
            req_bene_code=each_bene_creation.get("req_bene_code")
            req_account_number = each_bene_creation.get("req_account_number")
            req_ifsc_code = each_bene_creation.get("req_ifsc_code")
            req_account_name = each_bene_creation.get("req_account_name")
            req_customer_email = each_bene_creation.get("req_customer_email","")
            req_customer_phone = each_bene_creation.get("req_customer_phone","")

            print(req_account_number,"req_account_number")
            print(req_ifsc_code,"req_ifsc_code")
            print(req_account_name,"req_account_name")
            print(req_bene_code,"req_bene_code")
            ############### check for required fields for each record #####################
            if not (req_account_number and req_ifsc_code and req_account_name and req_bene_code):
                data_status["result"] = "Required Fields are missing!!"
                return data_status
            
            if len(req_account_number) < 11 or len(req_account_number) > 15:
                    errorList.append("Invalid length for Account number for "+req_account_number)
                
            if len(req_ifsc_code) != 11:
                errorList.append("Invalid length for IFSC code for "+ req_account_number)
            
            if not validate_alphanumeric(req_account_name):
                errorList.append("Special characters not allowed in account name, use only alpha numeric"+ req_account_number)
                        
            check_beneficiary = ThirdPartyBeneficiaries.objects(accountNumber=req_account_number).first()
            if check_beneficiary:
                for each_bene in check_beneficiary.beneCodeList:
                    if str(each_bene.get("transactionApiId")) == str(payout_gate_way_queryset.id):
                        errorList.append("Beneficiary Code already Registered for "+ req_account_number)

            beniDict = {
            "req_bene_code":req_bene_code,
            "beneficiaryCode":beneficiaryCode,
            "req_account_number":req_account_number,
            "req_ifsc_code":req_ifsc_code,
            "req_account_name":req_account_name,
            "req_customer_email":req_customer_email,
            "req_customer_phone":req_customer_phone
            }
            beneficiariesList.append(beniDict)

        if len(errorList) > 0:
            data_status["result"] = "Invalid request"
            data_status["errors"] = errorList
            return data_status
            
        if payout_gate_way_queryset:
            if payout_gate_way_queryset.code == "Axis_Payout":
                client_id = ""
                client_secret = ""
                get_api_key=""
                channelId=""
                serviceRequestId=""
                corpCode=""
                serviceRequestVersion=""
                get_base_url=""
                corp_account_number=""

                for each_key in payout_gate_way_queryset.paramsList:
                    get_key = each_key.get("key")
                    if get_key=="client_id":
                        client_id=each_key.get("value")
                    if get_key=="client_secret":
                        client_secret=each_key.get("value")
                    if get_key=="encryption_key":
                        get_api_key=each_key.get("value")
                    if get_key=="channel_id":
                        channelId=each_key.get("value")
                    if get_key=="service_request_id":
                        serviceRequestId=each_key.get("value")
                    if get_key=="service_request_version":
                        serviceRequestVersion=each_key.get("value")
                    if get_key=="corp_code":
                        corpCode=each_key.get("value")
                    if get_key=="get_base_url":
                        get_base_url=each_key.get("value")
                    if get_key=="corp_account_number":
                        corp_account_number=each_key.get("value")
                
                requestUUID = str(random_alphanumeric_generate(15))
                
                ###################### Axis Beneficiary Creation Functionality Code #####################################
                paymentgatewayResponseStatusDict = axis_bulk_beneficiary_registration(
                                    client_id=client_id,
                                    client_secret=client_secret,
                                    get_api_key=get_api_key,
                                    channelId=channelId,
                                    serviceRequestId=serviceRequestId,
                                    serviceRequestVersion=serviceRequestVersion,
                                    corpCode=corpCode,
                                    userId=userId,
                                    get_base_url=get_base_url,
                                    requestUUID=requestUUID,
                                    apiVersion="1.0",
                                    beneficiaries=beneficiariesList
                                    )
                ##########################################################################################################
            else:
                data_status["result"]="Unable to connect to the server!!"
                return data_status
            ##################  Common code for Bene Creations #####################
            if paymentgatewayResponseStatusDict.get("responseStatus") == 1:
                transactionData = paymentgatewayResponseStatusDict.get("transactionData")
                beneList = paymentgatewayResponseStatusDict.get("beneList")
                responseList = paymentgatewayResponseStatusDict.get("responseList")

                print(beneList,"(((((((((((((beneList)))))))))))))")
                for each_req_bene in beneficiariesList:
                    print(each_req_bene,"(((((((((((((each_req_bene)))))))))))))")
                    bene_code = each_req_bene["req_bene_code"] ## this is req_bene_code- client sent
                    # each_req_bene.update(beneCode=bene_code)
                    # beneList.append(each_req_bene)

                    beneficiary_queryset = ThirdPartyBeneficiaries.objects(accountNumber=each_req_bene.get("req_account_number"),userId=str(merchant_queryset.id),status=1).first()

                    new_bene_code_entry = {
                        "beneCode": each_req_bene.get("beneficiaryCode"),
                        "transactionApiId": str(payout_gate_way_queryset.id),
                        "status": "Pending",
                    }
                    if beneficiary_queryset and responseList:
                        existing_entry = None
                        for entry in beneficiary_queryset.beneCodeList:
                            if entry.get("transactionApiId") == str(payout_gate_way_queryset.id):
                                existing_entry = entry
                                break
                        
                        if existing_entry:
                            print("Entry with the same bankId already exists. Skipping append.")
                        else:
                            existingBenecodesList = beneficiary_queryset.beneCodeList
                            existingBenecodesList.append(new_bene_code_entry)
                            beneficiary_queryset.update(beneCodeList=existingBenecodesList)
                    else:
                        beneficary_creation_table =  ThirdPartyBeneficiaries(
                            userId=ObjectId(merchant_queryset.id),
                            masterBankId=None,
                            remitterId=None,
                            beneficiaryId=bene_code,
                            fullName=each_req_bene.get("req_account_name"),
                            mobileNumber="",
                            verifyStatus="Pending",
                            accountNumber=each_req_bene.get("req_account_number"),
                            ifscCode=each_req_bene.get("req_ifsc_code"),
                            transactionAPIId=ObjectId(payout_gate_way_queryset.id),
                            createdOn=datetime.datetime.now(),
                            beneCodeList=[new_bene_code_entry],
                            status = 1
                        ).save()


                responseBody = {
                "status": paymentgatewayResponseStatusDict.get("result"),
                "beneList": beneList,
                "error_message":paymentgatewayResponseStatusDict.get("message"),
                }
                data_status["responseStatus"]=1
                data_status["result"]="Bulk benificaries created successfully!"
                data_status["bulkBenificiariesCreationsList"]=responseBody
                return data_status

            elif paymentgatewayResponseStatusDict.get("responseStatus") == 0:
                data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                return data_status
            else:
                data_status["result"]=paymentgatewayResponseStatusDict.get("message")
                return data_status
        else:
            data_status["result"]="Please contact to admin to enable payout option!!"
            save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
            return data_status

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to get required data!!"
        save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
        exceptionData = [traceback.format_exc()]
        exception_log_table = save_exception_logs_data(None,"payout","beneficiary_creation","beneficiary_creation",exceptionData,client_ip,"api")
        return data_status