from appservices.common.util import *
from appservices.v1.controllers.payout_apis import *
from appservices.common.payment_gateways.wowpe_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.lyra_payment_gateway import *
from appservices.common.payment_gateways.campuslinkpro_payment_gateway import *
from appservices.common.payment_gateways.getepay_payment_gateway import *
from appservices.common.payment_gateways.worldline_payment_gateway import *

users = Blueprint("users",__name__)

csrf.exempt(users)

@users.route("/user_signup",methods=["POST"])
@encrypt_decrypt_before_login
def user_signup():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        fullName = data.get("fullName","")
        phoneNumber = data.get("phoneNumber","")
        email = data.get("email","")
        address = data.get("address","")
        stateId = data.get("stateId","")
        cityId = data.get("cityId","")
        blockPoId = data.get("blockPoId","")
        pincodeId = data.get("pincodeId","")
        password = data.get("password","")
        siteTitle = data.get("siteTitle","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if fullName and phoneNumber and email and password and address and stateId and cityId and blockPoId and pincodeId and siteTitle:
        try:
            user_queryset = Users.objects(email__iexact=email).first()
            if user_queryset:
                data_status["result"]="Email id already exist!!"
                return data_status
            user_queryset = Users.objects(phoneNumber__iexact=phoneNumber).first()
            if user_queryset:
                data_status["result"]="Mobile Number already exist!!"
                return data_status
            # userPermissionId = "66bb4abb3bcb018a213b5af5"
            pattern_queryset = Patterns.objects(defaultProfile=True,status__in=[0,1]).first()
            patternId = str(pattern_queryset.id)

            imeiNumber = random_digit_generate(15)
            user_table = Users(
                fullName = fullName,
                phoneNumber  = phoneNumber,
                email  = email,
                password  = generate_password_hash(password), 
                address = address,
                createdOn =datetime.datetime.now(),
                stateId = stateId,
                cityId = cityId,
                blockPoId = blockPoId,
                pincodeId = pincodeId,
                patternId = patternId,
                # userPermissionId = userPermissionId,
                merchantUniqueNumber = generate_next_serial_number(),
                payoutBalance = 0,
                walletBalance = 0,
                siteTitle = siteTitle,
                merchantType="customer",
                channel="app",
                imeiNumber = imeiNumber,
                status = 1
                )
            save_table = user_table.save()
            userId = str(save_table.id)

            if userId:
                user_kyc_table = UserKYC(
                    userId=userId,
                    channel="app",
                    createdOn =datetime.datetime.now(),
                    submittedDate =datetime.datetime.now(),
                    panStatus="Pending",
                    bankStatus="Pending",
                    aadharStatus="Pending",
                    businessStatus="Pending",
                    agreementVerificationStatus="Pending",
                    videoVerificationStatus="Pending",
                    siteTitle=siteTitle,
                    status = 1
                    )
                save_table = user_kyc_table.save()

            user_queryset = Users.objects(id=userId).first()
            userLoginDetails = {
            "id": str(user_queryset.id),
            "stateId": str(user_queryset.stateId.id),
            "userPermissionId": str(user_queryset.patternId.userPermissionId.id),
            "userPermissionName": user_queryset.patternId.userPermissionId.permissionName,
            "fullName": user_queryset.fullName,
            "phoneNumber": user_queryset.phoneNumber,
            "email": user_queryset.email,
            "address": user_queryset.address,
            "createdOn": str(user_queryset.createdOn),
            "status": user_queryset.status,
            "merchantType": user_queryset.merchantType,
            "lastLogin": user_queryset.lastLogin
            }
            if user_queryset.tPin == 0:
                userLoginDetails["tPin"] = 0
            else:
                userLoginDetails["tPin"] = user_queryset.tPin

            data_status["responseStatus"] = 1
            data_status["result"] = "User signup successfully!"
            data_status["userLoginDetails"]=userLoginDetails
            try:
                email=user_queryset.email
                if email:
                    merchantName = str(user_queryset.fullName)
                    mail_subject = "Welcome to GraamPay!"
                    recipients_list = [email]
                    template_name = "emails/welcomeemail.html"
                    mail_data = {
                    "merchantName":merchantName,
                    "mobileNumber":user_queryset.phoneNumber
                    }
                    mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
            except Exception as e:
                pass
                
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to create user signup!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status

@users.route("/user_login",methods=["POST"])
@encrypt_decrypt_before_login
def user_login():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        phoneNumber = data.get("phoneNumber","")
        password = data.get("password","")
        deviceName = data.get("deviceName","")
        latitude = data.get("latitude","")
        longitude = data.get("longitude","")
        os = data.get("os","")
        siteTitle = data.get("siteTitle","")
        print(siteTitle,"(((((((((((siteTitle)))))))))))")
        print(phoneNumber,"(((((((((((phoneNumber)))))))))))")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    
    if phoneNumber and password:
        try:
            user_queryset=None
            if siteTitle:
                print('if page')
                site_queryset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
                if not site_queryset:
                    data_status["result"] = "Invalid App Request.Contact to admin support."
                    return data_status
                user_queryset = Users.objects(phoneNumber__iexact=phoneNumber,status__nin=[2],siteTitle=siteTitle).first()
            else:
                user_queryset = Users.objects((Q(phoneNumber__iexact=phoneNumber) & Q(status__nin=[2])) & (Q(siteTitle=None) | Q(siteTitle=""))).first()
            # user_queryset = Users.objects(phoneNumber__iexact=phoneNumber,status__nin=[2]).first()
            print(user_queryset,"user_queryset")
            if not user_queryset:
                data_status["result"]="Invalid phone number!!"
                return data_status
            userId = str(user_queryset.id)
            try:
                user_login_report_table = LoginReportLogs(
                    userId = userId,
                    deviceName = deviceName,
                    latitude = str(latitude),
                    longitude = str(longitude),
                    os = os,
                    wrongPasswordAttempts=0,
                    createdOn = datetime.datetime.now(),
                    status = 1
                    )
                save_user_log_table=user_login_report_table.save()
                logId = str(save_user_log_table.id)
            except Exception as e:
                app.logger.error(traceback.format_exc())
                pass
            if user_queryset.status == 0:
                data_status["result"]="The phone number is not verified."
                return data_status
            elif user_queryset.status == 5:
                data_status["result"]="Your account is locked please contact to support!!"
                return data_status
            elif user_queryset.status == 3:
                data_status["result"]="Your account is blocked please contact to support!!"
                return data_status
            elif user_queryset.status != 1:
                data_status["result"]="Invalid phone number!!"
                return data_status
            if check_password_hash(user_queryset.password, password):
                if user_queryset.status == 1:
                    user_queryset.lastLogin = datetime.datetime.now()
                    user_queryset.save()
                    userLoginDetails = {
                    "id": str(user_queryset.id),
                    "stateId": str(user_queryset.stateId.id),
                    "fullName": user_queryset.fullName,
                    "phoneNumber": user_queryset.phoneNumber,
                    "email": user_queryset.email,
                    "address": user_queryset.address,
                    "createdOn": str(user_queryset.createdOn),
                    "status": user_queryset.status,
                    "merchantType": user_queryset.merchantType,
                    "lastLogin": str(user_queryset.lastLogin),
                    "merchantId":str(user_queryset.merchantUniqueNumber)
                    }
                    if user_queryset.tPin == 0:
                        userLoginDetails["tPin"] = 0
                    else:
                        userLoginDetails["tPin"] = user_queryset.tPin

                    try:
                        if user_queryset.patternId.userPermissionId:
                            userLoginDetails["userPermissionId"] = str(user_queryset.patternId.userPermissionId.id)
                            userPermissionsDetails = {}
                            user_permissions_queryset = UserPermissions.objects(id=str(user_queryset.patternId.userPermissionId.id)).first()
                            userPermissionsDetails = {
                            "userPermissionId":str(user_permissions_queryset.id),
                            "permissionName":user_permissions_queryset.permissionName,
                            "groupingPermissionsList":user_permissions_queryset.groupingPermissionsList,
                            "categoryPermissionsList":user_permissions_queryset.categoryPermissionsList,
                            "servicePermissionsList":user_permissions_queryset.servicePermissionsList,
                            "operatorPermissionsList":user_permissions_queryset.operatorPermissionsList,
                            "otherPermissionsList":user_permissions_queryset.otherPermissionsList
                            }
                            userLoginDetails["userPermissionsDetails"]=userPermissionsDetails
                        else:
                            userLoginDetails["userPermissionId"] = ""
                            userLoginDetails["userPermissionsDetails"] = {}
                    except Exception as e:
                        userLoginDetails["userPermissionId"] = ""
                        userLoginDetails["userPermissionsDetails"] = {}

                    access_token = str(random_alphanumeric_generate(32))
                    print("new access token:", access_token)
                    user_queryset.update(userAccessToken=access_token) 

                    data_status["accessToken"] = access_token
                    data_status["responseStatus"] = 1
                    data_status["result"] = "User login successfull!"
                    data_status["userLoginDetails"] = userLoginDetails
                    return data_status
                else:
                    data_status["result"] = "Please contact the admin for approval to log in!!"
                    return data_status
            else:
                save_user_log_table.update(wrongPasswordAttempts=1)
                user_logs_queryset = LoginReportLogs.objects(userId=userId).order_by("-id").limit(3)
                if user_logs_queryset:
                    isLock = 0
                    for each_user_log in user_logs_queryset:
                        if each_user_log.wrongPasswordAttempts == 0:
                            isLock = 1
                    if isLock == 0:
                        user_queryset.update(status=5)
                        data_status["result"]="Too many attempts. Your account is locked please contact to support!!"
                        return data_status
                    else:
                        data_status["result"] = "Invalid Password!!"
                        return data_status
                else:
                    data_status["result"] = "Invalid Password!!"
                    return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to user login!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status


@users.route("/add_top_up_request",methods=["POST"])
@encrypt_decrypt_after_login
def add_top_up_request():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        depositBankId = data.get("depositBankId","")
        amount = data.get("amount",0)
        paymentMode = data.get("paymentMode","")
        transaction = data.get("transaction","")
        paymentDate = data.get("paymentDate","")
        transactionSlip = data.get("transactionSlip","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    

    if depositBankId and amount and paymentMode and userId and paymentDate and transaction:
        try:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status
            top_up_table = TopUpRequests(
                userId=userId,
                depositBankId = depositBankId,
                amount  = amount,
                paymentMode  = paymentMode,
                transaction  = transaction,
                paymentDate  = paymentDate,
                createdOn =datetime.datetime.now(),
                status = 1
                )
            save_table = top_up_table.save()

            if transactionSlip:
                image_name = upload_file_image(transactionSlip, "transactionSlips", str(get_epoch_milli_time()), "")
                if image_name:
                    save_table.update(transactionSlip=image_name)

            data_status["responseStatus"] = 1
            data_status["result"] = "User top up request successfully!"
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to save user top up request!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status


@users.route("/deposite_banks_list",methods=["POST"])
@encrypt_decrypt_after_login
def deposite_banks_list():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        bankType = data.get("bankType") #"administrator" or "parent"
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if not bankType:
        data_status["result"]="Required fields are missing!!"
        return data_status
    depositeBanksList=[]
    try:
        deposite_banks_queryset = CompanyBankAccounts.objects(companyType=bankType,status=1).only("id","bankName","companyType","accountName","accountNumber","bankCode").order_by("-id").all()
        
        for each_bank in deposite_banks_queryset:
            depositeBankDict = {
            "id":str(each_bank.id),
            "bankName":each_bank.bankName,
            "companyType":each_bank.companyType,
            "accountName":each_bank.accountName,
            "accountNumber":each_bank.accountNumber,
            "bankCode":each_bank.bankCode
            }
            if each_bank.image:
                depositeBankDict["image"]=domain+each_bank.image
            else:
                depositeBankDict["image"]=""
            depositeBanksList.append(depositeBankDict)
        data_status["responseStatus"] = 1
        data_status["result"] = "Deposite Banks data fected successfull!"
        data_status["depositeBanksList"] = depositeBanksList
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch deposite banks data!!"
        return data_status


@users.route("/transaction_history",methods=["POST"])
@encrypt_decrypt_after_login
def transaction_history():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        startDate = data.get("startDate")
        endDate = data.get("endDate")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if startDate and endDate:
        
        transactionHistoryList=[]
        try:
            startDateTimeObject = datetime.datetime.strptime(startDate,"%m-%d-%Y")
            endDateTimeObject = datetime.datetime.strptime(endDate,"%m-%d-%Y")
            start_date = startDateTimeObject.replace(hour=0, minute=0, second=0, microsecond=0)
            end_date = endDateTimeObject.replace(hour=23, minute=59, second=59, microsecond=999999)

            transactions_queryset = TopUpRequests.objects(
                createdOn__gte=start_date,
                createdOn__lte=end_date,
                status=1
                ).order_by("-id").all()
            
            for each_transaction in transactions_queryset:
                transactionDict = {
                "id":str(each_transaction.id),
                "depositBankId":str(each_transaction.depositBankId.id),
                "depositBankName":each_transaction.depositBankId.bankName,
                "depositBankCode":each_transaction.depositBankId.bankCode,
                "depositBankAccountNumber":each_transaction.depositBankId.accountNumber,
                "depositBankAccountType":each_transaction.depositBankId.accountType,
                "paymentMode":each_transaction.paymentMode,
                "transaction":each_transaction.transaction,
                "paymentDate":each_transaction.paymentDate,
                "amount":each_transaction.amount
                }
                if each_transaction.transactionSlip:
                    transactionDict["transactionSlip"]=domain+each_transaction.transactionSlip
                else:
                    transactionDict["transactionSlip"]=""
                transactionHistoryList.append(transactionDict)
            data_status["responseStatus"] = 1
            data_status["result"] = "Transaction history data fetched successfull!"
            data_status["transactionHistoryList"] = transactionHistoryList
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to fetch transaction history data!!"
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status


@users.route("/add_user_kyc",methods=["POST"])
@encrypt_decrypt_after_login
def add_user_kyc():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        originalPanName = data.get("originalPanName","")
        panName = data.get("panName","")
        panNumber = data.get("panNumber","")
        panStatus = data.get("panStatus","")
        panDocument = data.get("panDocument","")
        bankId = data.get("bankId","")
        bankName = data.get("bankName","")
        originalBankName = data.get("originalBankName","")
        bankAccountNumber = data.get("bankAccountNumber","")
        bankStatus = data.get("bankStatus","")
        ifscCode = data.get("ifscCode","")
        aadharName = data.get("aadharName","")
        originalAadharName = data.get("originalAadharName","")
        aadharNumber = data.get("aadharNumber","")
        aadharStatus = data.get("aadharStatus","")
        aadharDocument = data.get("aadharDocument","")
        aadharBackDocument = data.get("aadharBackDocument","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if panNumber and panStatus:
        try:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status
            user_kyc_table = UserKYC(
                userId=userId,
                panName = panName,
                originalPanName = originalPanName,
                panNumber  = panNumber,
                panStatus  = panStatus,
                bankName  = bankName,
                originalBankName  = originalBankName,
                bankId  = bankId,
                bankAccountNumber  = bankAccountNumber,
                bankStatus  = bankStatus,
                ifscCode  = ifscCode,
                aadharName  = aadharName,
                originalAadharName  = originalAadharName,
                aadharNumber  = aadharNumber,
                aadharStatus  = aadharStatus,
                channel="app",
                createdOn =datetime.datetime.now(),
                submittedDate =datetime.datetime.now(),
                status = 1
                )
            save_table = user_kyc_table.save()

            if panDocument:
                image_name = upload_file_image(panDocument, "panDocuments", str(get_epoch_milli_time()), "")
                if image_name:
                    save_table.update(panDocument=image_name)

            if aadharDocument:
                image_name = upload_file_image(aadharDocument, "aadharDocuments", str(get_epoch_milli_time()), "")
                if image_name:
                    save_table.update(aadharDocument=image_name)

            if aadharBackDocument:
                image_name = upload_file_image(aadharBackDocument, "aadharDocuments", str(get_epoch_milli_time()), "")
                if image_name:
                    save_table.update(aadharBackDocument=image_name)

            data_status["responseStatus"] = 1
            data_status["result"] = "User KYC added successfully!"
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to save user KYC!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status

# def add_user_kyc():
#   data_status = {"responseStatus": 0, "result": ""}
#   userId = request.json.get("userId","")
#   panName = request.json.get("panName","")
#   panNumber = request.json.get("panNumber","")
#   panStatus = request.json.get("panStatus","")
#   panDocument = request.json.get("panDocument","")
#   bankId = request.json.get("bankId","")
#   bankName = request.json.get("bankName","")
#   bankAccountNumber = request.json.get("bankAccountNumber","")
#   bankStatus = request.json.get("bankStatus","")
#   ifscCode = request.json.get("ifscCode","")
#   aadharName = request.json.get("aadharName","")
#   aadharNumber = request.json.get("aadharNumber","")
#   aadharStatus = request.json.get("aadharStatus","")
#   aadharDocument = request.json.get("aadharDocument","")

#   if panNumber and panStatus:
#       try:
#           user_queryset = Users.objects(id=userId,status=1).first()
#           if not user_queryset:
#               data_status["result"]="Invalid user id!!"
#               return data_status
#           user_kyc_table = UserKYC(
#               userId=userId,
#               panName = panName,
#               panNumber  = panNumber,
#               panStatus  = panStatus,
#               bankName  = bankName,
#               bankId  = bankId,
#               bankAccountNumber  = bankAccountNumber,
#               bankStatus  = bankStatus,
#               ifscCode  = ifscCode,
#               aadharName  = aadharName,
#               aadharNumber  = aadharNumber,
#               aadharStatus  = aadharStatus,
#               createdOn =datetime.datetime.now(),
#               status = 1
#               )
#           save_table = user_kyc_table.save()

#           if panDocument:
#               image_name = upload_file_image(panDocument, "panDocuments", str(get_epoch_milli_time()), "")
#               if image_name:
#                   save_table.update(panDocument=image_name)

#           if aadharDocument:
#               image_name = upload_file_image(aadharDocument, "aadharDocuments", str(get_epoch_milli_time()), "")
#               if image_name:
#                   save_table.update(aadharDocument=image_name)


#           data_status["responseStatus"] = 1
#           data_status["result"] = "User KYC added successfully!"
#           return data_status
#       except Exception as e:
#           app.logger.error(traceback.format_exc())
#           data_status["result"] = "Unable to save user KYC!!"
#           return data_status
#   else:
#       data_status["result"] = "Required fields are missing!!"
#       return data_status

@users.route("/update_user_kyc",methods=["POST"])
@encrypt_decrypt_after_login
def update_user_kyc():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        panName = data.get("panName","")
        originalPanName = data.get("originalPanName","")
        panNumber = data.get("panNumber","")
        panStatus = data.get("panStatus","")
        panDocument = data.get("panDocument","")
        bankId = data.get("bankId","")
        bankName = data.get("bankName","")
        originalBankName = data.get("originalBankName","")
        bankHolderName = data.get("bankHolderName","")
        bankAccountNumber = data.get("bankAccountNumber","")
        bankStatus = data.get("bankStatus","")
        ifscCode = data.get("ifscCode","")
        aadharName = data.get("aadharName","")
        originalAadharName = data.get("originalAadharName","")
        aadharNumber = data.get("aadharNumber","")
        aadharStatus = data.get("aadharStatus","")
        aadharDocument = data.get("aadharDocument","")
        aadharBackDocument = data.get("aadharBackDocument","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId:
        try:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status
            
            if bankHolderName=="":
                bankHolderName=str(user_queryset.fullName)
                
            user_kyc_queryset = UserKYC.objects(userId=userId).first()
            if user_kyc_queryset:
                if panNumber:
                    user_kyc_queryset.update(
                        panName = panName,
                        originalPanName = originalPanName,
                        panNumber = panNumber,
                        panStatus = "Approved",
                        submittedDate =datetime.datetime.now()
                        )
                if aadharNumber:
                    user_kyc_queryset.update(
                        aadharName = aadharName,
                        originalAadharName = originalAadharName,
                        aadharNumber = aadharNumber,
                        aadharStatus = "Approved",
                        submittedDate =datetime.datetime.now()
                        )

                if bankAccountNumber:
                    user_kyc_queryset.update(
                        bankName = bankName,
                        originalBankName = originalBankName,
                        bankAccountNumber = bankAccountNumber,
                        bankHolderName = bankHolderName,
                        bankStatus = "Approved",
                        ifscCode  = ifscCode,
                        submittedDate =datetime.datetime.now()
                        )
                    try:
                        if bankName=="" and bankId:
                            master_bank_queryset = MasterIFSCBank.objects(id=bankId).first()
                            if master_bank_queryset:
                                bankName = master_bank_queryset.bankName
                            else:
                                bankName = ""
                        autobeneficiary=autoBenificiaryCreation(userId,bankAccountNumber,ifscCode,str(user_queryset.fullName),bankId,bankName)
                    except Exception as e:
                        pass
                if bankId:
                    user_kyc_queryset.update(bankId=ObjectId(bankId))

                if panDocument:
                    image_name = upload_file_image(panDocument, "panDocuments", str(get_epoch_milli_time()), "")
                    if image_name:
                        user_kyc_queryset.update(panDocument=image_name,submittedDate =datetime.datetime.now())

                if aadharDocument:
                    image_name = upload_file_image(aadharDocument, "aadharDocuments", str(get_epoch_milli_time()), "")
                    if image_name:
                        user_kyc_queryset.update(aadharDocument=image_name,submittedDate =datetime.datetime.now())

                if aadharBackDocument:
                    image_name = upload_file_image(aadharBackDocument, "aadharDocuments", str(get_epoch_milli_time()), "")
                    if image_name:
                        user_kyc_queryset.update(aadharBackDocument=image_name,submittedDate =datetime.datetime.now())

                data_status["result"] = "User KYC updated successfully!"
            else:
                user_kyc_table = UserKYC(
                    userId=userId,
                    panName = panName,
                    originalPanName = originalPanName,
                    panNumber  = panNumber,
                    panStatus  = "Approved",
                    bankName  = bankName,
                    originalBankName  = originalBankName,
                    bankId  = bankId,
                    bankAccountNumber  = bankAccountNumber,
                    bankStatus  = "Approved",
                    ifscCode  = ifscCode,
                    aadharName  = aadharName,
                    originalAadharName  = originalAadharName,
                    aadharNumber  = aadharNumber,
                    aadharStatus  = "Approved",
                    createdOn =datetime.datetime.now(),
                    submittedDate =datetime.datetime.now(),
                    status = 1
                    )
                save_table = user_kyc_table.save()

                if bankAccountNumber!="":
                    try:
                        if bankName=="" and bankId:
                            master_bank_queryset = MasterIFSCBank.objects(id=bankId).first()
                            if master_bank_queryset:
                                bankName = master_bank_queryset.bankName
                            else:
                                bankName = ""
                        autobeneficiary=autoBenificiaryCreation(userId,bankAccountNumber,ifscCode,str(user_queryset.fullName),bankId,bankName)
                    except Exception as e:
                        pass

                if panDocument:
                    image_name = upload_file_image(panDocument, "panDocuments", str(get_epoch_milli_time()), "")
                    if image_name:
                        save_table.update(panDocument=image_name)

                if aadharDocument:
                    image_name = upload_file_image(aadharDocument, "aadharDocuments", str(get_epoch_milli_time()), "")
                    if image_name:
                        save_table.update(aadharDocument=image_name)

                if aadharBackDocument:
                    image_name = upload_file_image(aadharBackDocument, "aadharDocuments", str(get_epoch_milli_time()), "")
                    if image_name:
                        save_table.update(aadharBackDocument=image_name)

                data_status["result"] = "User KYC created successfully!"

            data_status["responseStatus"] = 1
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to update user KYC!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status

@users.route("/view_all_user_kyc",methods=["POST"])
@encrypt_decrypt_after_login
def view_all_user_kyc():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId:
        userKycList=[]
        try:
            user_kyc_queryset = UserKYC.objects(userId=userId,status=1).order_by("-id").all()
            
            for each_user_kyc in user_kyc_queryset:
                userKycDict = {
                "id":str(each_user_kyc.id),
                "panName":each_user_kyc.panName,
                "originalPanName":each_user_kyc.originalPanName,
                "panNumber":each_user_kyc.panNumber,
                "panStatus":each_user_kyc.panStatus,
                "bankName":each_user_kyc.bankName,
                "originalBankName":each_user_kyc.originalBankName,
                "bankAccountNumber":each_user_kyc.bankAccountNumber,
                "bankStatus":each_user_kyc.bankStatus,
                "ifscCode":each_user_kyc.ifscCode,
                "aadharName":each_user_kyc.aadharName,
                "originalAadharName":each_user_kyc.originalAadharName,
                "aadharNumber":each_user_kyc.aadharNumber,
                "aadharStatus":each_user_kyc.aadharStatus
                }
                if each_user_kyc.aadharDocument:
                    userKycDict["aadharDocument"]=domain+each_user_kyc.aadharDocument
                else:
                    userKycDict["aadharDocument"]=""

                if each_user_kyc.aadharBackDocument:
                    userKycDict["aadharBackDocument"]=domain+each_user_kyc.aadharBackDocument
                else:
                    userKycDict["aadharBackDocument"]=""

                if each_user_kyc.panDocument:
                    userKycDict["panDocument"]=domain+each_user_kyc.panDocument
                else:
                    userKycDict["panDocument"]=""

                if each_user_kyc.uploadVideo:
                    userKycDict["uploadVideo"]=domain+each_user_kyc.uploadVideo
                else:
                    userKycDict["uploadVideo"]=""

                # if each_user_kyc.bankId:
                #     userKycDict["bankId"]=str(each_user_kyc.bankId.id)
                # else:
                #     userKycDict["bankId"]=""
                userKycList.append(userKycDict)
            data_status["responseStatus"] = 1
            data_status["result"] = "User KYC data fetched successfull!"
            data_status["userKycList"] = userKycList
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to fetch user kyc data!!"
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status

# def view_all_user_kyc():
    # data_status = {"responseStatus": 0, "result": ""}
    # userId = request.json.get("userId","")

    # if userId:
    #   userKycList=[]
    #   try:
    #       user_kyc_queryset = UserKYC.objects(userId=userId,status=1).order_by("-id").all()
            
    #       for each_user_kyc in user_kyc_queryset:
    #           userKycDict = {
    #           "id":str(each_user_kyc.id),
    #           "panName":each_user_kyc.panName,
    #           "panNumber":each_user_kyc.panNumber,
    #           "panStatus":each_user_kyc.panStatus,
    #           "bankName":each_user_kyc.bankName,
    #           "bankAccountNumber":each_user_kyc.bankAccountNumber,
    #           "bankStatus":each_user_kyc.bankStatus,
    #           "ifscCode":each_user_kyc.ifscCode,
    #           "aadharName":each_user_kyc.aadharName,
    #           "aadharNumber":each_user_kyc.aadharNumber,
    #           "aadharStatus":each_user_kyc.aadharStatus,
    #           "aadharName":each_user_kyc.aadharName
    #           }
    #           if each_user_kyc.aadharDocument:
    #               userKycDict["aadharDocument"]=domain+each_user_kyc.aadharDocument
    #           else:
    #               userKycDict["aadharDocument"]=""

    #           if each_user_kyc.panDocument:
    #               userKycDict["panDocument"]=domain+each_user_kyc.panDocument
    #           else:
    #               userKycDict["panDocument"]=""

    #           if each_user_kyc.uploadVideo:
    #               userKycDict["uploadVideo"]=domain+each_user_kyc.uploadVideo
    #           else:
    #               userKycDict["uploadVideo"]=""

    #           # if each_user_kyc.bankId:
    #           #     userKycDict["bankId"]=str(each_user_kyc.bankId.id)
    #           # else:
    #           #     userKycDict["bankId"]=""
    #           userKycList.append(userKycDict)
    #       data_status["responseStatus"] = 1
    #       data_status["result"] = "User KYC data fetched successfull!"
    #       data_status["userKycList"] = userKycList
    #       return data_status
    #   except Exception as e:
    #       app.logger.error(traceback.format_exc())
    #       data_status["result"]="Unable to fetch user kyc data!!"
    #       return data_status
    # else:
    #   data_status["result"]="Required fields are missing!!"
        # return data_status

#Get User Personal Details API
@users.route("/get_user_personal_details",methods=["POST"])
@encrypt_decrypt_after_login
def get_user_personal_details():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    # userId = request.json.get("userId","")

    print(userId,"=====userId======")

    if userId:
        try:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status
            user_kyc_queryset = UserKYC.objects(userId=str(user_queryset.id)).first()

            user_details = {
            "id":str(user_queryset.id),
            "fullName":user_queryset.fullName,
            "merchantType":user_queryset.merchantType,
            "phoneNumber":user_queryset.phoneNumber,
            "email":user_queryset.email,
            "address":user_queryset.address,
            "pincode":user_queryset.pincodeId.pincode,
            "pincodeId":str(user_queryset.pincodeId.id),
            "stateId":str(user_queryset.stateId.id),
            "stateName":user_queryset.stateId.stateName,
            "cityId":str(user_queryset.cityId.id),
            "cityName":user_queryset.cityId.cityName,
            "blockPoId":str(user_queryset.blockPoId.id),
            "blockPoName":user_queryset.blockPoId.name,
            }
            try:
                if user_queryset.entityTypeId:
                    user_details["entityTypeId"]=str(user_queryset.entityTypeId.id)
                    user_details["entityType"]=user_queryset.entityTypeId.entityType
                    user_details["isIndividual"]=user_queryset.entityTypeId.isIndividual
                else:
                    user_details["entityTypeId"]=""
                    user_details["entityType"]= ""
                    user_details["isIndividual"]= True
            except Exception as e:
                user_details["entityTypeId"]=""
                user_details["entityType"]= ""
                user_details["isIndividual"]= True
            

            if user_queryset.pincodeId:
                user_details["pincode"]=user_queryset.pincodeId.pincode
            else:
                user_details["pincode"]=""

            if user_queryset.profilePicture:
                user_details["profilePicture"]=domain+user_queryset.profilePicture
            else:
                user_details["profilePicture"]=""
            try:
                if user_kyc_queryset.panNumber:
                    user_details["panName"]=user_kyc_queryset.panName
                    user_details["panNumber"]=user_kyc_queryset.panNumber
                    user_details["originalPanName"]=user_kyc_queryset.originalPanName
                    if user_kyc_queryset.panDocument:
                        user_details["panDocument"]=domain+user_kyc_queryset.panDocument
                    else:
                        user_details["panDocument"]=""
                else:
                    user_details["panName"]=""
                    user_details["panNumber"]=""
                    user_details["originalPanName"]=""
                    user_details["panDocument"]=""
            except:
                user_details["panName"]=""
                user_details["panNumber"]=""
                user_details["originalPanName"]=""
                user_details["panDocument"]=""
            try:
                if user_kyc_queryset.aadharNumber:
                    user_details["aadharName"]=user_kyc_queryset.aadharName
                    user_details["aadharNumber"]=user_kyc_queryset.aadharNumber
                    user_details["originalAadharName"]=user_kyc_queryset.aadharName
                    if user_kyc_queryset.aadharDocument:
                        user_details["aadharDocument"]=domain+user_kyc_queryset.aadharDocument
                    else:
                        user_details["aadharDocument"]=""

                    if user_kyc_queryset.aadharBackDocument:
                        user_details["aadharBackDocument"]=domain+user_kyc_queryset.aadharBackDocument
                    else:
                        user_details["aadharBackDocument"]=""
                else:
                    user_details["aadharName"]=""
                    user_details["aadharNumber"]=""
                    user_details["originalAadharName"]=""
                    user_details["aadharDocument"]=""
                    user_details["aadharBackDocument"]=""
            except:
                print(traceback.format_exc())
                user_details["aadharName"]=""
                user_details["aadharNumber"]=""
                user_details["originalAadharName"]=""
                user_details["aadharDocument"]=""
                user_details["aadharBackDocument"]=""
            try:
                if user_kyc_queryset.bankId:
                    user_details["bankId"]=str(user_kyc_queryset.bankId.id)
                    user_details["bankName"]=user_kyc_queryset.bankId.bankName
                else:
                    user_details["bankId"]=""
                    user_details["bankName"]=""
            except:
                user_details["bankId"]=""
                user_details["bankName"]=""

            try:
                if user_kyc_queryset.panReason:
                    user_details["panReason"]=user_kyc_queryset.panReason
                    user_details["bankReason"]=user_kyc_queryset.bankReason
                    user_details["aadharReason"]=user_kyc_queryset.aadharReason
                    user_details["videoVerificationReason"]=user_kyc_queryset.videoVerificationReason
                else:
                    user_details["panReason"]=""
                    user_details["bankReason"]=""
                    user_details["aadharReason"]=""
                    user_details["videoVerificationReason"]=""
            except:
                user_details["panReason"]=""
                user_details["bankReason"]=""
                user_details["aadharReason"]=""
                user_details["videoVerificationReason"]=""


            try:
                if user_kyc_queryset.panStatus:
                    user_details["panStatus"]=user_kyc_queryset.panStatus
                else:
                    user_details["panStatus"]="Pending"
            except Exception as e:
                user_details["panStatus"]="Pending"

            try:
                if user_kyc_queryset.businessStatus:
                    user_details["businessName"]=user_kyc_queryset.businessName
                    user_details["businessAddress"]=user_kyc_queryset.businessAddress
                    user_details["businessStatus"]=user_kyc_queryset.businessStatus
                else:
                    user_details["businessName"]=""
                    user_details["businessAddress"]=""
                    user_details["businessStatus"]="Pending"
            except Exception as e:
                user_details["businessName"]=""
                user_details["businessAddress"]=""
                user_details["businessStatus"]="Pending"

            try:
                if user_kyc_queryset.bankStatus:
                    user_details["bankStatus"]=user_kyc_queryset.bankStatus
                else:
                    user_details["bankStatus"]="Pending"
            except Exception as e:
                user_details["bankStatus"]="Pending"

            try:
                if user_kyc_queryset.aadharStatus:
                    user_details["aadharStatus"]=user_kyc_queryset.aadharStatus
                else:
                    user_details["aadharStatus"]="Pending"
            except Exception as e:
                user_details["aadharStatus"]="Pending"

            try:
                if user_kyc_queryset.videoVerificationStatus:user_details["videoVerificationStatus"]=user_kyc_queryset.videoVerificationStatus
                else:
                    user_details["videoVerificationStatus"]="Pending"
            except Exception as e:
                user_details["videoVerificationStatus"]="Pending"

            try:
                if user_kyc_queryset.agreementVerificationStatus:
                    user_details["agreementVerificationStatus"]=user_kyc_queryset.agreementVerificationStatus
                    user_details["agreementVerificationReason"]=user_kyc_queryset.agreementVerificationReason
                else:
                    user_details["agreementVerificationStatus"]="Pending"
                    user_details["agreementVerificationReason"]="Pending"
            except Exception as e:
                user_details["agreementVerificationStatus"]="Pending"
                user_details["agreementVerificationReason"]="Pending"

            try:
                kycStatus = [
                user_kyc_queryset.panStatus,
                user_kyc_queryset.bankStatus,
                user_kyc_queryset.aadharStatus,
                user_kyc_queryset.videoVerificationStatus,
                user_kyc_queryset.agreementVerificationStatus,
                ]
                businessStatus="Approved"
                businessStatusList=[]
                if user_queryset.entityTypeId.isIndividual == False:
                    businessStatusList.append(user_kyc_queryset.businessStatus)
                    kycStatus.append(user_kyc_queryset.businessStatus)
                    kycStatus.append(user_kyc_queryset.shopVideoStatus)
                    businessStatusList.append(user_kyc_queryset.shopVideoStatus)
                    if user_kyc_queryset.shopImagesList==[]:
                        kycStatus.append("Pending")
                        businessStatusList.append("Pending")
                    if user_kyc_queryset.documentsList==[]:
                        kycStatus.append("Pending")
                        businessStatusList.append("Pending")

                    if user_kyc_queryset.shopImagesList==[]:
                        kycStatus.append("Pending")
                        businessStatusList.append("Pending")
                    for each_image_status in user_kyc_queryset.shopImagesList:
                        shopImageStatus = each_image_status.get("shopImageStatus")
                        kycStatus.append(shopImageStatus)
                        businessStatusList.append(shopImageStatus)

                    
                    for each_document_status in user_kyc_queryset.documentsList:
                        documentStatus = each_document_status.get("documentStatus")
                        kycStatus.append(documentStatus)
                        businessStatusList.append(documentStatus)
        
                if any(status == "Rejected" for status in businessStatusList):
                    businessStatus = "Rejected"
                elif all(status == "Pending" for status in businessStatusList):
                    businessStatus = "Pending"
                elif all(status == "Approved" for status in businessStatusList):
                    businessStatus = "Approved"
                elif any(status == "Pending" for status in businessStatusList):
                    businessStatus = "Processing"
                else:
                    businessStatus= "Submitted"
                
                user_details["businessStatus"]=businessStatus
                user_details["kycStatus"] = all(status == "Approved" for status in kycStatus)
            except Exception as e:
                user_details["kycStatus"] = False

            try:
                if user_kyc_queryset:
                    user_details["originalBankName"]=user_kyc_queryset.originalBankName
                    user_details["bankAccountNumber"]=user_kyc_queryset.bankAccountNumber
                    user_details["ifscCode"]=user_kyc_queryset.ifscCode
                else:
                    user_details["originalBankName"]=""
                    user_details["bankAccountNumber"]=""
                    user_details["ifscCode"]=""
            except Exception as e:
                user_details["originalBankName"]=""
                user_details["bankAccountNumber"]=""
                user_details["ifscCode"]=""

            try:
                if user_kyc_queryset.uploadVideo:
                    user_details["uploadVideo"]=domain+user_kyc_queryset.uploadVideo
                else:
                    user_details["uploadVideo"]=""
            except Exception as e:
                user_details["uploadVideo"]=""

            try:
                if user_kyc_queryset.shopVideo:
                    user_details["shopVideo"]=domain+user_kyc_queryset.shopVideo
                else:
                    user_details["shopVideo"]=""
            except Exception as e:
                user_details["shopVideo"]=""

            if user_queryset.signatureImage:
                user_details["signatureImage"]=domain+user_queryset.signatureImage
                user_details["agreementDocument"]=domain+user_queryset.agreementDocument
            else:
                user_details["signatureImage"]=""
                user_details["agreementDocument"]=""

            # try:
            #     if user_kyc_queryset.panStatus == "Approved" and user_kyc_queryset.bankStatus == "Approved" and user_kyc_queryset.aadharStatus == "Approved" and user_kyc_queryset.videoVerificationStatus == "Approved":
            #         user_details["kycStatus"] = True
            #     else:
            #         user_details["kycStatus"] = False
            # except Exception as e:
            #     user_details["kycStatus"] = False
            try:
                if user_queryset.patternId.userPermissionId:
                    user_details["userPermissionId"] = str(user_queryset.patternId.userPermissionId.id)
                    userPermissionsDetails = {}
                    user_permissions_queryset = UserPermissions.objects(id=str(user_queryset.patternId.userPermissionId.id)).first()
                    userPermissionsDetails = {
                    "userPermissionId":str(user_permissions_queryset.id),
                    "permissionName":user_permissions_queryset.permissionName,
                    "groupingPermissionsList":user_permissions_queryset.groupingPermissionsList,
                    "categoryPermissionsList":user_permissions_queryset.categoryPermissionsList,
                    "servicePermissionsList":user_permissions_queryset.servicePermissionsList,
                    "operatorPermissionsList":user_permissions_queryset.operatorPermissionsList,
                    "otherPermissionsList":user_permissions_queryset.otherPermissionsList
                    }
                    user_details["userPermissionsDetails"]=userPermissionsDetails
                else:
                    user_details["userPermissionId"] = ""
                    user_details["userPermissionsDetails"] = {}
            except Exception as e:
                user_details["userPermissionId"] = ""
                user_details["userPermissionsDetails"] = {}

            data_status["responseStatus"] = 1
            data_status["userPersonalDetails"] = user_details
            data_status["result"] = "User personal details fetched successfully!"
            print(user_details,"====")
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to fetch user personal details data!!"
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status

# def get_user_personal_details():
    # # data_status = {"responseStatus": 0, "result": ""}
    # userId = request.json.get("userId","")

    # if userId:
    #   try:
    #       user_queryset = Users.objects(id=userId,status=1).first()
    #       user_kyc_queryset = UserKYC.objects(userId=userId,status=1).first()
    #       if not user_queryset:
    #           data_status["result"]="Invalid user id!!"
    #           return data_status
    #       user_details = {
    #       "id":str(user_queryset.id),
    #       "fullName":user_queryset.fullName,
    #       "mobileNumber":user_queryset.phoneNumber,
    #       "emailId":user_queryset.email,
    #       "address":user_queryset.address,
    #       "pincode":user_queryset.pincodeId.pincode,
    #       "pincodeId":str(user_queryset.pincodeId.id),
    #       "stateId":str(user_queryset.stateId.id),
    #       "stateName":user_queryset.stateId.stateName,
    #       "cityId":str(user_queryset.cityId.id),
    #       "cityName":user_queryset.cityId.cityName,
    #       "blockPoId":str(user_queryset.blockPoId.id),
    #       "blockPoName":user_queryset.blockPoId.name,
    #       }
    #       if user_queryset.userTypeId:
    #           user_details["userTypeId"]=str(user_queryset.userTypeId.id)
    #           user_details["userType"]=user_queryset.userTypeId.name
    #       else:
    #           user_details["userTypeId"]=""
    #           user_details["userType"]= ""

    #       try:
    #           if user_queryset.entityTypeId:
    #               user_details["entityTypeId"]=str(user_queryset.entityTypeId.id)
    #               user_details["entityType"]=user_queryset.entityTypeId.entityType
    #           else:
    #               user_details["entityTypeId"]=""
    #               user_details["entityType"]= ""
    #       except Exception as e:
    #           user_details["entityTypeId"]=""
    #           user_details["entityType"]= ""

    #       if user_queryset.pincodeId:
    #           user_details["pincode"]=user_queryset.pincodeId.pincode
    #       else:
    #           user_details["pincode"]=""

    #       if user_queryset.profilePicture:
    #           user_details["profilePicture"]=domain+user_queryset.profilePicture
    #       else:
    #           user_details["profilePicture"]=""
    #       try:

    #           if user_kyc_queryset.panName:
    #               user_details["panName"]=user_kyc_queryset.panName
    #           else:
    #               user_details["panName"]=""
    #       except:
    #           user_details["panName"]=""
    #       try:
    #           if user_kyc_queryset.aadharName:
    #               user_details["aadharName"]=user_kyc_queryset.aadharName
    #           else:
    #               user_details["aadharName"]=""
    #       except:
    #           user_details["panName"]=""
    #       try:
    #           if user_kyc_queryset.bankId:
    #               user_details["bankId"]=str(user_kyc_queryset.bankId.id)
    #               user_details["bankName"]=user_kyc_queryset.bankId.bankName
    #           else:
    #               user_details["bankId"]=""
    #               user_details["bankName"]=""
    #       except:
    #           user_details["bankId"]=""
    #           user_details["bankName"]=""

    #       try:
    #           if user_kyc_queryset.panReason:
    #               user_details["panReason"]=user_kyc_queryset.panReason
    #               user_details["bankReason"]=user_kyc_queryset.bankReason
    #               user_details["aadharReason"]=user_kyc_queryset.aadharReason
    #               user_details["videoVerificationReason"]=user_kyc_queryset.videoVerificationReason
    #           else:
    #               user_details["panReason"]=""
    #               user_details["bankReason"]=""
    #               user_details["aadharReason"]=""
    #               user_details["videoVerificationReason"]=""
    #       except:
    #           user_details["panReason"]=""
    #           user_details["bankReason"]=""
    #           user_details["aadharReason"]=""
    #           user_details["videoVerificationReason"]=""

    #       try:
    #           if user_kyc_queryset:
    #               user_details["panStatus"]=user_kyc_queryset.panStatus
    #               user_details["bankStatus"]=user_kyc_queryset.bankStatus
    #               user_details["aadharStatus"]=user_kyc_queryset.aadharStatus
    #               user_details["videoVerificationStatus"]=user_kyc_queryset.videoVerificationStatus
    #           else:
    #               user_details["panStatus"]="Pending"
    #               user_details["bankStatus"]="Pending"
    #               user_details["aadharStatus"]="Pending"
    #               user_details["videoVerificationStatus"]="Pending"
    #       except Exception as e:
    #           # app.logger.error(traceback.format_exc())
    #           user_details["panStatus"]="Pending"
    #           user_details["bankStatus"]="Pending"
    #           user_details["aadharStatus"]="Pending"
    #           user_details["videoVerificationStatus"]="Pending"
    #       try:
    #           kycStatus = [user_kyc_queryset.panStatus,
    #           user_kyc_queryset.bankStatus,
    #           user_kyc_queryset.aadharStatus,
    #           user_kyc_queryset.videoVerificationStatus
    #           ]
    #           user_details["kycStatus"] = all(status == "Approved" for status in kycStatus)
    #       except Exception as e:
    #           user_details["kycStatus"] = False

    #       # try:
    #       #     if user_kyc_queryset.panStatus == "Approved" and user_kyc_queryset.bankStatus == "Approved" and user_kyc_queryset.aadharStatus == "Approved" and user_kyc_queryset.videoVerificationStatus == "Approved":
    #       #         user_details["kycStatus"] = True
    #       #     else:
    #       #         user_details["kycStatus"] = False
    #       # except Exception as e:
    #       #     user_details["kycStatus"] = False

    #       if user_queryset.userPermissionId:
    #           user_details["userPermissionId"] = str(user_queryset.userPermissionId.id)
    #           userPermissionsDetails = {}
    #           user_permissions_queryset = UserPermissions.objects(id=str(user_queryset.userPermissionId.id)).first()
    #           userPermissionsDetails = {
    #           "userPermissionId":str(user_permissions_queryset.id),
    #           "permissionName":user_permissions_queryset.permissionName,
    #           "groupingPermissionsList":user_permissions_queryset.groupingPermissionsList,
    #           "categoryPermissionsList":user_permissions_queryset.categoryPermissionsList,
    #           "servicePermissionsList":user_permissions_queryset.servicePermissionsList,
    #           "operatorPermissionsList":user_permissions_queryset.operatorPermissionsList,
    #           "otherPermissionsList":user_permissions_queryset.otherPermissionsList
    #           }
    #           user_details["userPermissionsDetails"]=userPermissionsDetails
    #       else:
    #           user_details["userPermissionId"] = ""
    #           user_details["userPermissionsDetails"] = {}

    #       data_status["responseStatus"] = 1
    #       data_status["userPersonalDetails"] = user_details
    #       data_status["result"] = "User personal details fetched successfully!"
    #       return data_status
    #   except Exception as e:
    #       app.logger.error(traceback.format_exc())
    #       data_status["result"]="Unable to fetch user personal details data!!"
    #       return data_status
    # else:
    #   data_status["result"]="Required fields are missing!!"
    #   return data_status

# Get User Business Details API
@users.route("/get_user_business_details",methods=["POST"])
@encrypt_decrypt_after_login
def get_user_business_details():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId:
        try:
            user_queryset = Users.objects(id=userId,status=1).only("id","businessName","businessAddress").first()
            if not user_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status
            user_data = {
            "id":str(user_queryset.id)
            }
            if user_queryset.businessName:
                user_data["businessName"]=user_queryset.businessName
            else:
                user_data["businessName"]=""

            if user_queryset.businessAddress:
                user_data["businessAddress"]=user_queryset.businessAddress
            else:
                user_data["businessAddress"]=""

            data_status["responseStatus"] = 1
            data_status["userBusinessDetailsList"] = user_data
            data_status["result"] = "User business details fetched successfully!"
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to fetch user business details data!!"
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status

# Get User KYC Details API
@users.route("/get_user_kyc_details",methods=["POST"])
@encrypt_decrypt_after_login
def get_user_kyc_details():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        print(userId)
        print("((((((((((userId))))))))))")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId:
        try:
            user_kyc_queryset = UserKYC.objects(userId=userId,status=1).first()
            if not user_kyc_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status
            userKycDict = {
            "id":str(user_kyc_queryset.id),
            "panName":user_kyc_queryset.panName,
            "panNumber":user_kyc_queryset.panNumber,
            "panStatus":user_kyc_queryset.panStatus,
            "bankName":user_kyc_queryset.bankName,
            "bankAccountNumber":user_kyc_queryset.bankAccountNumber,
            "bankStatus":user_kyc_queryset.bankStatus,
            "ifscCode":user_kyc_queryset.ifscCode,
            "aadharName":user_kyc_queryset.aadharName,
            "aadharNumber":user_kyc_queryset.aadharNumber,
            "aadharStatus":user_kyc_queryset.aadharStatus,
            "aadharName":user_kyc_queryset.aadharName
            }
            if user_kyc_queryset.aadharDocument:
                userKycDict["aadharDocument"]=domain+user_kyc_queryset.aadharDocument
            else:
                userKycDict["aadharDocument"]=""

            if user_kyc_queryset.aadharBackDocument:
                userKycDict["aadharBackDocument"]=domain+user_kyc_queryset.aadharBackDocument
            else:
                userKycDict["aadharBackDocument"]=""

            if user_kyc_queryset.panDocument:
                userKycDict["panDocument"]=domain+user_kyc_queryset.panDocument
            else:
                userKycDict["panDocument"]=""

            if user_kyc_queryset.uploadVideo:
                userKycDict["uploadVideo"]=domain+user_kyc_queryset.uploadVideo
            else:
                userKycDict["uploadVideo"]=""
            try:

                if user_kyc_queryset.bankId:
                    userKycDict["bankId"]=str(user_kyc_queryset.bankId.id)
                else:
                    userKycDict["bankId"]=""
            except:
                userKycDict["bankId"]=""

            try:
                if user_kyc_queryset.panReason:
                    userKycDict["panReason"]=user_kyc_queryset.panReason
                    userKycDict["bankReason"]=user_kyc_queryset.bankReason
                    userKycDict["aadharReason"]=user_kyc_queryset.aadharReason
                    userKycDict["videoVerificationReason"]=user_kyc_queryset.videoVerificationReason
                else:
                    userKycDict["panReason"]=""
                    userKycDict["bankReason"]=""
                    userKycDict["aadharReason"]=""
                    userKycDict["videoVerificationReason"]=""
            except:
                userKycDict["panReason"]=""
                userKycDict["bankReason"]=""
                userKycDict["aadharReason"]=""
                userKycDict["videoVerificationReason"]=""
                
            data_status["responseStatus"] = 1
            data_status["result"] = "User KYC data fetched successfully!"
            data_status["userKycData"] = userKycDict
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to fetch user kyc data!!"
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status

# Get user verification video API
@users.route("/get_user_verification_video",methods=["POST"])
@encrypt_decrypt_after_login
def get_user_verification_video():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId:
        try:
            user_kyc_queryset = UserKYC.objects(userId=userId).only("id","userId","uploadVideo").first()
            if not user_kyc_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status
            user_data_dict = {
            "id":str(user_kyc_queryset.id),
            "merchantName":user_kyc_queryset.userId.fullName
            }
            if user_kyc_queryset.uploadVideo:
                user_data_dict["uploadVideo"]=domain+user_kyc_queryset.uploadVideo
            else:
                user_data_dict["uploadVideo"]=""

            data_status["responseStatus"] = 1
            data_status["result"] = "User verification video fetched successfully!"
            data_status["userVideoData"] = user_data_dict
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to fetch user video!!"
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status

#Change User Password API
@users.route("/change_user_password",methods=["POST"])
@encrypt_decrypt_after_login
def change_user_password():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        oldPassword = data.get("oldPassword","")
        newPassword = data.get("newPassword","")
        confirmPassword = data.get("confirmPassword","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId and oldPassword and newPassword and confirmPassword:
        if newPassword != confirmPassword:
            data_status["result"]="New password and confirm password should be the same!!"
            return data_status
        try:
            user_queryset = Users.objects(id=userId,status=1).only("password").first()
            if user_queryset:
                if check_password_hash(user_queryset.password, oldPassword):
                    user_queryset.update(password=generate_password_hash(newPassword))
                    # user_queryset.password = generate_password_hash(newPassword)
                    # user_queryset.save()
                    data_status["responseStatus"] = 1
                    data_status["result"] = "Password changed successfully!"
                    return data_status
                else:
                    data_status["result"]="Old password is incorrect!!"
                    return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to change password!!"
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status


# Change User Tpin API
@users.route("/change_user_tpin",methods=["POST"])
@encrypt_decrypt_after_login
def change_user_tpin():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        oldTpin = data.get("oldTpin","")
        newTpin = data.get("newTpin","")
        confirmTpin = data.get("confirmTpin","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId and oldTpin and newTpin and confirmTpin:
        if newTpin != confirmTpin:
            data_status["result"]="New Tpin and confirm Tpin should be the same!!"
            return data_status
        try:
            user_queryset = Users.objects(id=userId,status=1).only("id","tPin").first()
            if user_queryset:
                print(str(user_queryset.id),"((((((((user_queryset.tPin))))))))",oldTpin)
                print(user_queryset.tPin,"((((((((user_queryset.tPin))))))))",oldTpin)
                if user_queryset.tPin == int(oldTpin):
                    user_queryset.update(tPin=newTpin)
                    data_status["responseStatus"] = 1
                    data_status["result"] = "Tpin changed successfully!"
                    return data_status
                else:
                    data_status["result"]="Old Tpin is incorrect!!"
                    return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to change Tpin!!"
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status

# #Forgot Tpin API
# @users.route("/forgot_tpin",methods=["POST"])
# def forgot_tpin():
#     data_status = {"responseStatus": 0, "result": ""}
#     userId = request.json.get("userId")
#     newTpin = request.json.get("newTpin")
#     confirmTpin = request.json.get("confirmTpin")
#     if userId and newTpin and confirmTpin:
#         try:
#             user_queryset = Users.objects(id=userId,status=1).first()
#             if user_queryset:
#                 user_queryset.update(tpin=newTpin)
#                 data_status["responseStatus"] = 1
#                 data_status["result"] = "Tpin changed successfully!"
#                 return data_status
#         except Exception as e:
#             app.logger.error(traceback.format_exc())
#             data_status["result"]="Unable to change Tpin!!"
#             data_status["tPin"]=tpin
#             return data_status
#     else:
#         data_status["result"]="Required fields are missing!!"
#         return data_status

#Forgot Tpin API
@users.route("/set_up_tpin",methods=["POST"])
@encrypt_decrypt_after_login
def set_up_tpin():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        tPin = data.get("tPin")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    if userId and tPin:
        try:
            user_queryset = Users.objects(id=userId,status=1).only("id","tPin").first()
            if user_queryset:
                user_queryset.update(tPin=tPin)
                data_status["responseStatus"] = 1
                data_status["result"] = "Tpin set up successfully"
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to set up Tpin!!"
            # data_status["tPin"]=tpin
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status

#OTP Generate API
@users.route("/generate_otp",methods=["GET","POST"])
@encrypt_decrypt_after_login
def generate_otp():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        otpType = data.get("otpType","TPIN_Setup_OTP")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    try:
        if userId and otpType:
            user_queryset = Users.objects(id=userId,status=1).only("phoneNumber","fullName","email").first()
            if user_queryset:
                phoneNumber = user_queryset.phoneNumber
                userName = user_queryset.fullName
                smsresponse=send_sms(phoneNumber, otpType,userName)
                data_status["responseStatus"] = 1
                data_status["result"]="Otp generated successfully"
                data_status["otp"]=smsresponse.get('otp')
                if otpType != "Other_OTP":
                    try:
                        email=user_queryset.email
                        if email:
                            merchantName = str(user_queryset.fullName)
                            mail_subject = "Otp verification for GraamPay!"
                            recipients_list = [email]
                            template_name = "emails/otpverification.html"
                            mail_data = {
                            "merchantName":merchantName,
                            "otpCode":smsresponse.get('otp'),
                            }
                            mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                    except Exception as e:
                        pass
                return data_status
            else:
                data_status["result"]="Invalid User"
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to generate OTP."
        return data_status

@users.route("/generate_signup_otp",methods=["GET","POST"])
@encrypt_decrypt_before_login
def generate_signup_otp():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        phoneNumber = data.get("phoneNumber")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    try:
        if not phoneNumber:
            data_status["result"]="Required fields are missing!!"
            return data_status
        user_queryset = Users.objects(phoneNumber=phoneNumber,status=1).only('id',"phoneNumber").first()
        if not user_queryset:
            try:
                smsResponse=send_sms(phoneNumber,"Signup_Mobile_Verification")
                print(smsResponse,"smsResponse")
                data_status["responseStatus"] = 1
                data_status["result"]="Otp generated successfully"
                data_status["otp"]=smsResponse.get('otp')
                return data_status
            except Exception as e:
                data_status["result"]="Unable to generate OTP!!"
                return data_status
        else:
            data_status["result"]="Mobile Number already exist!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to generate OTP."
        return data_status


#Email Verification API
@users.route("/verify_email",methods=["GET","POST"])
@encrypt_decrypt_before_login
def verify_email():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        email = data.get("email")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    if email:
        try:
            user_queryset = Users.objects(email__iexact=email).only('id',"email").first()
            if user_queryset:
                data_status["result"] = "Email already exists"
                return data_status
            else:
                otp = random.randint(100000,999999)
                merchantName ="User"
                mail_subject = "Otp verification for GraamPay!"
                recipients_list = [email]
                template_name = "emails/otpverification.html"
                mail_data = {
                    "merchantName": merchantName,
                    "otpCode": otp,
                }
                mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
              
                data_status["responseStatus"] = 1
                data_status["result"] = "Otp sent successfully"
                data_status["otp"] = otp
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to send OTP."
            return data_status
    else:
        data_status["result"]="Required field is missing!!"
        return data_status

#Forgot password API
@users.route("/forgot_password_otp",methods=["POST"])
@encrypt_decrypt_before_login
def forgot_password_otp():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        phoneNumber = data.get("phoneNumber")
        otpType = data.get("otpType")
        siteTitle = data.get("siteTitle","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    

    if phoneNumber and otpType:
        try:
            user_queryset=None
            if siteTitle:
                site_queryset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
                if not site_queryset:
                    data_status["result"] = "Invalid App Request.Contact to admin support."
                    return data_status
                user_queryset = Users.objects(phoneNumber__iexact=phoneNumber,status=1,siteTitle=siteTitle).only("fullName","email").first()
            else:
                user_queryset = Users.objects((Q(phoneNumber__iexact=phoneNumber) & Q(status=1)) & (Q(siteTitle=None) | Q(siteTitle=""))).only("fullName","email").first()
            # user_queryset = Users.objects(phoneNumber__iexact=phoneNumber).first()
            if user_queryset:
                smsResponse=send_sms(phoneNumber, otpType,userName=(user_queryset.fullName),Reason="",amount="")
                data_status["responseStatus"] = 1
                data_status["otp"] = smsResponse.get('otp')
                data_status["result"] = "Otp sent successfully!"
                if otpType != "Other_OTP":
                    try:
                        email=user_queryset.email
                        if email:
                            merchantName = str(user_queryset.fullName)
                            mail_subject = "Otp verification for GraamPay!"
                            recipients_list = [email]
                            template_name = "emails/otpverification.html"
                            mail_data = {
                            "merchantName":merchantName,
                            "otpCode":smsResponse.get('otp'),
                            }
                            mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                    except Exception as e:
                        pass
                return data_status
            else:
                data_status["result"]="Invalid mobile number!!"
                return data_status

        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to send otp!!"
            return data_status
    else:
        data_status["result"]="Required field is missing!!"
        return data_status

#Update forgot password API
@users.route("/update_forgot_password",methods=["POST"])
@encrypt_decrypt_before_login
def update_forgot_password():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        phoneNumber = data.get("phoneNumber")
        password = data.get("password")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if phoneNumber:
        try:
            user_queryset = Users.objects(phoneNumber__iexact=phoneNumber,status=1).only("id","password").first()
            if user_queryset:
                user_queryset.update(password = generate_password_hash(password),)

                data_status["responseStatus"] = 1
                data_status["result"] = "Your password updated successfully!"
                return data_status
            else:
                data_status["result"]="Invalid mobile number!!"
                return data_status

        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to change password!"
            return data_status
    else:
        data_status["result"]="Required field is missing!!"
        return data_status

#Verification mobile number API
@users.route("/verify_mobile_number",methods=["GET","POST"])
@encrypt_decrypt_before_login
def verify_mobile_number():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        print(data,"request.json")
        phoneNumber = data.get("phoneNumber")
        otpType = data.get("otpType")
        siteTitle = data.get("siteTitle","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    if phoneNumber:
        try:
            user_queryset=None
            print(siteTitle,"siteTitle")
            if siteTitle:
                site_queryset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
                if not site_queryset:
                    data_status["result"] = "Invalid App Request.Contact to admin support."
                    return data_status
                user_queryset = Users.objects(phoneNumber__iexact=phoneNumber,siteTitle=siteTitle).only("id","phoneNumber").first()
            else:
                user_queryset = Users.objects(Q(phoneNumber__iexact=phoneNumber) & (Q(siteTitle=None) | Q(siteTitle=""))).only("id","phoneNumber").first()
            # print(user_queryset.tojson(),"user_queryset")
            if user_queryset:
                data_status["result"] = "Phone number already in use!"
                return data_status
            else:
                smsResponse=send_sms(phoneNumber,otpType)
                print(smsResponse,"smsResponse")
                data_status["responseStatus"] = 1
                data_status["result"]="Otp generated successfully"
                data_status["otp"]=smsResponse.get('otp')
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to send OTP."
            return data_status
    else:
        data_status["result"]="Required field is missing!!"
        return data_status

#Fetch Login Report Details API
@users.route("/get_login_reports",methods=["POST"])
@encrypt_decrypt_after_login
def get_login_reports():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        startDate =data.get("startDate","")
        endDate = data.get("endDate","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request. "
        return data_status

    LoginReportsList = []

    if userId:
        if startDate and endDate:
            startDate = startDate + " 00:00:00"
            endDate = endDate + " 23:59:59"
            start_date = datetime.datetime.strptime(startDate, "%m-%d-%Y %H:%M:%S")
            end_date = datetime.datetime.strptime(endDate, "%m-%d-%Y %H:%M:%S")

            login_reports_queryset = LoginReportLogs.objects(
                userId = userId,
                createdOn__gte = start_date,
                createdOn__lte = end_date
                ).order_by('-id').all()
        else:
            login_reports_queryset = LoginReportLogs.objects(
                userId = userId
                ).order_by('-id').all()
        try:
            for each_login_report in login_reports_queryset:
                ist_time=each_login_report.createdOn.replace(tzinfo=pytz.utc).astimezone(ist_timezone)
                login_dict = {
                "id":str(each_login_report.id),
                "deviceName":each_login_report.deviceName,
                "latitude":each_login_report.latitude,
                "longitude":each_login_report.longitude,
                "os":each_login_report.os,
                "on":ist_time.strftime("%d %b,%I:%M %p"),
                }
                LoginReportsList.append(login_dict)

            data_status["responseStatus"] = 1
            data_status["result"] = "Login reports fetched successfully"
            data_status["LoginReportsList"] = LoginReportsList
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fetch details"
            return data_status
    else:
        data_status["result"] = "Required fields are missing"
        return data_status


################### Add Money Wallet API's ##############

@users.route("/get_payment_gateways",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def get_payment_gateways():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        paymentGatewaysList = []
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        merchant_queryset = Users.objects(id=userId,status=1).first()
        if not merchant_queryset.patternId:
            data_status["result"]="No payment gateways available!"
            return data_status
        pattern_queryset = Patterns.objects(id=str(merchant_queryset.patternId.id)).first()
        if not pattern_queryset.payinPaymentGatewaysList:
            data_status["result"]="No payment gateways available!!"
            return data_status

        payinPaymentGatewaysList = [str(each_payin_pg.id) for each_payin_pg in pattern_queryset.payinPaymentGatewaysList]
        print(payinPaymentGatewaysList,"(((((((((((((payinPaymentGatewaysList)))))))))))))")
        startDate = datetime.datetime.now().replace(hour=0,minute=0,second=0)
        endDate = startDate.replace(hour=23,minute=59,second=59)

        print(startDate,"(((((((((startDate)))))))))")
        print(endDate,"(((((((((endDate)))))))))")

        payment_gateways_queyset = TransactionAPI.objects(id__in=payinPaymentGatewaysList,status=1).order_by('-id').all()
        for each_payment_gateway in payment_gateways_queyset:
            print(each_payment_gateway,"((((((each_payment_gateway))))))")
            today_wallet_txn_amount = WalletTransactions.objects(paymentGatewayId=str(each_payment_gateway.id),createdOn__gte=startDate,createdOn__lte=endDate,status__in=[1,2],userType="user",creditType="Credit").sum("amount")
            print(today_wallet_txn_amount,"((((((((((((today_wallet_txn_amount))))))))))))")
            print(each_payment_gateway.perdayTransactionLimit,"((((((((((((Per day TXN AMOUNT))))))))))))")
            if float(each_payment_gateway.perdayTransactionLimit)==0 or (float(each_payment_gateway.perdayTransactionLimit) > float(today_wallet_txn_amount)):
                paymeny_gateway_dict = {
                "id":str(each_payment_gateway.id),
                "paymentGateway":each_payment_gateway.apiName,
                "transactionType":each_payment_gateway.transactionType,
                "paramsList":each_payment_gateway.paramsList
                }
                paymentGatewaysList.append(paymeny_gateway_dict)
        data_status["result"] = "Payment gateways data fetched successfully!"
        data_status["responseStatus"] = 1
        data_status["paymentGatewaysList"] = paymentGatewaysList
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to fetch payment gateways data!!"
        return data_status


# #Get Settlement Type's API
# @users.route("/get_settlement_types",methods=["POST"])
# @encrypt_decrypt_after_login
# def get_settlement_types():
#     data_status = {"responseStatus": 0, "result": ""}
#     try:
#         data = request.decrypted_data
#         userId = data.get("userId")
#         settlementPaysList = []
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         data_status["result"] = "Invalid Request"
#         return data_status

#     try:
#         settlement_types_queyset = Settlement.objects(status=1).order_by('-id').all()
#         for each_settlement_type in settlement_types_queyset:
#             settlement_type_dict = {
#             "id":str(each_settlement_type.id),
#             "settlementPay":each_settlement_type.settlementType
#             }
#             settlementPaysList.append(settlement_type_dict)
#         data_status["result"] = "Data fetched successfully"
#         data_status["responseStatus"] = 1
#         data_status["settlementPaysList"] = settlementPaysList
#         return data_status
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         data_status["result"] = "unable to fetch data"
#         return data_status


#Get Settlement Type's API
@users.route("/get_settlement_types",methods=["POST"])
@encrypt_decrypt_after_login
def get_settlement_types():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        siteTitle = data.get("siteTitle","")
        settlementPaysList = []
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    try:
        multiplesite_queyset=None
        user_queryset=None
        if userId:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"]="Invalid user!!"
                return data_status

            if siteTitle:
                siteTitle = siteTitle.lower()
                multiplesite_queyset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
                if not multiplesite_queyset:
                    data_status["result"]="Invalid sitetitle!!"
                    return data_status

                enableMerchantSettlement = multiplesite_queyset.enableMerchantSettlement
                instantSettlementType = multiplesite_queyset.instantSettlementType
                paylaterSettlementType = multiplesite_queyset.paylaterSettlementType
                defaultSelect = multiplesite_queyset.defaultSelect

                if enableMerchantSettlement == True:
                    if instantSettlementType == True:
                        if defaultSelect == "instant":
                            defaultSelectValue = True
                        else:
                            defaultSelectValue = False

                        instantSettlementDict = {"settlementType": "Instant","defaultSelect": defaultSelectValue}
                        settlementPaysList.append(instantSettlementDict)

                    if paylaterSettlementType == True:
                        if defaultSelect == "paylater":
                            defaultSelectPaylaterValue = True
                        else:
                            defaultSelectPaylaterValue = False

                        paylaterSettlementDict = {"settlementType": "T+1", "defaultSelect": defaultSelectPaylaterValue}
                        settlementPaysList.append(paylaterSettlementDict)

            data_status["result"] = "Settlement data fetched successfully!"
            data_status["responseStatus"] = 1
            data_status["settlementPaysList"] = settlementPaysList
            print(data_status,"data_status")
            return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch settlement data!!"
        return data_status

#Add Wallet Money API 
@users.route("/add_money_to_wallet",methods=["POST"])
@encrypt_decrypt_after_login
def add_money_to_wallet():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        amount = data.get("amount",0.00)
        paymentGatewayId = data.get("paymentGatewayId","")
        paymentType = data.get("paymentType","")
        creditType = data.get("creditType","")
        transactionId = data.get("transactionId","")
        settlementPayId = data.get("settlementPayId","")
        isConfirm = data.get("isConfirm",False)
        paymentAuthentication = data.get("paymentAuthentication",False)
        transactionData = data.get("transactionData")
        orderId = data.get("orderId","")
        status = data.get("status")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if amount and paymentGatewayId and settlementPayId:
        try:
            user_queryset = Users.objects(id=userId,status=1).only("id","walletBalance","").first()
            if not user_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status
            if status == 1:   
                actuallBalance = user_queryset.walletBalance
                updateAmount = float(actuallBalance)+amount
                user_queryset.update(walletBalance = updateAmount)

                transactionData = [transactionData]
                wallet_transaction_table = WalletTransactions(
                    userId = userId,
                    amount = amount,
                    paymentGatewayId = paymentGatewayId,
                    paymentType = paymentType,
                    creditType = creditType,
                    transactionId = transactionId,
                    settlementPayId = settlementPayId,
                    isConfirm = isConfirm,
                    transactionData = transactionData,
                    paymentAuthentication = paymentAuthentication,
                    orderId = orderId,
                    walletLog="Wallet Balance is added with the amount of " + str(int(amount)) + ".",
                    userType="user",
                    createdBy = None,
                    createdOn = datetime.datetime.now(),
                    status = status
                    ).save()
                walletTransactionId = str(wallet_transaction_table.id)
            elif status == 0:
                transactionData = [transactionData]
                wallet_transaction_table = WalletTransactions(
                    userId = userId,
                    amount = amount,
                    paymentGatewayId = paymentGatewayId,
                    paymentType = paymentType,
                    creditType = creditType,
                    transactionId = transactionId,
                    settlementPayId = settlementPayId,
                    isConfirm = isConfirm,
                    transactionData = transactionData,
                    paymentAuthentication = paymentAuthentication,
                    orderId = orderId,
                    walletLog="Unable to add money.Transaction Failed!!",
                    userType="user",
                    createdBy = None,
                    createdOn = datetime.datetime.now(),
                    status = status
                    ).save()
                walletTransactionId = str(wallet_transaction_table.id)

            data_status["responseStatus"] = 1
            data_status["walletTransactionId"] = walletTransactionId
            data_status["result"] = "Money added to the wallet successfully"
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to add money to the wallet"
            return data_status
    else:
        data_status["result"] = "Required fields are missing."
        return data_status


def fetching_wallet_transaction_reports(each_wallet_trasaction):
    wallet_transaction_dict = {}
    try:
        transaction_queryset = Transactions.objects(transactionId=each_wallet_trasaction.transactionId).only("serviceName","id").first()
        wallet_transaction_dict = {
        "id":str(each_wallet_trasaction.id),
        "amount":each_wallet_trasaction.amount,
        # "paymentGatewayId":str(each_wallet_trasaction.paymentGatewayId.id),
        # "paymentGateway":each_wallet_trasaction.paymentGatewayId.sourceName,
        # "settlementPayId":str(each_wallet_trasaction.settlementPayId.id),
        # "settlementPay":each_wallet_trasaction.settlementPayId.settlementType,
        "paymentType":each_wallet_trasaction.paymentType,
        "creditType":each_wallet_trasaction.creditType,
        "transactionId":each_wallet_trasaction.transactionId,
        # "isConfirm":each_wallet_trasaction.isConfirm,
        # "transactionData":each_wallet_trasaction.transactionData,
        # "createdOn":each_wallet_trasaction.createdOn,
        #"serviceName":transaction_queryset.serviceName,
        "status":each_wallet_trasaction.status,
        }
        if transaction_queryset:
            wallet_transaction_dict.update({"serviceName":transaction_queryset.serviceName}),
        else:
            wallet_transaction_dict.update({"serviceName":each_wallet_trasaction.paymentType}),

        if each_wallet_trasaction.createdOn:
            ist_time=each_wallet_trasaction.createdOn.replace(tzinfo=pytz.utc).astimezone(ist_timezone)
            wallet_transaction_dict["createdOn"] = ist_time.strftime("%m-%d-%Y %I:%M %p")
        # if each_wallet_trasaction.paymentGatewayId:
        #     wallet_transaction_dict["paymentGatewayId"] = str(each_wallet_trasaction.paymentGatewayId.id)
        #     wallet_transaction_dict["paymentGateway"] = each_wallet_trasaction.paymentGatewayId.sourceName
        # else:
        #     wallet_transaction_dict["paymentGatewayId"] = ""
        #     wallet_transaction_dict["paymentGateway"] = ""

        # if each_wallet_trasaction.settlementPayId:
        #     wallet_transaction_dict["settlementPayId"] = str(each_wallet_trasaction.settlementPayId.id)
        #     wallet_transaction_dict["settlementPayId"] = each_wallet_trasaction.settlementPayId.settlementType
        # else:
        #     wallet_transaction_dict["settlementPayId"] = ""
        #     wallet_transaction_dict["settlementPay"] = ""

    except Exception as e:
        app.logger.error(traceback.format_exc())
    return wallet_transaction_dict

#Add Wallet Money API 
@users.route("/get_wallet_transactions",methods=["POST"])
@encrypt_decrypt_after_login
def get_wallet_transactions():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        startDate = data.get("startDate","")
        endDate = data.get("endDate","")
        walletTransactionsList = []
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId:
        if startDate and endDate:
            startDate = startDate + " 00:00:00"
            endDate = endDate + " 23:59:59"
            start_date = datetime.datetime.strptime(startDate, "%m-%d-%Y %H:%M:%S")
            end_date = datetime.datetime.strptime(endDate, "%m-%d-%Y %H:%M:%S")
            wallet_transactions_queryset = WalletTransactions.objects(
                userId=userId,
                createdOn__gte=start_date,
                createdOn__lte=end_date,
                ).order_by("-id").all()
        else:
            wallet_transactions_queryset = WalletTransactions.objects(
                userId=userId,
                ).order_by("-id").all()
        try:
            for each_wallet_trasaction in wallet_transactions_queryset:
                wallet_transaction_data = fetching_wallet_transaction_reports(each_wallet_trasaction)
                walletTransactionsList.append(wallet_transaction_data)
            data_status["responseStatus"] = 1
            data_status["result"] = "Wallet reports fetched successfully"
            data_status["walletTransactionsList"] = walletTransactionsList
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fethc wallets data"
            return data_status
    else:
        data_status["result"] = "Required fields are missing"
        return data_status

#Add Wallet Money API 
@users.route("/get_wallet_single_transaction",methods=["POST"])
@encrypt_decrypt_after_login
def get_wallet_single_transaction():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        walletTransactionId = data.get("walletTransactionId")
        wallet_transaction_dict = {}
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    if walletTransactionId:
        each_wallet_trasaction = WalletTransactions.objects(
                id=walletTransactionId,
                ).order_by("-id").first()
        try:
            wallet_transaction_dict = {
                "id":str(each_wallet_trasaction.id),
                "amount":each_wallet_trasaction.amount,
                "paymentType":each_wallet_trasaction.paymentType,
                "creditType":each_wallet_trasaction.creditType,
                "transactionId":each_wallet_trasaction.transactionId,
                }

            data_status["responseStatus"] = 1
            data_status["result"] = "Wallet reports fetched successfully"
            data_status["walletTransactionData"] = wallet_transaction_dict
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fethc wallets data"
            return data_status
    else:
        data_status["result"] = "Required fields are missing"
        return data_status



########### Transactions API's ##########

# @users.route("/add_transaction",methods=["POST"])
# def add_transaction():
#     data_status = {"responseStatus": 0, "result": ""}
#     print(request.json,"add_transaction")
#     userId = request.json.get("userId","")
#     categoryId = request.json.get("categoryId",None)
#     serviceId = request.json.get("serviceId",None)
#     operatorId = request.json.get("operatorId",None)
#     transactionAPIId = request.json.get("transactionAPIId",None)
#     paymentType = request.json.get("paymentType","")
#     transactionId = request.json.get("transactionId","")
#     transactionData = request.json.get("transactionData")
#     mobileNumber = request.json.get("mobileNumber","")
#     categoryName = request.json.get("categoryName","")
#     serviceName = request.json.get("serviceName","")
#     operatorName = request.json.get("operatorName","")
#     amount = request.json.get("amount")
#     operatorReference = request.json.get("operatorReference","")
#     paymentGatewayId = request.json.get("paymentGatewayId",None)
#     status = request.json.get("status")

#     transactionData = [transactionData]
#     if categoryName and serviceName and operatorName and transactionId and mobileNumber and amount:
#         try:
#             user_queryset = Users.objects(id=userId,status=1).first()
#             if not user_queryset:
#                 data_status["result"] = "Invalid user Id"
#                 return data_status
#             commissionCharges = {}
#             chargeAmount = 0.0
#             if user_queryset.commissionId:
#                 commissionId = str(user_queryset.commissionId.id)
#                 commissions_queryset = Commissions.objects(id=commissionId,status=1).order_by("-id").first()
#                 for each_record in commissions_queryset.commissionList:
#                     if each_record.get("operatorId") == operatorId and each_record.get("transactionAPIId") == transactionAPIId:
#                         commissionDict = {
#                         # "operatorId": each_record.get("operatorId"),
#                         # "transactionAPIId": each_record.get("transactionAPIId"),
#                         "chargeType": each_record.get("chargeType"),
#                         "chargeValue": each_record.get("chargeValue"),
#                         "commissionType": each_record.get("commissionType"),
#                         "commissionValue": each_record.get("commissionValue")
#                         }

#                         if commissionDict.get("chargeType") == "Percentage":
#                             chargeAmount = (float(amount)*float(commissionDict.get("chargeValue")))/100
#                         elif commissionDict.get("chargeType") == "Fixed":
#                             chargeAmount = float(commissionDict.get("chargeValue"))
#                         if commissionType.get("commissionType") == "Percentage":
#                             commissionAmount = (float(amount)*float(commissionDict.get("commissionValue")))/100
#                         elif commissionDict.get("commissionType") == "Fixed":
#                             commissionAmount = float(commissionDict.get("commissionValue"))
                        
#                         #Updating user commission balance
#                         if commissionAmount:
#                             commissionBalance = user_queryset.commissionBalance
#                             commissionBalance += commissionAmount
#                             user_queryset.update(commissionBalance=commissionBalance)
                        
#                         commissionCharges = {
#                         "chargeType": commissionDict.get("chargeType"),
#                         "chargeValue": commissionDict.get("chargeValue"),
#                         "commissionType": commissionDict.get("commissionType"),
#                         "commissionValue": commissionDict.get("commissionValue"),
#                         "chargeAmount": chargeAmount,
#                         "commissionAmount": commissionAmount
#                         }
#                         operator_queryset = Operators.objects(id=operatorId).first()
#                         user_commission_table = UserCommissions(
#                             userId = userId,
#                             childUserId =None,
#                             operatorId = operatorId,
#                             serviceId = str(operator_queryset.serviceId.id),
#                             transactionId = transactionId,
#                             transactionAPIId = transactionAPIId,
#                             totalAmount = amount,
#                             commissionType = commissionDict.get("chargeType"),
#                             commissionAmount = commissionAmount,
#                             createdOn = datetime.datetime.now(),
#                             status = 1,
#                             ).save()
#             #Calulate total amount
#             totalAmount = float(amount) - chargeAmount
#             transaction_table = Transactions(
#                 userId = userId,
#                 categoryId = categoryId,
#                 serviceId = serviceId,
#                 operatorId = operatorId,
#                 categoryName = categoryName,
#                 serviceName = serviceName,
#                 operatorName = operatorName,
#                 paymentType  = paymentType,
#                 paymentGatewayId = paymentGatewayId,
#                 transactionAPIId = transactionAPIId,
#                 transactionId = str(transactionId),
#                 transactionData = transactionData,
#                 mobileNumber = mobileNumber,
#                 amount = amount,
#                 totalAmount = totalAmount,
#                 commissionCharges = commissionCharges,
#                 operatorReference = operatorReference,
#                 createdOn = datetime.datetime.now(),
#                 status = status
#                 ).save()
#             transactionTableId = str(transaction_table.id)
#             # if transactionTableId:
#                 # user_parent_method_commission_charges_details(userId,amount,operatorId,transactionAPIId,transactionId)
#                 # service_queryset = Service.objects(id=serviceId,status=1).first()
#                 # if service_queryset:
#                 #     serviceName = service_queryset.serviceName
#                 # else:
#                 #     serviceName = ""

#                 # if status in [1,2]:
#                 #   currentBalance = user_queryset.walletBalance
#                 #   updateBalance = float(currentBalance)-float(amount)
#                 #   user_queryset.update(walletBalance = updateBalance)

#                 #   #Here we need update this transaction to wallet also
#                 #   wallet_trasaction_table = WalletTransactions(
#                 #       userId = userId,
#                 #       amount =amount,
#                 #       paymentGatewayId = paymentGatewayId,
#                 #       creditType = "debit",
#                 #       transactionId = str(transactionId),
#                 #       paymentType = paymentType,
#                 #       # settlementPayId = None,
#                 #       walletLog = serviceName + " " + str(mobileNumber) + " is recharged with the amount of " + str(int(amount)) + ".",
#                 #       userType = "user",
#                 #       createdBy = None,
#                 #       createdOn = datetime.datetime.now(),
#                 #       status = 1,
#                 #       ).save()
#                 # except Exception as e:
#                 #     app.logger.error(traceback.format_exc())
#                 #     data_status["result"] = "Unable to make transaction"
#                 #     return data_status
#             if status:
#                 data_status["responseStatus"] = status
#                 data_status["id"] = transactionTableId
#                 data_status["result"] = "Transaction successful"
#                 # data_status["transactionId"] = transactionTableId
#                 return data_status
#             else:
#                 data_status["responseStatus"] = status
#                 data_status["id"] = transactionTableId
#                 data_status["result"] = "Transaction unsuccessful"
#                 return data_status
#         except Exception as e:
#             app.logger.error(traceback.format_exc())
#             data_status["result"] = "Unable to make transaction"
#             return data_status
#     else:
#         data_status['result'] = "Required fields are missing"
#         return data_status

@users.route("/add_transaction",methods=["POST"])
@encrypt_decrypt_after_login
def add_transaction():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        print(data,"add_transaction")
        userId = data.get("userId","")
        categoryId = data.get("categoryId",None)
        serviceId = data.get("serviceId",None)
        operatorId = data.get("operatorId",None)
        transactionAPIId = data.get("transactionAPIId",None)
        paymentType = data.get("paymentType","")
        transactionId = data.get("transactionId","")
        transactionData = data.get("transactionData")
        billPayment = data.get("billPayment",0)
        payload = data.get("payload",'')
        headers = data.get("headers",'')
        mobileNumber = data.get("mobileNumber","")
        categoryName = data.get("categoryName","")
        serviceName = data.get("serviceName","")
        operatorName = data.get("operatorName","")
        amount = data.get("amount")
        operatorReference = data.get("operatorReference","")
        errorMessage = data.get("errorMessage","")
        paymentGatewayId = data.get("paymentGatewayId",None)
        status = data.get("status")
        paymentCategory = data.get("paymentCategory","")
        cardNumber = data.get("cardNumber","")
        customerVpa = data.get("customerVpa","")
        walletName = data.get("walletName","")
        accountNumber = data.get("accountNumber","")
        ifscCode = data.get("ifscCode","")
        customeParamsList = data.get("customeParamsList",{})
        # transactionData=json.loads(transactionData)
        transactionData = [transactionData]
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if categoryName and serviceName and operatorName and transactionId and mobileNumber and amount and operatorId and transactionAPIId:
        try:
            user_queryset = Users.objects(id=userId,status=1).only("id").first()
            if not user_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status
            commissionCharges = {}
            chargeAmount = 0.0
            commissionDictResult=operator_based_commission_details(userId,operatorId,transactionAPIId)
            if commissionDictResult.get('responseStatus')==1:
                commissionDict=commissionDictResult.get('commissionDict')
                if commissionDict:
                    if commissionDict.get("chargeType") == "Percentage":
                        chargeAmount = (float(amount)*float(commissionDict.get("chargeValue")))/100
                    elif commissionDict.get("chargeType") == "Fixed":
                        chargeAmount = float(commissionDict.get("chargeValue"))
                    if commissionDict.get("commissionType") == "Percentage":
                        commissionAmount = (float(amount)*float(commissionDict.get("commissionValue")))/100
                    elif commissionDict.get("commissionType") == "Fixed":
                        commissionAmount = float(commissionDict.get("commissionValue"))
                        
                        commissionCharges = {
                        "chargeType": commissionDict.get("chargeType"),
                        "chargeValue": commissionDict.get("chargeValue"),
                        "commissionType": commissionDict.get("commissionType"),
                        "commissionValue": commissionDict.get("commissionValue"),
                        "chargeAmount": chargeAmount,
                        "commissionAmount": commissionAmount
                        }
                        
            #Calulate total amount
            billPaymentRequestData=[]
            billPaymentResponseData=[]
            totalAmount = float(amount) - float(chargeAmount)
            transaction_table = Transactions(
                userId = userId,
                categoryId = categoryId,
                serviceId = serviceId,
                operatorId = operatorId,
                categoryName = categoryName,
                serviceName = serviceName,
                operatorName = operatorName,
                paymentType  = paymentType,
                paymentCategory  = paymentCategory,
                cardNumber  = cardNumber,
                customerVpa  = customerVpa,
                walletName  = walletName,
                accountNumber  = accountNumber,
                ifscCode  = ifscCode,
                customeParamsList  = customeParamsList,
                paymentGatewayId = paymentGatewayId,
                transactionAPIId = transactionAPIId,
                transactionId = str(transactionId),
                transactionData = transactionData,
                billPayment = str(billPayment),
                billPaymentRequestData = billPaymentRequestData,
                billPaymentResponseData = billPaymentResponseData,
                mobileNumber = mobileNumber,
                amount = amount,
                totalAmount = totalAmount,
                commissionCharges = commissionCharges,
                operatorReference = operatorReference,
                createdOn = datetime.datetime.now(),
                errorMessage=errorMessage,
                status = status
                ).save()
            transactionTableId = str(transaction_table.id)
            if transactionTableId:
                if status==1 and billPayment==1:
                    billPaymentRequestData.append(payload)
                    billPaymentRequestData.append(headers)
                    billpaymentresult=payuBillPayment(payload,headers)
                    if billpaymentresult.get('responseStatus')==1:
                        billpaymentresponse=billpaymentresult.get('result')
                        billPaymentResponseData.append(billpaymentresponse)
                        bbpsoperatorReference=billpaymentresponse.get('payload').get('additionalParams').get('txnReferenceId')
                        if billpaymentresponse.get('status')=="SUCCESS":
                            status=1
                            errorMessage=billpaymentresponse.get('status')

                        elif billpaymentresponse.get('status')=="FAILURE":
                            status=0
                            errorMessage="Payment Failed. if amount debited from your account it will be refund."
                        transaction_table.update(billPaymentRequestData=billPaymentRequestData,billPaymentResponseData=billPaymentResponseData,operatorReference=bbpsoperatorReference,errorMessage=errorMessage,status=status)
                if status:
                    data_status["responseStatus"] = status
                    data_status["id"] = transactionTableId
                    data_status["result"] = "Transaction successful"
                    # data_status["transactionId"] = transactionTableId
                    return data_status
                else:
                    data_status["responseStatus"] = status
                    data_status["id"] = transactionTableId
                    data_status["result"] = "Transaction unsuccessful"
                    return data_status
            else:
                data_status["id"] = ""
                data_status["result"] = "Transaction unsuccessful"
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to make transaction"
            return data_status
    else:
        data_status['result'] = "Required fields are missing"
        return data_status

def user_parent_method_commission_charges_details(userId,amount,operatorId,transactionAPIId,transactionId):
    try:
        user_queryset = Users.objects(id=userId).first()
        commissionCharges = {}
        childcommissionDict = {}
        parentcommissionDict = {}
        chargeAmount = 0.0
        if user_queryset.commissionId:
            childcommissionId = str(user_queryset.commissionId.id)
            childcommissions_queryset = Commissions.objects(id=childcommissionId,status=1).order_by("-id").first()
            for childeach_record in childcommissions_queryset.commissionList:
                if childeach_record.get("operatorId") == operatorId and childeach_record.get("transactionAPIId") == transactionAPIId:
                    childcommissionDict = {
                    "chargeType": childeach_record.get("chargeType"),
                    "chargeValue": childeach_record.get("chargeValue"),
                    "commissionType": childeach_record.get("commissionType"),
                    "commissionValue": childeach_record.get("commissionValue")
                    }

            if user_queryset.parentId:
                parent_queryset = Users.objects(id=user_queryset.parentId).first()
                if parent_queryset.commissionId:
                    parentcommissionId = str(parent_queryset.commissionId.id)
                    parentcommissions_queryset = Commissions.objects(id=parentcommissionId,status=1).order_by("-id").first()
                    for parenteach_record in parentcommissions_queryset.commissionList:
                        if parenteach_record.get("operatorId") == operatorId and parenteach_record.get("transactionAPIId") == transactionAPIId:
                            parentcommissionDict = {
                            "chargeType": parenteach_record.get("chargeType"),
                            "chargeValue": parenteach_record.get("chargeValue"),
                            "commissionType": parenteach_record.get("commissionType"),
                            "commissionValue": parenteach_record.get("commissionValue")
                            }

                    if parentcommissionDict.get("chargeType") == "Percentage":
                        parentchargeAmount = (float(amount)*float(parentcommissionDict.get("chargeValue")))/100
                    elif parentcommissionDict.get("chargeType") == "Fixed":
                        parentchargeAmount = float(parentcommissionDict.get("chargeValue"))

                    if childcommissionDict.get("chargeType") == "Percentage":
                        childchargeAmount = (float(amount)*float(childcommissionDict.get("chargeValue")))/100
                    elif childcommissionDict.get("chargeType") == "Fixed":
                        childchargeAmount = float(childcommissionDict.get("chargeValue"))
                    parentcommissionamount=childchargeAmount-parentchargeAmount

                    operator_queryset = Operators.objects(id=operatorId).first()
                    if parentcommissionamount:
                        user_commission_table = UserCommissions(
                            userId = str(parent_queryset.id),
                            childUserId =userId,
                            operatorId = operatorId,
                            serviceId = str(operator_queryset.serviceId.id),
                            transactionId = transactionId,
                            transactionAPIId = transactionAPIId,
                            totalAmount = amount,
                            commissionType = parentcommissionDict.get("chargeType"),
                            commissionAmount = parentcommissionamount,
                            createdOn = datetime.datetime.now(),
                            status = 1,
                            ).save()
                        commissionBalance = parent_queryset.commissionBalance
                        commissionBalance += parentcommissionamount
                        parent_queryset.update(commissionBalance=commissionBalance)

                user_parent_method_commission_charges_details(str(parent_queryset.id),amount,operatorId,transactionAPIId,transactionId)
            else:
                False

    except Exception as e:
        app.logger.error(traceback.format_exc())
        return False


def fetching_transaction_data(each_transaction):
    transaction_data = {}
    try:
        transaction_data = {
        "id":str(each_transaction.id),
        "categoryName":each_transaction.categoryName,
        "serviceName":each_transaction.serviceName,
        "operatorName":each_transaction.operatorName,
        "transactionId":each_transaction.transactionId,
        "mobileNumber":each_transaction.mobileNumber,
        "amount":each_transaction.amount,
        "operatorReference":each_transaction.operatorReference
        }
        if each_transaction.ifscCode:
            transaction_data["ifscCode"] = each_transaction.ifscCode
        else:
            transaction_data["ifscCode"] = ""
        if each_transaction.accountNumber:
            transaction_data["accountNumber"] = each_transaction.accountNumber
        else:
            transaction_data["accountNumber"] = ""

        if each_transaction.paymentCategory:
            transaction_data["paymentCategory"] = each_transaction.paymentCategory
        else:
            transaction_data["paymentCategory"] = ""

        if each_transaction.cardNumber:
            transaction_data["cardNumber"] = each_transaction.cardNumber
        else:
            transaction_data["cardNumber"] = ""

        if each_transaction.customerVpa:
            transaction_data["customerVpa"] = each_transaction.customerVpa
        else:
            transaction_data["customerVpa"] = ""
        if each_transaction.customeParamsList:
            transaction_data["customeParamsList"] = each_transaction.customeParamsList
        else:
            transaction_data["customeParamsList"] = {}

        if each_transaction.walletName:
            transaction_data["walletName"] = each_transaction.walletName
        else:
            transaction_data["walletName"] = ""
            
        if each_transaction.createdOn:
            # ist_time=each_transaction.createdOn.replace(tzinfo=pytz.utc).astimezone(ist_timezone)
            transaction_data["createdOn"] = each_transaction.createdOn.strftime("%m-%d-%Y %I:%M %p")
        else:
            transaction_data["createdOn"]=""
        try:
            if each_transaction.categoryId:
                transaction_data["categoryId"] = str(each_transaction.categoryId.id)
                transaction_data["categoryName"] = each_transaction.categoryId.categoryName
            else:
                transaction_data["categoryId"] = ""
                transaction_data["categoryName"] = ""
        except:
            transaction_data["categoryId"] = ""
            transaction_data["categoryName"] = ""

        try:
            if each_transaction.serviceId:
                transaction_data["serviceId"] = str(each_transaction.serviceId.id)
                transaction_data["serviceName"] = each_transaction.serviceId.serviceName
            else:
                transaction_data["serviceId"] = ""
                transaction_data["serviceName"] = ""
        except:
            transaction_data["serviceId"] = ""
            transaction_data["serviceName"] = ""

        try:
            if each_transaction.operatorId:
                transaction_data["operatorId"] = str(each_transaction.operatorId.id)
                transaction_data["operatorName"] = each_transaction.operatorId.operatorName
            else:
                transaction_data["operatorId"] = ""
                transaction_data["operatorName"] = ""
        except:
            transaction_data["operatorId"] = ""
            transaction_data["operatorName"] = ""

        if each_transaction.status == 1:
            transaction_data["status"] = "successful"
        elif each_transaction.status == 0:
            transaction_data["status"] = "failed"
        else:
            transaction_data["status"] = "pending"
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return transaction_data

#Get all transactions
@users.route("/get_all_transactions",methods=["POST"])
@encrypt_decrypt_after_login
def get_all_transactions():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        startDate = data.get("startDate","")
        endDate = data.get("endDate","")
        transactionsList = []
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId:

        if startDate and endDate:
            startDate = startDate + " 00:00:00"
            endDate = endDate + " 23:59:59"
            start_date = datetime.datetime.strptime(startDate, "%d-%m-%Y %H:%M:%S")
            end_date = datetime.datetime.strptime(endDate, "%d-%m-%Y %H:%M:%S")
            transactions_queryset = Transactions.objects(
                userId=userId,
                createdOn__gte=start_date,
                createdOn__lte=end_date,
                ).order_by("-id").all()
        else:
            transactions_queryset = Transactions.objects(
                userId=userId,
                ).order_by("-id").all()
        
        for each_transaction in transactions_queryset:
            transaction_data = fetching_transaction_data(each_transaction)
            transactionsList.append(transaction_data)

        data_status["result"] = "Transaction details fetched successfully"
        data_status["responseStatus"] = 1
        data_status["transactionsList"] = transactionsList
        return data_status
    else:
        data_status["result"] = "Required fields are missing"
        return data_status


@users.route("/view_single_transaction",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def view_single_transaction():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        transactionId = data.get("transactionId","")
        transactionDict = {}
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId and transactionId:
        transaction_queryset = Transactions.objects(id=transactionId,userId=userId).first()
        if not transaction_queryset:
            data_status["result"]="Invalid transaction id!!"
            return data_status
        
        transactionDict = fetching_transaction_data(transaction_queryset)

        data_status["result"] = "Transaction details fetched successfully"
        data_status["responseStatus"] = 1
        data_status["transactionDict"] = transactionDict
        return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status


#Get single transactions
@users.route("/get_single_transaction",methods=["POST"])
@encrypt_decrypt_after_login
def get_single_transaction():
    data_status = {"responseStatus": 0, "result": "",}
    try:
        data = request.decrypted_data
        transactionId = data.get("transactionId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    if transactionId:
        try:
            transaction_data = {}
            each_transaction = Transactions.objects(id=transactionId).order_by('-id').first()
            if each_transaction:
                transaction_data = {
                "id":str(each_transaction.id),
                "categoryName":each_transaction.categoryName,
                "serviceName":each_transaction.serviceName,
                "operatorName":each_transaction.operatorName,
                "mobileNumber":each_transaction.mobileNumber,
                "amount":each_transaction.amount,
                "commissionCharges":each_transaction.commissionCharges,
                "customeParamsList":each_transaction.customeParamsList,
                "status":each_transaction.status
                }
                if each_transaction.createdOn:
                    # ist_time=each_transaction.createdOn.replace(tzinfo=pytz.utc).astimezone(ist_timezone)
                    transaction_data["createdOn"] = each_transaction.createdOn.strftime("%m-%d-%Y %I:%M %p")
                else:
                    transaction_data["createdOn"] = ""

                payment_details = {}
                payment_details["transactionId"] = each_transaction.transactionId
                if each_transaction.operatorReference:
                    payment_details["operatorReference"] = each_transaction.operatorReference.strip()
                else:
                    payment_details["operatorReference"] = ""

                if each_transaction.paymentType:
                    payment_details["debitedFrom"] = each_transaction.paymentType
                else:
                    payment_details["debitedFrom"] = ""

                if not each_transaction.paymentType:
                    wallet_transaction = WalletTransactions.objects(transactionId=each_transaction.transactionId).order_by('-id').first()
                    if wallet_transaction:
                        payment_details["debitedFrom"] = wallet_transaction.paymentType
                    else:
                        payment_details["debitedFrom"] = ""

                transaction_data["paymentDetails"] = payment_details

                transaction_data["accountHolderName"] = ""

                try:
                    if each_transaction.operatorId.image:
                        transaction_data["image"] = domain+each_transaction.operatorId.image
                    else:
                        transaction_data["image"] = ""
                except:
                    transaction_data["image"] = ""

                # if each_transaction.status == 1:
                #     transaction_data["status"] = "Successful"
                # elif each_transaction.status == 0:
                #     transaction_data["status"] = "Failed"
                # else:
                #     transaction_data["status"] = "Pending"

                if each_transaction.ifscCode:
                    transaction_data["ifscCode"] = each_transaction.ifscCode
                else:
                    transaction_data["ifscCode"] = ""
                if each_transaction.accountNumber:
                    transaction_data["accountNumber"] = each_transaction.accountNumber
                elif each_transaction.cardNumber:
                    transaction_data["accountNumber"] = each_transaction.cardNumber
                elif each_transaction.customerVpa:
                    transaction_data["accountNumber"] = each_transaction.customerVpa
                else:
                    transaction_data["accountNumber"] = ""
            data_status["result"] = "Transaction details fetched successfully"
            data_status["responseStatus"] = 1
            data_status["transactionData"] = transaction_data
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fetch transaction details"
            return data_status 
    else:
        data_status["result"] = "Required field is missing"
        return data_status



# #Get single transactions
# @users.route("/get_single_transaction",methods=["POST"])
# def get_single_transaction():
#     data_status = {"responseStatus": 0, "result": ""}
#     transactionId = request.json.get("transactionId","")

#     if transactionId:

#         each_transaction = Transactions.objects(id=transactionId).order_by('-id').first()

#         transaction_data = {
#         "id":str(each_transaction.id),
#         "categoryName":each_transaction.categoryName,
#         "serviceName":each_transaction.serviceName,
#         "operatorName":each_transaction.operatorName,
#         "transactionId":each_transaction.transactionId,
#         "mobileNumber":each_transaction.mobileNumber,
#         "amount":each_transaction.amount,
#         "operatorReference":each_transaction.operatorReference,
#         }
#         if each_transaction.ifscCode:
#             transaction_data["ifscCode"] = each_transaction.ifscCode
#         else:
#             transaction_data["ifscCode"] = ""
#         if each_transaction.accountNumber:
#             transaction_data["accountNumber"] = each_transaction.accountNumber
#         else:
#             transaction_data["accountNumber"] = ""
            
#         if each_transaction.createdOn:
#             ist_time=each_transaction.createdOn.replace(tzinfo=pytz.utc).astimezone(ist_timezone)
#             transaction_data["createdOn"] = ist_time.strftime("%m-%d-%Y %I:%M %p")
#         try:
#             if each_transaction.categoryId:
#                 transaction_data["categoryId"] = str(each_transaction.categoryId.id)
#                 transaction_data["categoryName"] = each_transaction.categoryId.categoryName
#             else:
#                 transaction_data["categoryId"] = ""
#                 # transaction_data["categoryName"] = ""
#         except:
#             transaction_data["categoryId"] = ""

#         try:
#             if each_transaction.serviceId:
#                 transaction_data["serviceId"] = str(each_transaction.serviceId.id)
#                 transaction_data["serviceName"] = each_transaction.serviceId.serviceName
#             else:
#                 transaction_data["serviceId"] = ""
#                 # transaction_data["serviceName"] = ""
#         except:
#             transaction_data["serviceId"] = ""

#         try:
#             if each_transaction.operatorId:
#                 transaction_data["operatorId"] = str(each_transaction.operatorId.id)
#                 transaction_data["operatorName"] = each_transaction.operatorId.operatorName
#             else:
#                 transaction_data["operatorId"] = ""
#                 # transaction_data["operatorName"] = ""
#         except:
#             transaction_data["operatorId"] = ""


#         if each_transaction.status == 1:
#             transaction_data["status"] = "successful"
#         elif each_transaction.status == 0:
#             transaction_data["status"] = "failed"
#         else:
#             transaction_data["status"] = "pending"

#         data_status["result"] = "Transaction details fetched successfully"
#         data_status["responseStatus"] = 1
#         data_status["transactionData"] = transaction_data
#         return data_status
#     else:
#         data_status["result"] = "Required fields are missing"
#         return data_status


#Add Profile Picture
@users.route("/add_profile_picture",methods=["POST"])
@encrypt_decrypt_after_login
def add_profile_picture():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        profilePicture = data.get("profilePicture","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request."
        return data_status

    if userId and profilePicture:
        try:
            user_queryset = Users.objects(id=userId,status__nin=[2]).only("profilePicture","id").first()
            if not user_queryset:
                data_status["result"] = "Invalid user id"
                return data_status

            profile = upload_file_image(profilePicture, "userProfiles", str(get_epoch_milli_time()), "")
            if profile:
                user_queryset.update(profilePicture=profile)


            data_status["responseStatus"] = 1
            data_status["result"] = "Profile picture added successfully"
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to add profile picture"
            return data_status
    else:
        data_status["result"] = "Required fields are missing"
        return data_status

########### Internal Transfer API ##########

@users.route("/add_internal_transfer",methods=["POST"])
@encrypt_decrypt_after_login
def add_internal_transfer():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        paymentType = data.get("paymentType","")
        transactionId = data.get("transactionId","")
        mobileNumber = data.get("mobileNumber","")
        amount = data.get("amount")
        remarks = data.get("remarks")
        paymentGatewayId = data.get("paymentGatewayId",None)
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if transactionId and mobileNumber and amount and remarks and userId:
        try:
            user_queryset = Users.objects(id=userId,status=1).only("fullName","phoneNumber","walletBalance").first()
            if not user_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status
            otheruser_queryset = Users.objects(phoneNumber=mobileNumber,status=1).only("id","fullName","walletBalance").first()
            if not otheruser_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status
            currentBalance = user_queryset.walletBalance
            updateBalance = float(currentBalance)-float(amount)
            user_queryset.update(walletBalance = updateBalance)

            #Here we need update this transaction to wallet also
            wallet_trasaction_table = WalletTransactions(
                userId = userId,
                amount =amount,
                paymentGatewayId = paymentGatewayId,
                creditType = "debit",
                transactionId = transactionId,
                paymentType = paymentType,
                settlementPayId = None,
                walletLog = str(int(amount)) + " is transferd to " + otheruser_queryset.fullName + " (" + str(mobileNumber)+ ")",
                remarks = remarks,
                userType = "user",
                createdBy = None,
                createdOn = datetime.datetime.now(),
                status = 1,
                ).save()

            othercurrentBalance = otheruser_queryset.walletBalance
            otherupdateBalance = float(othercurrentBalance)+float(amount)
            otheruser_queryset.update(walletBalance = otherupdateBalance)

            #Here we need update this transaction to wallet also
            wallet_trasaction_table1 = WalletTransactions(
                userId = str(otheruser_queryset.id),
                amount =amount,
                paymentGatewayId = paymentGatewayId,
                creditType = "credit",
                transactionId = transactionId,
                paymentType = paymentType,
                settlementPayId = None,
                walletLog = str(int(amount)) + " is transferd from " + user_queryset.fullName + " (" + str(user_queryset.phoneNumber)+ ")",
                remarks = remarks,
                userType = "user",
                createdBy = None,
                createdOn = datetime.datetime.now(),
                status = 1,
                ).save()
            wtransactionId = str(wallet_trasaction_table1.id)
            if wtransactionId:
                data_status["responseStatus"] = 1
                data_status["result"] = "Transaction successful"
                data_status["transactionId"] = wtransactionId
                return data_status
            else:
                data_status["responseStatus"] = 0
                data_status["result"] = "Transaction transfered failed."
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Transaction unsuccessful"
            return data_status
    else:
        data_status['result'] = "Required fields are missing"
        return data_status


########### User Mobile Number Verify API ##########

@users.route("/user_mobileNumber_verify",methods=["POST"])
@encrypt_decrypt_before_login
def user_mobileNumber_verify():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        mobileNumber = data.get("mobileNumber","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId and mobileNumber:
        try:
            user_queryset = Users.objects(id=userId,status=1).only("id").first()
            if not user_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status
            otheruser_queryset = Users.objects(phoneNumber=mobileNumber,status=1).only("id").first()
            if not otheruser_queryset:
                data_status["result"] = "Invalid Mobile Number"
                return data_status
            else:
                data_status["responseStatus"] = 1
                data_status["result"] = "Mobile Number Valid."
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Transaction unsuccessful"
            return data_status
    else:
        data_status['result'] = "Required fields are missing"
        return data_status

@users.route("/user_upload_video",methods=["POST"])
@encrypt_decrypt_after_login
def user_upload_video():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        uploadVideo = request.files.get("uploadVideo","")
        videoVerificationStatus = data.get("videoVerificationStatus","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    print(uploadVideo,"(((((((((((uploadVideo)))))))))))")

    if not userId:
        data_status["result"] = "Required fields are missing!!"
        return data_status
    try:
        user_queryset = Users.objects(id=userId,status=1).only("id").first()
        if not user_queryset:
            data_status["result"]="Invalid user id!!"
            return data_status

        user_kyc_queryset = UserKYC.objects(userId=str(user_queryset.id)).only("uploadVideo","videoVerificationStatus","submittedDate").first()
        if user_kyc_queryset:
            if uploadVideo:
                video_file = upload_file_video("uploadKYCVideos", userId, ".mp4", uploadVideo)
                print(video_file,"(((((((((((((video_file)))))))))))))")
                if video_file:
                    user_kyc_queryset.update(
                        uploadVideo=video_file,
                        videoVerificationStatus="Submitted",
                        submittedDate=datetime.datetime.now()
                        )

        data_status["responseStatus"] = 1
        data_status["result"] = "Video uploaded successfully!"
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to upload video!!"
        return data_status

# @users.route("/operator_grouping_based_operator_parameters_list",methods=["POST"])
# def operator_grouping_based_operator_parameters_list():
#     data_status = {"responseStatus": 0, "result": ""}
#     operatorGroupingsList = []
#     try:
#         operator_grouping_queryset = OperatorGrouping.objects(status=1).order_by('-id').all()
#         for each_operator_grouping in operator_grouping_queryset:
#             operator_grouping_data = {
#             "id":str(each_operator_grouping.id),
#             "groupName":each_operator_grouping.groupName,
#             "value":each_operator_grouping.value,
#             }
#             operatorParametersList = []
#             if each_operator_grouping.operatorParameterId:
#                 operator_parameters_queryset = OperatorParameter.objects(
#                     id=str(each_operator_grouping.operatorParameterId.id),
#                     status=1
#                     ).order_by("-id").all()
#                 for each_operator_parameter in operator_parameters_queryset:
#                     operator_parameter_dict = fetching_operator_parameter_details(each_operator_parameter)
#                     operatorParametersList.append(operator_parameter_dict)
#             operator_grouping_data["operatorParametersList"] = operatorParametersList
#             operatorGroupingsList.append(operator_grouping_data)
#         data_status["responseStatus"] = 1
#         data_status["result"] = "Operator grouping based operator parameters data fetched successfully!"
#         data_status["operatorGroupingsList"] = operatorGroupingsList
#         return data_status
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         data_status["result"] = "Unable to fetch operator parameters data!!"
#         return data_status



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

# @users.route("/get_single_transaction1111", methods=["POST"])
# def get_single_transaction1111():
#     data_status = {"responseStatus": 0, "result": "", "transactionData": {}}
#     transaction_id = request.json.get("transactionId", "")

#     if not transaction_id:
#         data_status["result"] = "Required field 'transactionId' is missing"
#         return jsonify(data_status)

#     try:
#         each_transaction = Transactions.objects(id=transaction_id).order_by('-id').first()

#         if not each_transaction:
#             data_status["result"] = "Transaction not found"
#             return jsonify(data_status)

#         transaction_data = format_transaction_data(each_transaction)
#         data_status["result"] = "Transaction details fetched successfully"
#         data_status["responseStatus"] = 1
#         data_status["transactionData"] = transaction_data
#         return jsonify(data_status)

#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         data_status["result"] = "Unable to fetch transaction details"
#         return jsonify(data_status)


# def format_transaction_data(transaction):
#     transaction_data = {
#         "id": str(transaction.id),
#         "categoryName": transaction.categoryName,
#         "serviceName": transaction.serviceName,
#         "operatorName": transaction.operatorName,
#         "mobileNumber": transaction.mobileNumber,
#         "amount": transaction.amount,
#         "createdOn": format_created_on(transaction.createdOn),
#         "paymentDetails": format_payment_details(transaction),
#         "accountHolderName": transaction.accountHolderName if transaction.categoryName == "Payout" else "",
#         "image": domain + transaction.image if hasattr(transaction, 'image') and transaction.image else "",
#         "status": format_transaction_status(transaction.status),
#     }

#     return transaction_data


# def format_created_on(created_on):
#     if created_on:
#         ist_time = created_on.replace(tzinfo=pytz.utc).astimezone(ist_timezone)
#         return ist_time.strftime("%m-%d-%Y %I:%M %p")
#     return ""


# def format_payment_details(transaction):
#     payment_details = {"transactionId": transaction.transactionId}

#     if transaction.operatorReference:
#         payment_details["operatorReference"] = transaction.operatorReference.strip()
#     else:
#         payment_details["operatorReference"] = ""

#     if transaction.paymentType:
#         payment_details["debitedFrom"] = transaction.paymentType
#     else:
#         wallet_transaction = WalletTransactions.objects(transactionId=transaction.transactionId).order_by('-id').first()
#         payment_details["debitedFrom"] = wallet_transaction.paymentType if wallet_transaction else ""

#     return payment_details


# def format_transaction_status(status):
#     if status == 1:
#         return "Successful"
#     elif status == 0:
#         return "Failed"
#     else:
#         return "Pending"



@users.route("/add_remitter_beneficiaries",methods=["POST"])
@encrypt_decrypt_after_login
def add_remitter_beneficiaries():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        firstName = data.get("firstName","")
        lastName = data.get("lastName","")
        phoneNumber = data.get("phoneNumber","")
        pincode = data.get("pincode","")
        moneyArtRemitterId = data.get("moneyArtRemitterId","")
        monthlyLimit = data.get("monthlyLimit","")
        availableBalance = data.get("availableBalance","")
        recipientsList = data.get("recipientsList",[])
        print(recipientsList)
        print("((((((((((((((recipientsList))))))))))))))")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId:
        try:
            remitter_queryset = Remitters.objects(phoneNumber__iexact=phoneNumber,status=1).first()
            if not remitter_queryset:
                remitters_table = Remitters(
                    userId = userId,
                    firstName = firstName,
                    lastName = lastName,
                    phoneNumber = phoneNumber,
                    pincode = pincode,
                    moneyArtRemitterId = moneyArtRemitterId,
                    monthlyLimit = monthlyLimit,
                    availableBalance = availableBalance,
                    createdOn = datetime.datetime.now(),
                    status = 1,
                    ).save()
                remitterId = str(remitters_table.id)
                for each_recipient in recipientsList:
                    print(each_recipient)
                    print("((((((((((each_recipient))))))))))")
                    ifscCode=each_recipient.get("ifscCode")
                    master_bank_queryset = MasterIFSCBank.objects(ifscCode=ifscCode,status=1).first()
                    if master_bank_queryset:
                        beneficiary_table = Beneficiaries(
                            userId = userId,
                            masterBankId = str(master_bank_queryset.id),
                            beneficiaryId = beneficiaryId,
                            fullName = fullName,
                            mobileNumber = mobileNumber,
                            verifyStatus = verifyStatus,
                            accountNumber = accountNumber,
                            createdOn = datetime.datetime.now(),
                            status = 1,
                            ).save()
                    else:
                        bankCode = ifscCode[-6:]
                        master_bank_table = MasterIFSCBank(
                            bankName = each_recipient.get("bankName",""),
                            bankCode = bankCode,
                            ifscCode = each_recipient.get("ifscCode",""),
                            isCreditCard = False,
                            isSettlement = False,
                            createdOn = datetime.datetime.now(),
                            status = 1,
                            ).save()
                        master_bank_table_id = str(master_bank_table.id)
                        beneficiary_table = Beneficiaries(
                            userId = userId,
                            masterBankId = master_bank_table_id,
                            beneficiaryId = each_recipient.get("beneficiaryId",""),
                            fullName = each_recipient.get("fullName",""),
                            mobileNumber = each_recipient.get("mobileNumber",""),
                            verifyStatus = each_recipient.get("verifyStatus",False),
                            accountNumber = each_recipient.get("accountNumber"),
                            createdOn = datetime.datetime.now(),
                            status = 1,
                            ).save()
                
                remitter_queryset = Remitters.objects(id=remitterId,status=1).first()
                remittersData={
                'remitterId':str(remitter_queryset.id),
                # 'moneyArtRemitterId':str(remitter_queryset.moneyArtRemitterId),
                'phoneNumber':remitter_queryset.phoneNumber,
                'firstName':remitter_queryset.firstName,
                'lastName':remitter_queryset.lastName,
                'availableBalance':remitter_queryset.availableBalance,
                'monthlyLimit':remitter_queryset.monthlyLimit,
                }
                if remitter_queryset.moneyArtRemitterId:
                    remittersData["moneyArtRemitterId"] = remitter_queryset.moneyArtRemitterId
                else:
                    remittersData["moneyArtRemitterId"] = ""

                
                data_status["responseStatus"] = 1
                data_status ["result"] = "Remitters and beneficiaries added successfully"
                data_status["remittersData"]=remittersData
                return data_status
            else:
                remittersData={
                'remitterId':str(remitter_queryset.id),
                # 'moneyArtRemitterId':str(remitter_queryset.moneyArtRemitterId),
                'phoneNumber':remitter_queryset.phoneNumber,
                'firstName':remitter_queryset.firstName,
                'lastName':remitter_queryset.lastName,
                'availableBalance':remitter_queryset.availableBalance,
                'monthlyLimit':remitter_queryset.monthlyLimit,
                }
                if remitter_queryset.moneyArtRemitterId:
                    remittersData["moneyArtRemitterId"] = remitter_queryset.moneyArtRemitterId
                else:
                    remittersData["moneyArtRemitterId"] = ""

                data_status["remittersData"]=remittersData
                data_status["responseStatus"] = 1
                data_status["result"]="This mobile number is already in use!!"
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to add data"
            return data_status
    else:
        data_status["result"] = "The required fields are missing."
        return data_status

@users.route("/user_based_commissions", methods=["POST"])
@encrypt_decrypt_after_login
def user_based_commissions():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
        commissionList = []
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    if not userId:
        data_status["result"] = "Required fields are missing!!"
        return data_status

    try:
        user_queryset = Users.objects(id=userId,status__in=[0,1]).first()
        if not user_queryset:
            data_status["result"]="Invalid user id!!"
            return data_status
        commissionId = str(user_queryset.commissionId.id)
        commissions_queryset = Commissions.objects(id=commissionId,status=1).order_by("-id").first()
        commissionDict = {
        "id":str(commissions_queryset.id),
        "commissionName":commissions_queryset.commissionName
        }
        modifiedCommissionsList = []
        for each_commission in commissions_queryset.commissionList:
            operator_queryset = Operators.objects(id=each_commission.get("operatorId")).first()
            operatorName = operator_queryset.operatorName

            transaction_api_queryset = TransactionAPI.objects(id=each_commission.get("transactionAPIId")).only('apiName').first()
            apiName = transaction_api_queryset.apiName

            service_queryset = Service.objects(id=each_commission.get("serviceId")).first()
            serviceName = service_queryset.serviceName

            modifiedDict = {
            "id":str(commissions_queryset.id),
            "commissionName":commissions_queryset.commissionName,
            "operatorId":each_commission.get("operatorId"),
            "transactionAPIId":each_commission.get("transactionAPIId"),
            "serviceId":each_commission.get("serviceId"),
            "operatorName":operatorName,
            "apiName":apiName,
            "serviceName":serviceName,
            "chargeType": each_commission.get("chargeType"),
            "chargeValue": each_commission.get("chargeValue"),
            "commissionType": each_commission.get("commissionType"),
            "commissionValue": each_commission.get("commissionValue")
            }
            modifiedCommissionsList.append(modifiedDict)
        commissionDict["commissionList"]=modifiedCommissionsList

        data_status["result"] = "Commissions details fetched successfully"
        data_status["responseStatus"] = 1
        data_status["commissionDetails"] = commissionDict
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch commissions data!!"
        return data_status

##################### OLD CODE #####################
# @users.route("/operator_based_commissions", methods=["POST"])
# def operator_based_commissions():
#   data_status = {"responseStatus": 0, "result": "", "commissionDict": {}}
#   userId = request.json.get("userId", "")
#   operatorId = request.json.get("operatorId", "")
#   transactionAPIId = request.json.get("transactionAPIId", "")

#   if userId and operatorId and transactionAPIId:
#       try:
#           commissionDict = {}
#           user_queryset = Users.objects(id=userId,status__in=[0,1]).first()
#           if not user_queryset:
#               data_status["result"]="Invalid user id!!"
#               return data_status

#           if user_queryset.commissionId:
#               commissionId = str(user_queryset.commissionId.id)
#               commissions_queryset = Commissions.objects(id=commissionId,status=1).order_by("-id").first()
#               for each_record in commissions_queryset.commissionList:
#                   if each_record.get("operatorId") == operatorId and each_record.get("transactionAPIId") == transactionAPIId:
#                       commissionDict = {
#                       "operatorId": each_record.get("operatorId"),
#                       "transactionAPIId": each_record.get("transactionAPIId"),
#                       "chargeType": each_record.get("chargeType"),
#                       "chargeValue": each_record.get("chargeValue"),
#                       "commissionType": each_record.get("commissionType"),
#                       "commissionValue": each_record.get("commissionValue")
#                       }
#           data_status["result"] = "Commissions details fetched successfully"
#           data_status["responseStatus"] = 1
#           data_status["commissionDict"] = commissionDict
#           return data_status
#       except Exception as e:
#           app.logger.error(traceback.format_exc())
#           data_status["result"] = "Unable to fetch commissions data!!"
#           return data_status
#   else:
#       data_status["result"] = "Required fields are missing!!"
#       return data_status

@users.route("/operator_based_commissions", methods=["POST"])
@encrypt_decrypt_after_login
def operator_based_commissions():
    data_status = {"responseStatus": 0, "result": "", "commissionDict": {}}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
        operatorId = data.get("operatorId", "")
        transactionAPIId = data.get("transactionAPIId", "")
        print("request:", data)
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId and operatorId and transactionAPIId:
        try:
            commissionDictResult=operator_based_commission_details(userId,operatorId,transactionAPIId)
            # data_status["result"] = "Commissions details fetched successfully"
            # data_status["responseStatus"] = 1
            # data_status["commissionDict"] = commissionDict
            return commissionDictResult
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fetch commissions data!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status

def operator_based_commission_details(userId,operatorId,transactionAPIId):
    data_status = {"responseStatus": 0, "result": "", "commissionDict": {}}
    if userId and operatorId and transactionAPIId:
        try:
            commissionDict = {}
            user_queryset = Users.objects(id=userId,status__in=[0,1]).first()
            if not user_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status

            operators_commission_queryset = Commissions.objects(
                paymentGatewayId=transactionAPIId,
                # subServiceId=subServiceId,
                # profileId=profileId,
                commissionList__operatorId=operatorId
                ).first()
            # print(operators_commission_queryset.commissionList,"operators_commission_queryset")
            matched_commission_index=None
            commissionoperatorDict={}
            commissionValue="0"
            chargeValue="0"
            chargeType="FLAT"
            commissionType="FLAT"
            transactionAPIId = ""
            if operators_commission_queryset:
                matched_commission_index = next((index for index, commission in enumerate(operators_commission_queryset.commissionList) if commission['operatorId'] == operatorId), None)
                # print(matched_commission_index,"working")
            else:
                matched_commission_index = None
            if matched_commission_index!=None:
                commissionoperatorDict=operators_commission_queryset.commissionList[matched_commission_index]
                # print(commissionoperatorDict,"commissionoperatorDict")
                # print(each_operator.operatorName,"each_operator.operatorName")
                commissionType=commissionoperatorDict.get('commissionType')
                chargeType=commissionoperatorDict.get('chargeType')
                chargeValue=commissionoperatorDict.get('chargeValue')
                commissionValue=commissionoperatorDict.get('commissionValue')
                transactionAPIId=commissionoperatorDict.get('transactionAPIId')
                operatorId=commissionoperatorDict.get('operatorId')

            commissionDict = {
                "operatorId": operatorId,
                "transactionAPIId": transactionAPIId,
                "chargeType": chargeType,
                "chargeValue": chargeValue,
                "commissionType": commissionType,
                "commissionValue": commissionValue
                }
            data_status["result"] = "Commissions details fetched successfully"
            data_status["responseStatus"] = 1
            data_status["commissionDict"] = commissionDict
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fetch commissions data!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status

@users.route("/get_agents_list", methods=["POST"])
@encrypt_decrypt_after_login
def get_agents_list():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    agentsList =[]
    if userId:
        try:
            user_queryset = Users.objects(parentId=userId,status__nin=[2]).order_by("-id")
            if user_queryset:
                for each_user in user_queryset:
                    userDict = fetching_user_details(each_user)
                    agentsList.append(userDict)

            data_status["result"] = "Agents details fetched successfully"
            data_status["responseStatus"] = 1
            data_status["agentsList"] = agentsList
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fetch agents data!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status



@users.route("/get_single_agent_details", methods=["POST"])
@encrypt_decrypt_after_login
def get_single_agent_details():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    if userId:
        try:
            user_queryset = Users.objects(id=userId,status__nin=[2]).first()
            if not user_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status
            agent_dict = fetching_user_details(user_queryset)
            data_status["result"] = "Agent details fetched successfully"
            data_status["responseStatus"] = 1
            data_status["agentData"] = agent_dict
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fetch agent data!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status



@users.route("/get_commisssion_list", methods=["POST"])
@encrypt_decrypt_after_login
def get_commisssion_list():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    commissionsList = []
    if userId:
        try:
            commissions_queryset = Commissions.objects(createdBy=userId,status__nin=[2]).order_by("-id").all()
            if commissions_queryset:
                for each_commission in commissions_queryset:
                    commissions_data = fetching_commission_details(each_commission)
                    commissionsList.append(commissions_data)
            data_status["result"] = "Commission details fetched successfully"
            data_status["responseStatus"] = 1
            data_status["commissionsList"] = commissionsList
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fetch commissions data!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status

@users.route("/assigned_commisssions_list", methods=["POST"])
@encrypt_decrypt_after_login
def assigned_commisssions_list():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    commissionsList = []
    if userId:
        try:
            commissions_queryset = Commissions.objects(
                Q(createdBy=userId) | Q(createdBy=None),
                status=1
                ).order_by("-id").all()
            if commissions_queryset:
                for each_commission in commissions_queryset:
                    commissions_data = fetching_commission_details(each_commission)
                    commissionsList.append(commissions_data)
            data_status["result"] = "Commission details fetched successfully"
            data_status["responseStatus"] = 1
            data_status["commissionsList"] = commissionsList
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fetch commissions data!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status

def fetching_operator_details(operator_queryset):
    operator_dict = {}
    try:
        operator_dict={
        "id":str(operator_queryset.id),
        "operatorName":operator_queryset.operatorName,
        "serviceId":str(operator_queryset.serviceId.id),
        "serviceName":operator_queryset.serviceId.serviceName,
        }
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return operator_dict


def fetching_transaction_api_details(transaction_api_queryset):
    transaction_api_dict = {}
    try:
        transaction_api_dict={
        "id":str(transaction_api_queryset.id),
        "apiName":transaction_api_queryset.apiName,
        "code":transaction_api_queryset.code,
        "isActive":transaction_api_queryset.isActive,
        "isUserWise":transaction_api_queryset.isUserWise,
        "transactionType":transaction_api_queryset.transactionType,
        "paramsList":transaction_api_queryset.paramsList
        }
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return transaction_api_dict

#Get Commsion Operators List API
@users.route("/get_commission_operators_list",methods=["POST","GET"])
@encrypt_decrypt_after_login
def get_commission_operators_list():
    data_status = {"responseStatus": 0, "result": ""}
    operatorsList = []
    transactionApisList = []
    try:
        operators_queryset = Operators.objects(status=1).order_by("-id").all()
        for each_operator in operators_queryset:
            operator_data = fetching_operator_details(each_operator)
            operatorsList.append(operator_data)

        transaction_apis_queryset = TransactionAPI.objects(status=1).order_by("-id").all()
        for each_transaction_api in transaction_apis_queryset:
            transaction_api_data = fetching_transaction_api_details(each_transaction_api)
            transactionApisList.append(transaction_api_data)

        data_status["responseStatus"] = 1
        data_status["operatorsList"] = operatorsList
        data_status["transactionApisList"] = transactionApisList
        data_status["result"] = "Commission operators data fetched successfully"
        # return jsonify(data_status)
        return data_status
    except Exception as e:
        data_status["result"] = "Unable to fecth data"
        return data_status

def fetching_commission_details(commission_queryset):
    commissions_dict = {}
    try:
        commissions_dict = {
        "id":str(commission_queryset.id),
        "commissionName":commission_queryset.commissionName,
        # "createdOn":commission_queryset.createdOn,
        }
        if commission_queryset.createdOn:
            ist_time=commission_queryset.createdOn.replace(tzinfo=pytz.utc).astimezone(ist_timezone)
            commissions_dict["createdOn"] = ist_time.strftime("%m-%d-%Y %I:%M %p")
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return commissions_dict



#Add commission API
@users.route("/add_user_commission", methods=["POST"])
@encrypt_decrypt_after_login
def add_user_commission():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
        commissionName = data.get("commissionName","")
        commissionLists = data.get("commissionLists",[])
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        if commissionName:
            try:
                user_commission_table = Commissions(
                    commissionName = commissionName,
                    commissionList = commissionLists,
                    userType = "agent",
                    createdBy = userId,
                    createdOn = datetime.datetime.now(),
                    status = 1,
                    )
                save_table = user_commission_table.save()
                userCommissionId = str(save_table.id)

                data_status["result"] = "User commissions added successfully"
                data_status["responseStatus"] = 1
                return data_status
            except Exception as e:
                app.logger.error(traceback.format_exc())
                data_status["result"] = "Unable to add user commission"
                return data_status
        else:
            data_status["result"] = "Required fields are missing"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to add user commission"
        return data_status



@users.route("/get_single_user_commission",methods=["POST","GET"])
@encrypt_decrypt_after_login
def get_single_user_commission():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        commissionId = data.get("commissionId","")
        userId = data.get("userId","")
        commission_data ={}
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    try:
        commission_queryset = Commissions.objects(
            id=commissionId,
            createdBy=userId,
            status__in=[0,1]
            ).first()
        if commission_queryset:
            # commission_data = fetching_user_commission_details(commission_queryset)

            commission_data = {
            "id":str(commission_queryset.id),
            "commissionName":commission_queryset.commissionName
            }

            modifiedCommissionsList = []
            for each_commission in commission_queryset.commissionList:
                operator_queryset = Operators.objects(id=each_commission.get("operatorId")).first()
                operatorName = operator_queryset.operatorName

                transaction_api_queryset = TransactionAPI.objects(id=each_commission.get("transactionAPIId")).only("apiName").first()
                apiName = transaction_api_queryset.apiName

                service_queryset = Service.objects(id=each_commission.get("serviceId")).first()
                serviceName = service_queryset.serviceName

                modifiedDict = {
                # "id":str(commission_queryset.id),
                # "commissionName":commission_queryset.commissionName,
                "operatorId":each_commission.get("operatorId"),
                "transactionAPIId":each_commission.get("transactionAPIId"),
                "serviceId":each_commission.get("serviceId"),
                "operatorName":operatorName,
                "apiName":apiName,
                "serviceName":serviceName,
                "chargeType": each_commission.get("chargeType"),
                "chargeValue": each_commission.get("chargeValue"),
                "commissionType": each_commission.get("commissionType"),
                "commissionValue": each_commission.get("commissionValue")
                }
                modifiedCommissionsList.append(modifiedDict)
            commission_data["commissionList"]=modifiedCommissionsList

        data_status["responseStatus"] = 1
        data_status["result"] = "Commission details fetched successfully"
        data_status["commissionData"] = commission_data
        return data_status

    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch commission details"
        return data_status

@users.route("/update_user_commission",methods=["POST","GET"])
@encrypt_decrypt_after_login
def update_user_commission():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        commissionId = data.get("commissionId","")
        userId = data.get("userId","")
        commissionName = data.get("commissionName","")
        commissionLists = data.get("commissionLists",[])
        # operatorIdslist = request.json.get("operatorIdslist",[])
        # chargeTypesList = request.json.get("chargeTypesList",[])
        # chargeValuesList = request.json.get("chargeValuesList",[])
        # commissionTypesList = request.json.get("commissionTypesList",[])
        # commissionValuesList = request.json.get("commissionValuesList",[])
        # transactionApiIdsList = request.json.get("transactionApiIdsList",[])
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if commissionName:
        try:
            commission_queryset = Commissions.objects(id=commissionId,createdBy=userId).only("commissionName","commissionList").first()
            if not commission_queryset:
                data_status["result"] = "Commission does not exist"
                return data_status

            # if commission_queryset:
            #     updateCommissionList = []
            #     for i in range(len(operatorslist)):
            #         operator_queryset = Operators.objects(id=operatorslist[i]).first()
            #         serviceId = str(operator_queryset.serviceId.id)
            #         commissionDict1 = {
            #             "operatorId": operatorIdslist[i],
            #             "chargeType": chargeTypesList[i],
            #             "chargeValue": chargeTypesList[i],
            #             "commissionType": commissionTypesList[i],
            #             "commissionValue": commissionValuesList[i],
            #             "transactionAPIId": transactionApiIdsList[i],
            #             "serviceId":serviceId
            #         }
            #         updateCommissionList.append(commissionDict1)

            commission_queryset.update(
                commissionName=commissionName,
                commissionList = commissionLists
                )
            data_status["result"] = "User Commissions updated successfully"
            data_status["responseStatus"] = 1
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to update user commission!!"
            return data_status
    else:
        data_status["result"] = "The required field is missing"
        return data_status



@users.route("/assign_user_commission",methods=["POST","GET"])
@encrypt_decrypt_after_login
def assign_user_commission():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        commissionId = data.get("commissionId","")
        userId = data.get("userId","")
        parentId = data.get("parentId","") #Login user Id
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if commissionId and userId and parentId:
        try:
            user_queryset = Users.objects(id=userId,parentId=parentId).only("commissionId").first()
            if not user_queryset:
                data_status["result"] = "User does not exist"
                return data_status
            user_queryset.update(
                commissionId=ObjectId(commissionId)
                )
            data_status["result"] = "User commissions assigned successfully"
            data_status["responseStatus"] = 1
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to assign user commission!!"
            return data_status
    else:
        data_status["result"] = "The required field is missing"
        return data_status

@users.route("/payemnt_gateways_credentials_list",methods=["POST","GET"])
@encrypt_decrypt_after_login
def payemnt_gateways_credentials_list():
    data_status = {"responseStatus": 0, "result": ""}
    transactionApisList = []
    try:
        transaction_apis_queryset = TransactionAPI.objects(status=1,transactionType="PaymentGateway").order_by("-id").all()
        for each_transaction_api in transaction_apis_queryset:
            transaction_api_data = fetching_transaction_api_details(each_transaction_api)
            transactionApisList.append(transaction_api_data)

        data_status["responseStatus"] = 1
        data_status["transactionApisList"] = transactionApisList
        data_status["result"] = "Transaction API's data fetched successfully!"
        return data_status
    except Exception as e:
        data_status["result"] = "Unable to fecth transaction api data!!"
        return data_status


@users.route("/getauthtoken", methods=["POST"])
@encrypt_decrypt_after_login
def getauthtoken():
    payloadresponse=getBbpsAuthorizationToken()
    print(payloadresponse,"payloadresponse for BBPS")
    print(payloadresponse.get('accessToken'),"accessToken")
    return payloadresponse

#THIS FUNCTION IS IN UTIL
# def getBbpsAuthorizationToken(): 
#     data_status = {"responseStatus":0,"result":"","accessToken":""}
#     try:
#         url = "https://accounts.payu.in/oauth/token"
#         headers = {
#         "content-type": "application/json",
#         "content-type": "application/x-www-form-urlencoded"
#         }
#         # payload="client_id=33d68849106a4674db942a69532349b4bdddc73b20806ce9a7229c37e54cf836&client_secret=52794e8f850d5960a0a84d1795b55b60121a4f24136340759ebed9a229a70f94&scope=read_bills create_transactions read_billers read_biller_categories read_transactions&grant_type=client_credentials"

#         payload="client_id=35e731ff20e6bc521de9f29618b22c1240a4c69f6350c50e0fcb8e6b7d6c1bec&client_secret=610a66e8fb918d2c6a7ccf5674ea2893cb7cbbd589a0c3d9544e3f3ddf7366f4&scope=read_bills create_transactions read_billers read_biller_categories read_transactions&grant_type=client_credentials"
#         payuresponse = requests.post(url, data=payload, headers=headers)
#         payuresponseData = json.loads(payuresponse.text)
#         print("payuresponse.text",payuresponse.text)
#         data_status['responseStatus']=1
#         data_status['accessToken']=payuresponseData.get("access_token")
#         return data_status
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         data_status["result"]="Unable to fetch bill request data!!"
#         return data_status

# @users.route("/billfetchrequest", methods=["POST"])
# # @user_required
# @encrypt_decrypt_after_login
# def billfetchrequest():
#     data_status = {"responseStatus":0,"result":"","authorizationToken":""}
#     try:
#         data = request.decrypted_data
#         userId = data.get("userId","")
#         payload = data.get("payload",{})
#         authorizationToken = data.get("authorizationToken","")
#         clientCode = data.get("clientCode","")

#         if not userId and not payload and not clientCode:
#             data_status["result"]="Required fields are missing!!"
#             return data_status
#         if authorizationToken=="":
#             authtokenresp=getBbpsAuthorizationToken()
#             authorizationToken=authtokenresp.get('accessToken')

#         if payload.get('billerId')=="EDU010815MAH01":
#             todayDate=datetime.datetime.now()
#             formatted_date = todayDate.strftime("%Y-%m-%d")
#             print(todayDate,"todayDate")
#             payuresponseData={'code': 200, 'status': 'SUCCESS', 'payload': {'refId': payload.get('refId'), 'requestTimeStamp': formatted_date, 'amount': 25000.00, 'accountHolderName': 'Yadati Samuel John', 'dueDate': '2025-04-10', 'billDate': '2025-01-04', 'billerId': 'EDU010815MAH01', 'additionalParams': {}, 'billNumber': 'Term Fee', 'billPeriod': 'NA', 'approvalRefNum': 'AB123456'}}
#             data_status["responseStatus"]=1
#             data_status["result"]="Bill request data fetched successfully!"
#             data_status["payuresponseData"]=payuresponseData
#             data_status["authorizationToken"]=authorizationToken
#             return data_status

#         url = "https://bbps-sb.payu.in/payu-nbc/v1/nbc/billfetchrequest"
#         # url = "https://nbc.payu.in/payu-nbc/v1/nbc/billfetchrequest"
#         print(payload,"PAYLOAD")
#         headers = {
#         "content-type": "application/json",
#         "authorization": "Bearer "+str(authorizationToken),
#         "clientCode": clientCode
#         }
#         print(headers,"headers")

#         payuresponse = requests.post(url, json=payload, headers=headers)
#         print(payuresponse.text,"(((((((((((((payuresponse)))))))))))))")
#         payuresponseData = json.loads(payuresponse.text)

#         data_status["responseStatus"]=1
#         data_status["result"]="Bill request data fetched successfully!"
#         data_status["payuresponseData"]=payuresponseData
#         data_status["authorizationToken"]=authorizationToken
#         return data_status
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         data_status["result"]="Unable to fetch bill request data!!"
#         return data_status

@users.route("/payin_payment_response", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def payin_payment_response():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        paymentChannel = data.get("paymentChannel","")
        agent = data.get("agent","")
        location = data.get("location","")
        productName = data.get("productName","")
        walletId = data.get("walletId","")
        payInPaymentGatewayId = data.get("payInPaymentGatewayId","")
        responseDict = data.get("responseDict",{})

        if not userId and not responseDict and not walletId:
            data_status["result"]="Required fields are missing!!"
            return data_status
        wallettran_queryset = WalletTransactions.objects(id=walletId).first()
        if not wallettran_queryset:
            data_status["result"]="Invalid Request!!"
            return data_status

        merchant_queryset = Users.objects(id=userId,status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid Request!!"
            return data_status
        
        check_kyc_status = merchant_kyc_status(str(merchant_queryset.id))
        if check_kyc_status.get("responseStatus") != 1:
            data_status["result"]="Merchant KYC is not completed please contact to admin!!"
            return data_status
        kycStatus = check_kyc_status.get("merchantKycDetails", {}).get("kycStatus")
        if kycStatus == False:
            data_status["result"]="Merchant KYC is not completed please contact to admin!!"
            return data_status

        print(responseDict,"RESPONSE DICT")
        print(type(responseDict),"RESPONSE DICT")

        cardmasked = ""
        customerVpa = ""
        cardType = ""
        responseDict = responseDict.replace('\\', '')
        responseDict = ''.join(ch for ch in responseDict if ch not in '\x00-\x1f')
        jsonResponseDict = responseDict.replace("'", '"')
        jsonResponseDict = jsonResponseDict.strip()
        jsonResponseDict = json.loads(jsonResponseDict)
        
        if jsonResponseDict:
            
            if wallettran_queryset.pgOrderId != jsonResponseDict.get("txnid"):
                data_status["result"]="Invalid Request!!"
                return data_status

            
            if jsonResponseDict.get("error_code")=="E000":
                errorMessage = jsonResponseDict.get("field9")
            else:
                errorMessage = jsonResponseDict.get("field8")

            
            bankName=""
            bankRefId=str(jsonResponseDict.get("bank_ref_no"))
            pgOrderId=str(jsonResponseDict.get("id"))
            paymentMode=str(jsonResponseDict.get("mode"))
            currency="INR"
            if jsonResponseDict.get("mode")=="UPI":
                customerVpa = jsonResponseDict.get("field1")
            elif jsonResponseDict.get("mode")=="CC":
                paymentMode="CREDIT CARD"
                cardType=jsonResponseDict.get("card_type")
                bankName=jsonResponseDict.get("issuing_bank")
                customerVpa=jsonResponseDict.get("ibibo_code")
                cardmasked=jsonResponseDict.get("card_no")
            elif jsonResponseDict.get("mode")=="DC":
                paymentMode="DEBIT CARD"
                cardType=jsonResponseDict.get("ibibo_code")
                cardmasked=jsonResponseDict.get("card_no")
            elif jsonResponseDict.get("mode")=="NB":
                paymentMode="NET BANKING"
                customerVpa=jsonResponseDict.get("ibibo_code")
            # elif jsonResponseDict.get("mode")=="NEFT":
            #     cardmasked=""
            # elif jsonResponseDict.get("mode")=="AEPS":
            #     cardmasked=""
            # elif jsonResponseDict.get("mode")=="IMPS":
            #     cardmasked=""
            elif jsonResponseDict.get("mode")=="CASH":
                paymentMode="WALLET"
                customerVpa=jsonResponseDict.get("ibibo_code")

            
            
            ################################################### Slab Calculation for Payin #########################################################################
            payment_mode_queryset = PaymentMode.objects(paymentMode=str(paymentMode)).first()
            paymentModeId=""
            subPaymentModeId=""
            if payment_mode_queryset:
                paymentModeId = str(payment_mode_queryset.id)
                if cardType!="":
                    subPaymentMode=cardType
                    sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=str(subPaymentMode)).first()
                    if sub_payment_mode_queryset:
                        subPaymentModeId = str(sub_payment_mode_queryset.id)
                else:
                    subPaymentMode=paymentMode
                    sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=str(subPaymentMode)).first()
                    if sub_payment_mode_queryset:
                        subPaymentModeId = str(sub_payment_mode_queryset.id)

                if subPaymentModeId=="":
                    subPaymentMode=paymentMode
                    sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=str(subPaymentMode)).first()
                    if sub_payment_mode_queryset:
                        subPaymentModeId = str(sub_payment_mode_queryset.id)
                

            patternId = str(merchant_queryset.patternId.id)
            amount = jsonResponseDict.get("amount")
            print(amount,"(((((((((((((((AMOUNT)))))))))))))))")
            print(type(amount),"(((((((((((((((AMOUNT TYPE)))))))))))))))")
            if amount is None:
                amount = 0
            else:
                amount = float(amount)

            if amount < 0:
                data_status["result"]="Insufficient amount!!"
                return data_status

            slabId = None
            transactionAmount = amount
            commissionCharges={}
            if paymentModeId!="" and subPaymentModeId!="" and payInPaymentGatewayId!="" and patternId!="":

                commissionCharges = slab_calculation_for_payin(amount,paymentModeId,subPaymentModeId,patternId,payInPaymentGatewayId)

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

            #######################################################################################################################################################
            transactionData = [jsonResponseDict]
            if jsonResponseDict.get("status") == "success":
                if float(wallettran_queryset.amount)==float(amount):
                    status=1
                else:
                    status = 6
                    errorMessage = "Insufficient amount credited!!"
                lorder_queryset = WalletTransactions.objects(id=str(walletId),status__nin=[5]).first()
                if lorder_queryset.status!=1 and status==1:
                    balanceResult=user_payin_balance_update(str(merchant_queryset.id),float(transactionAmount),"Credit",str(payInPaymentGatewayId))
                    if balanceResult.get('responseStatus')==0:
                        data_status["result"]="Unable to connect with server. Please Try again."
                        return data_status
                    payinbalancelogs_queryset=PayinBalanceLogs(
                        transactionAPIId=str(payInPaymentGatewayId),
                        userId=userId,
                        previousBalance=round_last_digits(float(balanceResult.get('transactionPreviousBalance'))),
                        currentBalance=round_last_digits(float(balanceResult.get('transactionCurrentBalance'))),
                        orderId=str(wallettran_queryset.orderId),
                        amount=round_last_digits(float(amount)),
                        grandTotal=round_last_digits(float(transactionAmount)),
                        transferType="Credit",
                        userType="user",
                        transactionId=str(wallettran_queryset.transactionId),
                        createdOn=datetime.datetime.now(),
                        status=1
                        ).save()

                    lorder_queryset.update(status=status,payInResponseCallBackData=transactionData,responseCallBackTime=datetime.datetime.now(),pgOrderId=pgOrderId,bankRefId=str(bankRefId),customerVpa=customerVpa,currency=currency,errorMessage=errorMessage,grandTotal=round_last_digits(float(transactionAmount)),walletLog="Wallet Balance is added with the amount of " + str(amount) + ".",previousBalance=round_last_digits(float(balanceResult.get('userPreviousBalance'))),cardmasked=cardmasked,subPaymentModeId=ObjectId(subPaymentModeId),paymentModeId=ObjectId(paymentModeId),paymentType=paymentMode,bankName=bankName,productName=productName,currentBalance=round_last_digits(float(balanceResult.get('userCurrentBalance'))),commissionCharges=commissionCharges)
                    try:
                        merchantName = str(merchant_queryset.fullName)
                        trnsactionDate = datetime.datetime.now().astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p")
                        mail_subject = "Load Funds for Graam Pay from Merchant " + merchantName + "."
                        recipients_list = [admin_recieve_email]
                        template_name = "emails/loadfunds.html"
                        mail_data = {
                        "merchantName":merchantName,
                        "amount":formatINR("{:.2f}".format(float(amount))),
                        "transactionId":str(wallettran_queryset.transactionId),
                        "paymentMode":jsonResponseDict.get("mode"),
                        "cardNumber":cardmasked,
                        "orderId":str(wallettran_queryset.orderId),
                        "bankRefId":str(jsonResponseDict.get("bank_ref_no")),
                        "transactionDate":trnsactionDate,
                        }
                        mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                        
                        merchant_mail_subject = "Payment Transaction Alert From Graam Pay"
                        merchant_recipients_list = [merchant_queryset.email]

                        mailoutputData = send_asynchronous_email(merchant_mail_subject, merchant_recipients_list, template_name, mail_data)

                    except Exception as e:
                        app.logger.error(traceback.format_exc())
                        pass
                    try:
                        if merchant_queryset.parentId and commissionCharges.get("slabId") != None:
                            user_parent_payin_commission_details(str(merchant_queryset.parentId.id),amount,payInPaymentGatewayId,jsonResponseDict.get("txnid"),paymentModeId,subPaymentModeId,commissionCharges.get("chargeAmount"),commissionCharges.get("chargeValue"),commissionCharges.get("chargeType"),str(merchant_queryset.id),float(commissionCharges.get("gstAmount")),float(commissionCharges.get("tdsAmount")))
                    except Exception as e:
                        app.logger.error(traceback.format_exc())
                        pass
                else:
                    lorder_queryset.update(status=status,payInResponseCallBackData=transactionData,responseCallBackTime=datetime.datetime.now(),pgOrderId=pgOrderId,bankRefId=bankRefId,customerVpa=customerVpa,currency=currency,errorMessage=errorMessage,cardmasked=cardmasked,subPaymentModeId=ObjectId(subPaymentModeId),paymentModeId=ObjectId(paymentModeId),paymentType=paymentMode,bankName=bankName,productName=productName,grandTotal=round_last_digits(float(transactionAmount)),walletLog="Wallet Balance is added with the amount of " + str(amount) + ".",commissionCharges=commissionCharges)
            else:
                wallettran_queryset.update(status=0,payInResponseCallBackData=transactionData,responseCallBackTime=datetime.datetime.now(),pgOrderId=pgOrderId,bankRefId=bankRefId,customerVpa=customerVpa,currency=currency,errorMessage=errorMessage,cardmasked=cardmasked,subPaymentModeId=ObjectId(subPaymentModeId),paymentModeId=ObjectId(paymentModeId),paymentType=paymentMode,bankName=bankName,productName=productName,grandTotal=round_last_digits(float(transactionAmount)),walletLog="Wallet Balance is added with the amount of " + str(amount) + ".",commissionCharges=commissionCharges)
        data_status["responseStatus"]=1
        data_status["transactionId"]=walletId
        data_status["result"]="Payin response data saved successfully!"
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to save payin response data!!"
        return data_status

@users.route("/payin_payment_create_intent", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def payin_payment_create_intent():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        paymentChannel = data.get("paymentChannel","")
        agent = data.get("agent","")
        customerName = data.get("customerName","")
        customerEmail = data.get("customerEmail","")
        customerPhonenumber = data.get("customerPhonenumber","")
        location = data.get("location","")
        productName = data.get("productName","")
        payInPaymentGatewayId = data.get("payInPaymentGatewayId","")
        setlementId = data.get("setlementId","")
        amount = data.get("amount","")
        otpCheckId = data.get("otpCheckId","")
        print(data,"request.json")
        if not userId and not amount and not payInPaymentGatewayId and not setlementId and not customerName != "" and not customerEmail != "" and not customerPhonenumber != "":
            data_status["result"]="Required fields are missing!!"
            return data_status
        
        if amount is None:
            amount = 0
        else:
            amount = float(amount)

        if amount < 0:
            data_status["result"]="Insufficient amount!!"
            return data_status

        currentDateStart = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
        currentDateEnd = currentDateStart.replace(hour=23, minute=59, second=59, microsecond=999999)

        checkphoneNumber = WalletTransactions.objects(customerPhonenumber=str(customerPhonenumber),status=1,createdOn__gte=currentDateStart,createdOn__lte=currentDateEnd).first()
        if checkphoneNumber:
            data_status["result"]="Only one transaction is allowed per customer per day."
            return data_status

        payin_gate_way_queryset = TransactionAPI.objects(id=str(payInPaymentGatewayId),status=1).first()
        if not payin_gate_way_queryset:
            data_status["result"]="Invalid Request."
            return data_status

        merchant_queryset = Users.objects(id=str(userId),status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid Request."
            return data_status

        check_kyc_status = merchant_kyc_status(str(merchant_queryset.id))
        if check_kyc_status.get("responseStatus") != 1:
            data_status["result"]="Merchant KYC is not completed please contact to admin!!"
            return data_status
        kycStatus = check_kyc_status.get("merchantKycDetails", {}).get("kycStatus")
        if kycStatus == False:
            data_status["result"]="Merchant KYC is not completed please contact to admin!!"
            return data_status

        if merchant_queryset.merchantType=="customer":
            if otpCheckId=="":
                data_status["result"]="Invalid Request."
                return data_status
            otpcheck_querryset=OtpChecks.objects(userId=str(userId),id=str(otpCheckId),status=1).first()
            if not otpcheck_querryset:
                data_status["result"]="Invalid Request."
                return data_status
            otpcheck_querryset.update(status=2)

        check_transaction_limits = merchant_transaction_limit_settings("Payin",payInPaymentGatewayId,userId,amount)
        if check_transaction_limits.get("responseStatus") == 0:
            data_status['result']=check_transaction_limits.get("result")
            return data_status

        paymentGateWayCode = payin_gate_way_queryset.code
        errorMessage="Initiated"
        paymentMode=""
        customerVpa=""
        cardType=""
        cardmasked=""
        patternId = str(merchant_queryset.patternId.id)
        slabId = None
        transactionAmount = amount
        commissionCharges={}
        orderId = str(get_epoch_milli_time())+random_digit_generate(2)
        transactionId = random_digit_generate(15)
        walletId=""
        merchantUniqueNumber=str(merchant_queryset.merchantUniqueNumber)
        mid_extracted = merchantUniqueNumber[1:].lstrip("0")
        pgOrderId=str(transaction_id_prefix)+str(mid_extracted)+str(orderId)
        wallet_transaction_table = WalletTransactions(
            userId = userId,
            amount = round_last_digits(float(amount)),
            grandTotal=round_last_digits(float(transactionAmount)),
            paymentGatewayId = payInPaymentGatewayId,
            currency="INR",
            paymentType = paymentMode,
            creditType = "Credit",
            transactionId = transactionId,
            transactionData = [data],
            orderId = orderId,
            walletLog="",
            userType="user",
            createdBy = None,
            createdOn = datetime.datetime.now(),
            location = location,
            platform = "app",
            agent = agent,
            customerEmail = customerEmail,
            customerName = customerName,
            customerPhonenumber = customerPhonenumber,
            previousBalance=0,
            currentBalance=0,
            paymentLinkId = None,
            PaymentButtonId = None,
            paymentPageId = None,
            errorMessage = errorMessage,
            paymentChannel = paymentChannel,
            bankRefId="",
            cardmasked=cardmasked,
            productName=productName,
            setlementId=setlementId,
            pgOrderId=pgOrderId,
            customerVpa="",
            commissionCharges=commissionCharges,
            settlementStatus = 1,
            status = 3
            )
        wallet_save=wallet_transaction_table.save()
        walletId=str(wallet_save.id)
        upi_intent_url=""
        if walletId:
            if paymentGateWayCode == "Lyra_Payin":
                get_client = ""
                get_secret = ""
                get_base_url = ""
                user_name = ""
                get_base_url = ""
                password = ""
                webhook_url = ""
                return_url = ""
                for each_key in payin_gate_way_queryset.paramsList:
                    note="Online Course"
                    client_ip="125.40.25.126"
                    currency="INR"
                    get_key = each_key.get("key")
                    if get_key == "api_key":
                        get_client = each_key.get("value")
                    if get_key == "secret_key":
                        get_secret = each_key.get("value")
                    if get_key == "base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "webhook_url":
                        webhook_url = each_key.get("value")
                    if get_key == "return_url":
                        return_url = each_key.get("value")
                    if get_key == "user_name":
                        user_name = each_key.get("value")
                    if get_key == "password":
                        password = each_key.get("value")
                ###################################################### Lyra Payin Code #########################################################################
                paymentgatewayresponseDict = lyra_payin_payment_intent(get_base_url,pgOrderId,note,amount,currency,customerName,customerPhonenumber,customerEmail,webhook_url,return_url,userId,payInPaymentGatewayId,client_ip,"api",user_name,password)
                ################################################################################################################################################
                if paymentgatewayresponseDict.get("responseStatus") == 1:
                    transactionId = paymentgatewayresponseDict.get("payment_request_id")
                    transactionData = paymentgatewayresponseDict.get("transactionData")
                    paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
                    pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
                    upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
                    wallet_save.update(transactionId=transactionId,transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
                    data_status["responseStatus"]=1
                    data_status["transactionId"]=pgOrderId
                    data_status["walletId"]=walletId
                    data_status["PaymentLink"]=upi_intent_url
                    data_status["gatewayType"]=paymentGateWayCode
                    data_status["result"]="Payin response data saved successfully!"
                    return data_status
                else:
                    errorresult=paymentgatewayresponseDict.get("result")
                    wallet_save.update(errorMessage=errorresult,status=0)
                    data_status["result"]=errorresult
                    return data_status
            else:
                data_status["responseStatus"]=1
                data_status["transactionId"]=pgOrderId
                data_status["walletId"]=walletId
                data_status["PaymentLink"]=upi_intent_url
                data_status["gatewayType"]=paymentGateWayCode
                data_status["result"]="Payin response data saved successfully!"
                return data_status
        else:
            data_status["result"]="Unable to save payin response data!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        print(traceback.format_exc(),"traceback_error")
        data_status["result"]="Unable to save payin response data!!"
        return data_status

def fetching_transaction_details(each_transaction):
    transactionDict = {}
    try:
        transactionDict = {
        "id":str(each_transaction.id),
        "userId":str(each_transaction.userId.id),
        "paymentGatewayId":str(each_transaction.paymentGatewayId.id),
        "paymentGatewayName":each_transaction.paymentGatewayId.apiName,
        "fullName":each_transaction.userId.fullName,
        "amount":each_transaction.amount,
        "grandTotal":each_transaction.grandTotal,
        "previousBalance":each_transaction.previousBalance,
        "currentBalance":each_transaction.currentBalance,
        "currency":each_transaction.currency,
        "paymentType":each_transaction.paymentType,
        "cardType":each_transaction.cardType,
        "creditType":each_transaction.creditType,
        "transactionId":each_transaction.transactionId,
        "orderId":each_transaction.orderId,
        "createdOn":str(each_transaction.createdOn),
        "customerEmail":each_transaction.customerEmail,
        "customerName":each_transaction.customerName,
        "customerPhonenumber":each_transaction.customerPhonenumber,
        "errorMessage":each_transaction.errorMessage,
        "bankRefId":each_transaction.bankRefId,
        "cardmasked":each_transaction.cardmasked,
        "productName":each_transaction.productName,
        "customerVpa":each_transaction.customerVpa,
        "status":each_transaction.status,
        }
        try:
            if each_transaction.commissionCharges:
                transactionDict["commissionCharges"]=each_transaction.commissionCharges
            else:
                commissionCharges = {
                "aggregatorType":"",
                "aggregatorAmount":0,
                "commissionType":"",
                "commissionAmount":"",
                "chargeType":"FLAT",
                "chargeValue":0,
                "gstValue":0,
                "tdsValue":0,
                "aggregatorValue":0,
                "commissionValue":0,
                "chargeAmount":"0",
                "transactionAmount":"0",
                "gstInclude":0,
                "gstAmount":"0",
                "tdsInclude":0,
                "tdsAmount":0,
                "priceType":"Fixed",
                "slabId":""
                }
                transactionDict["commissionCharges"]=commissionCharges
        except Exception as e:
            commissionCharges = {
            "aggregatorType":"",
            "aggregatorAmount":0,
            "commissionType":"",
            "commissionAmount":"",
            "chargeType":"FLAT",
            "chargeValue":0,
            "gstValue":0,
            "tdsValue":0,
            "aggregatorValue":0,
            "commissionValue":0,
            "chargeAmount":"0",
            "transactionAmount":"0",
            "gstInclude":0,
            "gstAmount":"0",
            "tdsInclude":0,
            "tdsAmount":0,
            "priceType":"Fixed",
            "slabId":""
            }
            transactionDict["commissionCharges"]=commissionCharges
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return transactionDict

@users.route("/wallet_passbook_transactions",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def wallet_passbook_transactions():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        startDate = data.get("startDate","")
        endDate = data.get("endDate","")
        transactionsList = []
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        if startDate and endDate:
            startDate = startDate + " 00:00:00"
            endDate = endDate + " 23:59:59"
            start_date = datetime.datetime.strptime(startDate, "%d-%m-%Y %H:%M:%S")
            end_date = datetime.datetime.strptime(endDate, "%d-%m-%Y %H:%M:%S")

            transactions_queryset = WalletTransactions.objects(userId=userId,createdOn__gte=start_date,createdOn__lte=end_date).order_by("-createdOn").all()
        else:
            transactions_queryset = WalletTransactions.objects(userId=userId).order_by("-createdOn").all()

        for each_transaction in transactions_queryset:
            transactionDict = fetching_transaction_details(each_transaction)
            transactionsList.append(transactionDict)
        data_status["result"] = "Transaction details fetched successfully"
        data_status["responseStatus"] = 1
        data_status["transactionsList"] = transactionsList
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch transaction data!!"
        return data_status


@users.route("/wallet_passbook_transaction_details",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def wallet_passbook_transaction_details():
    data_status = {"responseStatus": 0, "result": ""}
    try:        
        data = request.decrypted_data
        userId = data.get("userId","")
        transactionId = data.get("transactionId","")
        transactionDict = {}
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        if not transactionId and not userId:
            data_status["result"]="Required fields are missing!!"
            return data_status
        transaction_queryset = WalletTransactions.objects(userId=userId,id=transactionId).first()
        if not transaction_queryset:
            data_status["result"]="Invalid transaction id!!"
            return data_status

        transactionDict = fetching_transaction_details(transaction_queryset)

        data_status["result"] = "Transaction details fetched successfully"
        data_status["responseStatus"] = 1
        data_status["transactionDetails"] = transactionDict
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch transaction data!!"
        return data_status

@users.route("/withdrawal_transaction_details",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def withdrawal_transaction_details():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        transactionId = data.get("transactionId","")
        transactionDict = {}
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        transaction_queryset = FundTransfers.objects(userId=userId,id=transactionId).first()
        if not transaction_queryset:
            data_status["result"]="Invalid transaction id!!"
            return data_status

        transactionDict = fetching_payouts_details(transaction_queryset)

        data_status["result"] = "Transaction details fetched successfully"
        data_status["responseStatus"] = 1
        data_status["transactionDetails"] = transactionDict
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch transaction data!!"
        return data_status


@users.route("/view_merchant_wallet_balance", methods=["POST"])
@encrypt_decrypt_after_login
def view_merchant_wallet_balance():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    if userId:
        try:
            user_queryset = Users.objects(id=userId,status=1).only("walletBalance","payoutBalance","commissionBalance").first()
            if not user_queryset:
                data_status["result"]="Invalid merchant id!!"
                return data_status

            data_status["result"] = "Merchant wallet balance fetched successfully"
            data_status["responseStatus"] = 1
            data_status["walletBalance"] = formatINR("{:.2f}".format(float(user_queryset.walletBalance)))
            data_status["payoutBalance"] = formatINR("{:.2f}".format(float(user_queryset.payoutBalance)))
            data_status["commissionBalance"] = formatINR("{:.2f}".format(float(user_queryset.commissionBalance)))
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to get merchant wallet balance!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status


@users.route("/payout_charges_calculation", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def payout_charges_calculation():
    data_status = {"responseStatus": 0, "result":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        amount = data.get("amount",0)
        paymentMode = data.get("paymentMode","")
        if not userId and not amount and not paymentMode:
            data_status["result"]="Required fields are missing!!"
            return data_status

        user_queryset = Users.objects(id=userId,status=1).first()
        if not user_queryset.patternId:
            data_status["result"]="No payment gateways available!!"
            return data_status
        
        payment_mode_queryset = PaymentMode.objects(paymentMode=paymentMode).first()
        paymentModeId = str(payment_mode_queryset.id)
        sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=paymentMode).first()
        subPaymentModeId = str(sub_payment_mode_queryset.id)
        patternId = str(user_queryset.patternId.id)
        chargeAmount=0
        gstAmount=0
        tdsAmount=0
        withdrawalBalance=0
        totalCharges=0

        commissionCharges = slab_calculation_for_payout_merchant(amount,paymentModeId,subPaymentModeId,patternId)
        if commissionCharges.get("slabId") == None:
            slabId = None
            transactionAmount = amount
        else:
            slabId = commissionCharges.get("slabId")
            transactionAmount = float(commissionCharges.get("transactionAmount"))
            totalCharges=float(transactionAmount)-float(amount)

        print(transactionAmount,"transactionAmount")    
        print(totalCharges,"totalCharges")  
        print(user_queryset.payoutBalance,"user_queryset.payoutBalance")    
        print(user_queryset.capBalance,"user_queryset.capBalance")


        if float(user_queryset.payoutBalance)<(float(transactionAmount)+float(user_queryset.capBalance)):
            withdrawalBalance=float(user_queryset.payoutBalance)-float(user_queryset.capBalance)-float(totalCharges)
            data_status['result']="Your available withdrawal balance is "+str(formatINR("{:.2f}".format(float(withdrawalBalance))))+", and the charges applied are "+str(formatINR("{:.2f}".format(float(totalCharges))))+"."
            return data_status
        else:
            data_status['responseStatus']=1
            data_status['totalCharges']=str(formatINR("{:.2f}".format(float(totalCharges))))
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to get merchant wallet balance!!"
        return data_status

@users.route("/payin_charges_calculation", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def payin_charges_calculation():
    data_status = {"responseStatus": 0, "result":""}
    try:
        encryptedBody = request.json.get("encryptedBody")
        ivKey = request.json.get("ivKey")
        if not encryptedBody and not ivKey:
            data_status["result"]="Required fields are missing!!3"
            return data_status

        try:
            decryptResponse=request.decrypted_data
            print(decryptResponse,"((((((((((((((((decryptResponse decryptResponse))))))))))))))))")
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Invalid Request"
            return data_status


        userId = decryptResponse.get("userId","")
        amount = decryptResponse.get("amount",0)
        paymentMode = decryptResponse.get("paymentMode","")
        subPaymentMode = decryptResponse.get("subPaymentMode","")
        instantSettlement = decryptResponse.get("instantSettlement",2)

        if not userId or not amount or not paymentMode or not subPaymentMode or instantSettlement not in [0,1,2]:
            data_status["result"]="Required fields are missing!!"
            return data_status

        user_queryset = Users.objects(id=userId,status=1).first()
        if not user_queryset.patternId:
            data_status["result"]="No payment gateways available!!11"
            return data_status
        siteTitle=str(user_queryset.siteTitle)
        siteId=""
        instantSettlementtype=None
        if instantSettlement==0 or instantSettlement==1:
            if instantSettlement==0:
                instantSettlementtype=True
            else:
                instantSettlementtype=False
        else:
            if siteTitle:
                site_queryset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
                if not site_queryset:
                    data_status["result"]="No payment gateways available!!22"
                    return data_status
                siteId=str(site_queryset.id)
                if site_queryset and site_queryset.defaultSettlement!=None and instantSettlement==2:
                    instantSettlementtype =site_queryset.defaultSettlement

        payment_mode_queryset = PaymentMode.objects(paymentMode=paymentMode).first()
        paymentModeId = str(payment_mode_queryset.id)
        sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=subPaymentMode).first()
        subPaymentModeId = str(sub_payment_mode_queryset.id)
        patternId = str(user_queryset.patternId.id)
        chargeAmount=0
        gstAmount=0
        tdsAmount=0
        withdrawalBalance=0
        transactionAmount=amount
        totalCharges=0
        if float(amount)> 0 and paymentModeId and subPaymentModeId and patternId:
            if instantSettlementtype==None:
                get_site_paymentgateway=SiteAssignPaymentgateways.objects(siteId=siteId,paymentModeId=paymentModeId,subPaymentModeId=subPaymentModeId,transactionApiId__ne=None,status=1).first()
                if not get_site_paymentgateway:
                    data_status["result"]="No payment gateways available!!33"
                    return data_status
                instantSettlementtype=get_site_paymentgateway.instantSettlement

            commissionCharges = slab_calculation_for_payin_merchant(amount,paymentModeId,subPaymentModeId,patternId,instantSettlementtype)
            if commissionCharges.get("slabId") == None:
                slabId = None
                transactionAmount = amount
            else:
                slabId = commissionCharges.get("slabId")
                transactionAmount = float(commissionCharges.get("transactionAmount"))
                gstAmount = float(commissionCharges.get("gstAmount"))
                chargeAmount = float(commissionCharges.get("chargeAmount"))
                totalCharges=float(amount)-float(transactionAmount)
        data_status['responseStatus']=1
        data_status['transactionAmount']=str(formatINR("{:.2f}".format(float(transactionAmount))))
        data_status['gstAmount']=str(formatINR("{:.2f}".format(float(gstAmount))))
        data_status['chargeAmount']=str(formatINR("{:.2f}".format(float(chargeAmount))))
        data_status['totalCharges']=str(formatINR("{:.2f}".format(float(totalCharges))))
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to get merchant wallet balance!!"
        return data_status


@users.route("/payout_transfer", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def payout_transfer():
    data_status = {"responseStatus": 0, "result":""}
    try:
        data = request.decrypted_data
        random_number = str(random_digit_generate(15))
        accountNumber=""
        accountIFSCCode=""
        beneficiaryName=""
        bankId=""
        beneficiaryPhone=""
        beneficiaryMail=""
        userId = data.get("userId","")
        amount = data.get("amount",0)
        accountNumber = data.get("accountNumber","")
        accountIFSCCode = data.get("ifscCode","")
        beneficiaryName = data.get("beneficiaryName","")
        bankId = data.get("bankId","")
        otpCheckId = data.get("otpCheckId","")
        skipOtp = data.get("skipOtp",False)
        narration = data.get("narration","transfer")
        paymentMode = data.get("paymentMode","")
        beneficiaryMail = data.get("beneficiaryMail","")
        beneficiaryPhone = data.get("beneficiaryPhone","")
        siteTitle = data.get("siteTitle","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    # 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

    transactionAPIId = ""
    requestData = [data]

    # # Here Create Client Logs Table
    save_client_table = save_client_logs_data(userId,"payout","fund_transfer","payout_transfer",transactionAPIId,requestData,client_ip,"app")

    print(request.json,"((((((((((payout_transfer request))))))))))")
    
    try:
        startDate = datetime.datetime.now()
        availability_check = check_transaction_availability(startDate, "payout")
        if availability_check.get('responseStatus')==0:
            data_status["result"]="Service Provider is not available. Please try after sometime."
            return data_status

        if amount and userId:
            if skipOtp==False:
                if otpCheckId=="":
                    data_status["result"]="Invalid Request."
                    return data_status
                otpcheck_querryset=OtpChecks.objects(userId=str(userId),id=str(otpCheckId),status=1).first()
                if not otpcheck_querryset:
                    data_status["result"]="Invalid Request."
                    return data_status
                otpcheck_querryset.update(status=2)

            merchant_queryset = Users.objects(id=str(userId),status=1).first()
            if not merchant_queryset:
                data_status["result"]="Invalid merchant id!!"
                return data_status

            merchant_kyc_queryset = UserKYC.objects(userId=str(merchant_queryset.id),status=1).first()

            fundTransferType = "Instant"
            accountType = "bank" # "bank","upi"
            overallCommissionAmount = 0

            if beneficiaryMail=="":
                beneficiaryMail = merchant_queryset.email
            if beneficiaryPhone=="":
                beneficiaryPhone = merchant_queryset.phoneNumber
            if beneficiaryName=="":
                beneficiaryName = merchant_queryset.fullName

            if merchant_queryset.merchantType=="customer":
                beneficiaryName = merchant_queryset.fullName
                accountNumber = merchant_kyc_queryset.bankAccountNumber
                accountIFSCCode = merchant_kyc_queryset.ifscCode
                bankId = str(merchant_kyc_queryset.bankId.id)
            elif not accountNumber and not beneficiaryName and not accountIFSCCode:
                data_status["result"]="Invalid account Details."
                return data_status

            DeclinedList=["card","cards","credit card","credit cards","creditcard","creditcards","credit","credits","cc","","creditcardsystem"]
            if beneficiaryName.lower() in DeclinedList or "card" in beneficiaryName.lower() or "credit" in beneficiaryName.lower():
                invalidbenny_table=InvalidBenificiaryLogs(
                    userId=str(merchant_queryset.id),
                    accountNumber=accountNumber,
                    beneficiaryName=str(beneficiaryName),
                    ifscCode=accountIFSCCode,
                    status=1
                    ).save()
                data_status["result"] = "Invalid Account Number."
                return data_status

            uniqueRequestNumber = ""
            narration = narration
            bankBranch = ""
            paymentMode = paymentMode # "IMPS"
            

            masked_account_number = mask_account_number(accountNumber)

            check_kyc_status = merchant_kyc_status(str(merchant_queryset.id))
            if check_kyc_status.get("responseStatus") != 1:
                data_status["result"]="Merchant KYC is not completed please contact to admin!!"
                return data_status

            kycStatus = check_kyc_status.get("merchantKycDetails", {}).get("kycStatus")
            if kycStatus == False:
                data_status["result"]="Merchant KYC is not completed please contact to admin!!"
                return data_status

            ################################################ Checking For Velocity Rule Engine Conditions Code ###################################################
            # velocity_rule_check = check_payout_velocity_rule_engine_conditions(userId,amount,accountNumber)
            # if velocity_rule_check.get("responseStatus") == 0:
            #     data_status["result"]=velocity_rule_check.get("result")
            #     return data_status
            ######################################################################################################################################################

            master_ifsc_queryset = MasterIFSCBank.objects(id=bankId,status=1).first()
            if not master_ifsc_queryset:
                data_status["result"]="Invalid bank id!!"
                return data_status
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset.patternId:
                data_status["result"]="No payment gateways available!!"
                return data_status
            transactionAPIId = str(user_queryset.patternId.payoutPaymentGatewayId.id)
            if not transactionAPIId:
                data_status["result"]="No payment gateways available!!"
                return data_status
            payout_gate_way_queryset = TransactionAPI.objects(id=transactionAPIId,status=1).first()
            if not payout_gate_way_queryset:
                data_status['result']="Payout option is diabled.Please contact to admin"
                return data_status
            # Here Update some data in client log
            save_client_table.update(transactionAPIId=ObjectId(transactionAPIId))


            check_transaction_limits = merchant_transaction_limit_settings("Payout",transactionAPIId,userId,amount)
            if check_transaction_limits.get("responseStatus") == 0:
                data_status['result']=check_transaction_limits.get("result")
                return data_status

            # pgOrderId = str(user_queryset.merchantUniqueNumber)+"-"+str(random_number)
            merchant_reference_number = random_number

            merchantUniqueNumber=str(user_queryset.merchantUniqueNumber)
            mid_extracted = merchantUniqueNumber[1:].lstrip("0")
            pgOrderId=str(transaction_id_prefix)+str(mid_extracted)+str(merchant_reference_number)

            
            ######################################################### Slab Calculation for Payout ###########################################################################
            payoutPaymentGatewayId = transactionAPIId
            payment_mode_queryset = PaymentMode.objects(paymentMode="Fundtransfer",status=1).first()
            if not payment_mode_queryset:
                data_status['result']="Payment mode not available"
                return data_status
            paymentModeId = str(payment_mode_queryset.id)
            sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=paymentMode,status=1).first()
            if not sub_payment_mode_queryset:
                data_status['result']="Payment mode not available"
                return data_status

            subPaymentModeId = str(sub_payment_mode_queryset.id)
            patternId = str(user_queryset.patternId.id)
            beneficiary_qryset=Beneficiaries.objects(accountNumber=accountNumber,userIdsList__in=[userId])
            beneficiary_check_qryset=beneficiary_qryset.filter().first()
            if not beneficiary_check_qryset:
                data_status['result']="Invalid Account Details"
                return data_status
            if payout_gate_way_queryset.preAuthorization==True:
                beneficiary_qryset_filter=beneficiary_qryset.filter(Q(beneCodeList__elemMatch={"transactionApiId": str(transactionAPIId)})).first()
                benecode=""
                beneCodeList=[]
                if beneficiary_qryset_filter:
                    beneCodeList=beneficiary_qryset_filter.beneCodeList
                    for each_benecode in beneCodeList:
                        if each_benecode.transactionApiId==transactionAPIId and each_benecode.status=="Active":
                            benecode=each_benecode.beneCode

                if benecode=="":
                    data_status["result"]="Service provider not available. Please try after sometime."
                    return data_status

            ############################################################# Slab Calculation For Payout #######################################################################
            commissionCharges = slab_calculation_for_payout_merchant(amount,paymentModeId,subPaymentModeId,patternId)
            print("commissionCharges",commissionCharges)
            if commissionCharges.get("slabId") == None:
                slabId = None
                transactionAmount = amount
            else:
                slabId = commissionCharges.get("slabId")
                transactionAmount = float(commissionCharges.get("transactionAmount"))

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

            ############################################################# Aggregator Calculation For Payout #######################################################################
            overallCommissionAmount =0
            chargeAmount =0
            aggregatorCharges={}
            createdOn = datetime.datetime.now()
            date_format = "%m%Y-%H%M%S%f"
            invoiceId = createdOn.strftime(date_format)
            
            aggregatorCharges = aggregator_calculation_for_payout(amount,paymentModeId,subPaymentModeId,transactionAPIId)
            if aggregatorCharges == {} or aggregatorCharges.get("apiSetupchargeId") == None:
                apiSetupchargeId = None
                chargeAmount = 0
            else:
                apiSetupchargeId = aggregatorCharges.get("apiSetupchargeId")
                chargeAmount = float(aggregatorCharges.get("chargeAmount"))
            if commissionCharges:
                overallCommissionAmount = float(commissionCharges.get("chargeAmount")) - float(chargeAmount)
            else:
                overallCommissionAmount=float(overallCommissionAmount) - float(chargeAmount)

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

            bank_branch=""
            transactionId=random_digit_generate(15)
            if float(user_queryset.payoutBalance)<(float(transactionAmount)+float(user_queryset.capBalance)):
                insufficient_table = InsufficientBalanceLogs(
                    userId=userId,
                    orderId=merchant_reference_number,
                    orderAmount=amount,
                    walletAmount=float(merchant_queryset.payoutBalance),
                    createdOn=datetime.datetime.now(),
                    status=1
                    ).save()
                data_status["result"]="Insufficient balance!!"
                return data_status

            balance_check=payout_balance_check(transactionAPIId)
            print(balance_check,"balance_check")
            if balance_check.get('responseStatus')==0:
                data_status["result"]="Service provider not available. Please try after sometime."
                return data_status

            apiBalance=balance_check.get('balance')
            
            
            tsingleTxnUpperLimit=float(check_transaction_limits.get('singleTxnUpperLimit'))
            availableApiBalance=float(apiBalance)-float(amount)
            if tsingleTxnUpperLimit!=0 and float(tsingleTxnUpperLimit)>=float(availableApiBalance):
                try:
                    sender_mail_query = SenderMails.objects(status=1,mailType="Payout_Insuficiant").first()
                    if sender_mail_query:
                        sapiName=str(payout_gate_way_queryset.apiName)
                        savilablebalance=formatINR("{:.2f}".format(float(availableApiBalance)))
                        if sender_mail_query.mobileNumber:
                            smobileNumber=','.join(sender_mail_query.mobileNumber)
                            smsResponse=send_sms(smobileNumber,"Insufficient_Funds",userName=sapiName,Reason="",amount=savilablebalance)
                        if sender_mail_query.mailsList:
                            mailsList=','.join(sender_mail_query.mailsList)
                            print(mailsList,"mailsList")
                            trnsactionDate = datetime.datetime.now().astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p")
                            mail_subject = "Low balance alert from " + sapiName + "."
                            recipients_list = [mailsList]
                            template_name = "emails/insufficientfunds.html" 
                            mail_data = {
                            "amount":savilablebalance,
                            "apiName":sapiName,
                            "transactionDate":trnsactionDate
                            }
                            mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                except Exception as e:
                    app.logger.error(traceback.format_exc())
                    pass

            if float(apiBalance) == 0 or float(apiBalance)<float(amount):
                data_status["result"]="Service provider not available. Please try after sometime."
                return data_status

            prevuserquery_set = Users.objects(id=str(userId),payoutBalance__gte=float(transactionAmount)).modify(dec__payoutBalance=float(transactionAmount),new=True)
            if prevuserquery_set==None:
              data_status["result"]="Insufficient balance!!"
              return data_status
            updateAmount = prevuserquery_set.payoutBalance
            actuallBalance = float(updateAmount)+float(transactionAmount)
            

            fund_transfer_table = FundTransfers(
                userId=userId,
                slabId=slabId,
                transactionAPIId=transactionAPIId,
                bankId=bankId,
                bankName=str(master_ifsc_queryset.bankName),
                merchantReferenceNumber=merchant_reference_number,
                fundTransferType=fundTransferType,
                accountType=accountType,
                apiType="app",
                bankBranch=bankBranch,
                accountNumber=accountNumber,
                accountIFSCCode=accountIFSCCode,
                beneficiaryName=beneficiaryName,
                uniqueRequestNumber=uniqueRequestNumber,
                amount=round(float(amount),2),
                grandTotal=round(float(transactionAmount),2),
                transferType="Debit",
                beneficiaryMail=beneficiaryMail,
                beneficiaryPhone=beneficiaryPhone,
                paymentMode=paymentMode,
                narration=narration,
                commissionCharges=commissionCharges,
                createdOn=datetime.datetime.now(),
                pgOrderId=pgOrderId,
                statusCheckId = pgOrderId,
                transactionUniqueId=transactionId,
                userType="user",
                siteTitle=siteTitle,
                previousBalance = round(float(actuallBalance),2),
                currentBalance = round(float(updateAmount),2),
                aggregatorCharges=aggregatorCharges,
                overallCommissionAmount=round(float(overallCommissionAmount),2),
                status=2
                )
            save_table = fund_transfer_table.save()
            instantTransferId = str(save_table.id)
            fund_transfer_queryset = FundTransfers.objects(id=instantTransferId).first()

            # Here Routing Switch Table Log Save and Update
            currentDate = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
            routing_switch_counts_queryset = RoutingSwitchCounts.objects(userId=userId,transactionAPIId=transactionAPIId,createdOn=currentDate).first()
            if routing_switch_counts_queryset:
                numberOfFails = routing_switch_counts_queryset.numberOfFails
                numberOfSuccess = routing_switch_counts_queryset.numberOfSuccess

            else:
                save_routing_switch_table=save_routing_switch_logs_data(userId,"payout",str(transactionAPIId))

            bank_name = master_ifsc_queryset.bankName

            if user_queryset.patternId.payoutPaymentGatewayId.code == "AccurePay_Payout":
                get_api_key = ""
                get_salt = ""
                get_base_url = ""
                for each_key in user_queryset.patternId.payoutPaymentGatewayId.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()

                
                ############################################ Accurepay Payout Fundtransfer Functionality Code #######################################################
                paymentgatewayresponseDict = accurepay_payout_fundtransfer(get_api_key,get_salt,get_base_url,userId,transactionAPIId,client_ip,amount,paymentMode,beneficiaryName,accountNumber,accountIFSCCode,bank_name,pgOrderId,"app")
                ######################################################################################################################################################

            elif user_queryset.patternId.payoutPaymentGatewayId.code == "WowPe_Payout":
                get_client = ""
                get_secret = ""
                get_base_url = ""

                for each_key in user_queryset.patternId.payoutPaymentGatewayId.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,beneficiaryPhone,amount,paymentMode,accountNumber,accountIFSCCode,beneficiaryName,pgOrderId,userId,transactionAPIId,client_ip,"app")
                ##########################################################################################################
              
              
            elif user_queryset.patternId.payoutPaymentGatewayId.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()
                    if get_key == "remitter_mobile_number":
                        remitter_mobile_number = 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,beneficiaryPhone,amount,paymentMode,accountNumber,accountIFSCCode,beneficiaryName,bank_branch,pgOrderId,userId,transactionAPIId,client_ip,"app",narration,beneficiaryMail)
                
                # benivalidationCheck = idfc_benivalidation(source,kid,aud_url,client_id,auth_url,grant_type,scope,client_assertion_type,secretKey,accountIFSCCode,accountNumber,debitAcountNumber,remitterName,remitter_mobile_number,narration,transactionId)

                # if benivalidationCheck.get("responseStatus") == 1:
                #   creditorAccountId = benivalidationCheck.get("creditorAccountId")
                #   beniValidationData = benivalidationCheck.get("beniValidationData")
                #   creditorName = benivalidationCheck.get("creditorName")
                #   transactionReferenceNumber = benivalidationCheck.get("transactionReferenceNumber")

                #   benificiary_account_table = BenificiaryAccounts(
                #       userId=userId,
                #       creditorAccountNumber=creditorAccountId,
                #       ifscCode=accountIFSCCode,
                #       creditorName=creditorName,
                #       transactionReferenceNumber=transactionReferenceNumber,
                #       name=name,
                #       bankId=bankId,
                #       beniValidationData=beniValidationData,
                #       createdOn=datetime.datetime.now(),
                #       status=1
                #       ).save()

                #   paymentgatewayresponseDict = idfc_payout_fundtransfer(client_id,secretKey,kid,get_base_url,aud_url,auth_url,grant_type,scope,source,client_assertion_type,debitAcountNumber,remitterName,beneficiaryPhone,amount,paymentMode,accountNumber,accountIFSCCode,beneficiaryName,bank_branch,transactionId,userId,transactionAPIId,client_ip,"app",narration,beneficiaryMail)
                # else:
                #   data_status["result"]=benivalidationCheck.get("message")
                #   return data_status
                ################################################################################################################################################################
            elif user_queryset.patternId.payoutPaymentGatewayId.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_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,beneficiaryName,userId,accountIFSCCode,paymentMode,benecode,pgOrderId,accountNumber,bank_name)
                ################################################################################################################################################################
                    
            else: 
                data_status["result"]="Our banking partner server is down please try after sometime!!"
                save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
                # For count update number of failures in routing switch counts table
                if routing_switch_counts_queryset:
                    existingFailuresCount = routing_switch_counts_queryset.numberOfFails
                    updateFailuresCount = existingFailuresCount+1
                    routing_switch_counts_queryset.update(numberOfFails=updateFailuresCount)
                else:
                    save_routing_switch_table.update(numberOfFails=1)
                return data_status


            ################################################## Common Code for all Payment Gateways ##########################################
            if paymentgatewayresponseDict.get("responseStatus") == 1:
                if paymentgatewayresponseDict.get("bank_reference_number"):
                    bank_reference_number = paymentgatewayresponseDict.get("bank_reference_number")
                else:
                    bank_reference_number = fund_transfer_queryset.bankReferenceNumber

                transactionData = paymentgatewayresponseDict.get("transactionData")

                # latest_fund_transfer_queryset = FundTransfers.objects(id=instantTransferId).first()
                # previousstatus=latest_fund_transfer_queryset.status
                # if paymentgatewayresponseDict.get("transactionstatus")==0 or paymentgatewayresponseDict.get("transactionstatus")==4:
                #     getrefund_record=FundTransfers.objects(transactionUniqueId=latest_fund_transfer_queryset.merchantReferenceNumber,userId=str(userId)).count()
                #     if (previousstatus==1 or previousstatus==2) and getrefund_record==0:
                #         userbalance_queryset = Users.objects(id=str(userId)).modify(inc__payoutBalance=float(transactionAmount),new=True)
                #         userCurrentBalance = userbalance_queryset.payoutBalance
                #         userPreviousBalance = float(userCurrentBalance)-float(transactionAmount)

                #         # balanceResult=user_payout_balance_update(str(userId),float(transactionAmount),"Credit",str(transactionAPIId))
                #         # if balanceResult.get('responseStatus')==0:
                #         #     data_status["result"]="Unable to connect with server. Please Try again."
                #         #     return data_status
                        
                #         merchantReferenceNumber=random_digit_generate(15)
                #         refund_transfer_table = FundTransfers(
                #             userId=str(userId),
                #             transactionAPIId=transactionAPIId,
                #             fundTransferId=str(latest_fund_transfer_queryset.id),
                #             bankId=bankId,
                #             merchantReferenceNumber=merchantReferenceNumber,
                #             transactionUniqueId=merchant_reference_number,
                #             pgOrderId=pgOrderId,
                #             fundTransferType="instant",
                #             accountType="bank",
                #             apiType="web",
                #             slabId=slabId,
                #             transferType="Refund",
                #             bankBranch=bankBranch,
                #             accountNumber=accountNumber,
                #             accountIFSCCode=accountIFSCCode,
                #             beneficiaryName=beneficiaryName,
                #             uniqueRequestNumber=uniqueRequestNumber,
                #             amount=round(float(amount),2),
                #             grandTotal=round(float(transactionAmount),2),
                #             previousBalance = round(float(userPreviousBalance),2),
                #             currentBalance = round(float(userCurrentBalance),2),
                #             beneficiaryMail=beneficiaryMail,
                #             bankReferenceNumber=bank_reference_number,
                #             beneficiaryPhone=beneficiaryPhone,
                #             paymentMode=paymentMode,
                #             transactionDate=paymentgatewayresponseDict.get("transactionDate"),
                #             requestData=paymentgatewayresponseDict.get("requestData"),
                #             narration=narration,
                #             createdOn=datetime.datetime.now(),
                #             userType="user",
                #             status=5,
                #             transactionData=transactionData,
                #             commissionCharges=commissionCharges
                #             )
                #         save_table = refund_transfer_table.save()
                finalStatus=2
                if paymentgatewayresponseDict.get("transactionstatus")==1:
                    finalStatus=1
                fund_transfer_queryset.update(
                    transactionData=transactionData,
                    errorMessage=paymentgatewayresponseDict.get("messages"),
                    transactionUniqueId=paymentgatewayresponseDict.get("transaction_id"),
                    bankReferenceNumber=bank_reference_number,
                    transactionDate=paymentgatewayresponseDict.get("transactionDate"),
                    requestData=paymentgatewayresponseDict.get("requestData"),
                    status=finalStatus
                    )

                try:
                    if skipOtp==False:
                        merchantName = str(user_queryset.fullName)
                        trnsactionDate = datetime.datetime.now().astimezone(ist_timezone).strftime("%d-%m-%Y %I:%M %p")
                        mail_subject = "Instant fund transfer initiated from " + merchantName + "."
                        recipients_list = [admin_recieve_email]
                        template_name = "emails/instant_fundtransfer.html"
                        mail_data = {
                        "merchantName":merchantName,
                        "accountNumber":accountNumber,
                        "bankName":bank_name,
                        "ifscCode":accountIFSCCode,
                        "amount":formatINR("{:.2f}".format(float(amount))),
                        "transactionId":paymentgatewayresponseDict.get("transaction_id"),
                        "orderId":merchant_reference_number,
                        "transactionDate":trnsactionDate,
                        }
                        domainUrl=domain
                        mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                        merchantemail = str(user_queryset.email)
                        merchant_mail_subject = "Fund Transaction Alert From Graam Pay"
                        merchant_recipients_list = [merchantemail]

                        mailoutputData = send_asynchronous_email(merchant_mail_subject, merchant_recipients_list, template_name, mail_data)

                except Exception as e:
                    app.logger.error(traceback.format_exc())
                    pass

                data_status["responseStatus"] = 1
                data_status["result"] = "Payout transfer was successful!"
                data_status["transactionId"]=instantTransferId
                # 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(amount)

                    routing_switch_counts_queryset.update(numberOfSuccess=updateSuccessCount,maxVolume=updateSuccessAmount)
                else:
                    save_routing_switch_table.update(numberOfSuccess=1,maxVolume=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())

                # For count update number of failures in routing switch counts table
                if routing_switch_counts_queryset:
                    existingFailuresCount = routing_switch_counts_queryset.numberOfFails
                    updateFailuresCount = existingFailuresCount+1

                    routing_switch_counts_queryset.update(numberOfFails=updateFailuresCount)
                else:
                    save_routing_switch_table.update(numberOfFails=1)
                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"] = "Instant transfer was unsuccessful!!"
        exceptionData = [traceback.format_exc()]
        exception_log_table = save_exception_logs_data(userId,"payout","fund_transfer","payout_instant_transfer",exceptionData,client_ip,"web")
        save_client_table.update(responseData=[data_status],responseDate=datetime.datetime.now())
        return data_status   

#OTP Generate API
@users.route("/generate_fundtransfer_otp",methods=["GET","POST"])
@encrypt_decrypt_after_login
def generate_fundtransfer_otp():
    data_status = {"responseStatus": 0, "result": "","otpCheckId":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        reason = data.get("reason","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    try:
        if userId and reason:
            user_queryset = Users.objects(id=userId,status=1).only("id","email","phoneNumber","fullName").first()
            if user_queryset:
                phoneNumber = user_queryset.phoneNumber
                smsResponse=send_sms(phoneNumber, "Transaction_Verify_OTP",userName="",Reason="",amount="")
                print(phoneNumber,"((((((((((((phoneNumber SMS))))))))))))")
                print(smsResponse,"((((((((((((smsResponse))))))))))))")
                otpCode=smsResponse.get('otp')
                otpcheck_queryset=OtpChecks(
                    userId=userId,
                    otpCode=str(otpCode),
                    phoneNumber=str(phoneNumber),
                    attempts=0,
                    status=0,
                    createdOn=datetime.datetime.now(),
                    otpReason=reason
                    ).save()
                otpCheckId=str(otpcheck_queryset.id)
                data_status["responseStatus"] = 1
                data_status["otpCheckId"] = otpCheckId
                data_status["result"]="Otp generated successfully"
                try:
                    email=user_queryset.email
                    if email:
                        merchantName = str(user_queryset.fullName)
                        mail_subject = "Otp verification for GraamPay Fundtransfer!"
                        recipients_list = [email]
                        template_name = "emails/otpverification.html"
                        mail_data = {
                        "merchantName":merchantName,
                        "otpCode":smsResponse.get('otp'),
                        }
                        mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                except Exception as e:
                    pass
                return data_status
            else:
                data_status["result"]="Invalid Merchant."
                return data_status
        else:
            data_status["result"]="Required fields are missing."
            return data_status      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to generate OTP."
        return data_status

#OTP Generate API
@users.route("/resend_fundtransfer_otp",methods=["GET","POST"])
@encrypt_decrypt_after_login
def resend_fundtransfer_otp():
    data_status = {"responseStatus": 0, "result": "","otpCheckId":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        otpCheckId = data.get("otpCheckId")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    try:
        if otpCheckId and userId:
            user_queryset = Users.objects(id=userId,status=1).only("id","email","phoneNumber","fullName").first()
            if user_queryset:
                phoneNumber = user_queryset.phoneNumber
                smsResponse=send_sms(phoneNumber, "Transaction_Verify_OTP",userName="",Reason="",amount="")
                print(phoneNumber,"((((((((((((phoneNumber SMS in Resend))))))))))))")
                print(smsResponse,"((((((((((((smsResponse Resend))))))))))))")
                otpCode=smsResponse.get('otp')
                otpcheck_querryset=OtpChecks.objects(userId=str(userId),id=str(otpCheckId)).first()
                if otpcheck_querryset:
                    otpcheck_querryset.update(status=0,otpCode=str(otpCode))
                    otpCheckId=str(otpcheck_querryset.id)
                    data_status["responseStatus"] = 1
                    data_status["otpCheckId"] = otpCheckId
                    data_status["result"]="Otp generated successfully"
                    try:
                        email=user_queryset.email
                        if email:
                            merchantName = str(user_queryset.fullName)
                            mail_subject = "Otp verification for GraamPay Fundtransfer!"
                            recipients_list = [email]
                            template_name = "emails/otpverification.html"
                            mail_data = {
                            "merchantName":merchantName,
                            "otpCode":smsResponse.get('otp'),
                            }
                            mailoutputData = send_asynchronous_email(mail_subject, recipients_list, template_name, mail_data)
                    except Exception as e:
                        pass
                    return data_status
                else:
                    data_status["result"]="Invalid Request."
                    return data_status
            else:
                data_status["result"]="Invalid Merchant."
                return data_status
        else:
            data_status["result"]="Required fields are missing."
            return data_status      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to generate OTP."
        return data_status

@users.route("/check_fundtransfer_otp",methods=["POST"])
@encrypt_decrypt_after_login
def check_fundtransfer_otp():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        otpCheckId = data.get("otpCheckId","")
        otpCode = data.get("otpCode","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    if userId and otpCode and otpCheckId:
        try:
            user_queryset = Users.objects(id=str(userId),status__nin=[2]).only("id","status").first()
            if not user_queryset:
                data_status["result"]="Invalid phone number!!"
                return data_status
            if user_queryset.status == 3:
                data_status["result"]="Your account has been blocked by the admin. Please get in touch with the admin for assistance."
                return data_status
            elif user_queryset.status == 0:
                data_status["result"]="Your account is in-active please contact admin."
                return data_status
            elif user_queryset.status != 1:
                data_status["result"]="Invalid phone number!!"
                return data_status
            
            if otpCheckId!="":
                otpcheck_querryset=OtpChecks.objects(userId=str(userId),id=str(otpCheckId),status=0).first()
                if otpcheck_querryset:
                    attempts=otpcheck_querryset.attempts+1
                    if otpcheck_querryset.otpCode==otpCode:
                        otpcheck_querryset.update(status=1,attempts=attempts)
                        data_status["responseStatus"] = 1
                        data_status["result"] = "Otp validated."
                        return data_status
                    else:
                        otpcheck_querryset.update(attempts=attempts)
                        data_status["result"] = "Invalid Otp."
                        return data_status
                else:
                    data_status["result"] = "Invalid Otp."
                    return data_status
            else:
                data_status["result"] = "Invalid Otp."
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to user login!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status


@users.route("/payout_reports_list", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def payout_reports_list():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        payoutsList = []
        userId = data.get("userId","")
        startDate = data.get("startDate","")
        endDate = data.get("endDate","")
        # payoutType = request.json.get("payoutType","")
        # transferType = request.json.get("transferType","")
        # orderId = request.json.get("orderId","")
        # pageLimit = request.json.get("pageLimit","20")
        # pageOffset = request.json.get("pageOffset","0")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    try:
        # page_start=int(pageOffset)
        # page_end=int(pageOffset)+int(pageLimit)

        if not startDate or not endDate:
            data_status["result"] = "Start date and end date are required!!"
            return data_status

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

        payouts_queryset = FundTransfers.objects(userId=userId,createdOn__gte=startDate,createdOn__lte=endDate,status__in=[0,1,2,4,5]).order_by("-createdOn")
        # for each_payout in payouts_queryset[page_start:page_end]:
        for each_payout in payouts_queryset:
            payoutDict = fetching_payouts_details(each_payout)
            payoutsList.append(payoutDict)
        data_status["responseStatus"] = 1
        data_status["result"] = "Payouts data fetched successful!"
        data_status["payoutsList"]=payoutsList
        data_status["totalPayoutsCount"]=payouts_queryset.count()
        return data_status      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch payouts data!!"
        return data_status

@users.route("/get_user_charges",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def get_user_charges():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        pgId = data.get("pgId","")
        userChargesList = []
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    try:
        merchant_queryset = Users.objects(id=userId,status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid user id!!"
            return data_status

        if not merchant_queryset.patternId:
            data_status["result"]="No payment gateways available!!"
            return data_status

        charges_queryset = SetupChargeCommissions.objects(patternId=str(merchant_queryset.patternId.id),transactionAPIId=pgId,status=1).order_by('-id').all()
        for each_pg_charges in charges_queryset:
            pg_dict = {
            "id":str(each_pg_charges.id),
            "patternId":str(each_pg_charges.patternId.id),
            "patternName":each_pg_charges.patternId.name,
            "paymentModeId":str(each_pg_charges.paymentModeId.id),
            "paymentModeName":each_pg_charges.paymentModeId.paymentMode,
            "subPaymentModeId":str(each_pg_charges.subPaymentModeId.id),
            "subPaymentModeName":each_pg_charges.subPaymentModeId.subPaymentModeType,
            "paymentGatewayId":str(each_pg_charges.transactionAPIId.id),
            "paymentGatewayName":each_pg_charges.transactionAPIId.apiName,
            "transactionType":each_pg_charges.transactionAPIId.transactionType,
            "slabName":each_pg_charges.slabName,
            "priceType":each_pg_charges.priceType,
            "aggregatorType":each_pg_charges.aggregatorType,
            "aggregatorValue":each_pg_charges.aggregatorValue,
            "gstInclude":each_pg_charges.gstInclude,
            "gstValue":each_pg_charges.gstValue,
            "tdsInclude":each_pg_charges.tdsInclude,
            "tdsValue":each_pg_charges.tdsValue,
            "chargeType":each_pg_charges.chargeType,
            "chargeValue":each_pg_charges.chargeValue,
            "chargeType":each_pg_charges.chargeType,
            "priceRangeList":each_pg_charges.priceRangeList
            }
            userChargesList.append(pg_dict)
        data_status["result"] = "Payment gateways charges data fetched successfully!"
        data_status["responseStatus"] = 1
        data_status["userChargesList"] = userChargesList
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to fetch payment gateways charges data!!"
        return data_status

@users.route("/grievance_form_list",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def grievance_form_list():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    assemblyMembersList = []
    departmentsList = []
    try:
        merchant_queryset = Users.objects(id=userId,status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid user id!!"
            return data_status

        assembly_members_queryset = AssemblyMembers.objects(status=1).order_by('-id')
        for each_assembly_member in assembly_members_queryset:
            assembly_member_dict = {
            "id":str(each_assembly_member.id),
            "distictName":each_assembly_member.distictName,
            "assemblyName":each_assembly_member.assemblyName,
            "mlaName":each_assembly_member.mlaName
            }
            assemblyMembersList.append(assembly_member_dict)

        departments_queryset = Departments.objects(status=1).order_by("-id")
        for each_department in departments_queryset:
            departmentDict = {
            "id":str(each_department.id),
            "departmentName":each_department.departmentName,
            "superiorName":each_department.superiorName
            }
            departmentsList.append(departmentDict)

        data_status["result"] = "Grievance data fetched successfully!"
        data_status["responseStatus"] = 1
        data_status["assemblyMembersList"] = assemblyMembersList
        data_status["departmentsList"] = departmentsList
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to fetch grievance data!!"
        return data_status

@users.route("/create_grievance_form",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def create_grievance_form():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        name = data.get("name","")
        mobileNumber = data.get("mobileNumber","")
        complaint = data.get("complaint","")
        departmentId = data.get("departmentId","")
        assemblyMemberId = data.get("assemblyMemberId","")
        pincodeId = data.get("pincodeId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        if userId and name and mobileNumber and complaint and departmentId and assemblyMemberId and pincodeId:
            merchant_queryset = Users.objects(id=userId,status=1).first()
            if not merchant_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status
            acknowledgementNumber=str(random_digit_generate(15))
            grievance_table=Grievances(
                userId=userId,
                name=name,
                acknowledgementNumber=acknowledgementNumber,
                mobileNumber=mobileNumber,
                complaint=complaint,
                departmentId=departmentId,
                assemblyMemberId=assemblyMemberId,
                pincodeId=pincodeId,
                createdOn=datetime.datetime.now(),
                status=0
                ).save()
            
            try:
                departments_queryset=Departments.objects(id=str(departmentId)).first()
                print(str(departments_queryset.departmentName),"str(departments_queryset.departmentName)")
                smsresponse=send_sms(mobileNumber, "Grievance_success","","","",str(departments_queryset.departmentName),acknowledgementNumber)
            except Exception as e:
                pass
            data_status["result"] = "Grievance form submitted successfully!"
            data_status["responseStatus"] = 1
            return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to create grievance data!!"
        return data_status


@users.route("/view_all_grievance_list",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def view_all_grievance_list():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    grievanceList = []
    try:
        merchant_queryset = Users.objects(id=userId,status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid user id!!"
            return data_status

        grievances_queryset = Grievances.objects(userId=userId).order_by('-id')
        for each_grievance in grievances_queryset:
            grievance_dict = {
            "id":str(each_grievance.id),
            "userId":str(each_grievance.userId.id),
            "userName":str(each_grievance.userId.fullName),
            "departmentId":str(each_grievance.departmentId.id),
            "departmentName":str(each_grievance.departmentId.departmentName),
            "assemblyMemberId":str(each_grievance.assemblyMemberId.id),
            "assemblyMemberName":str(each_grievance.assemblyMemberId.assemblyName),
            "name":each_grievance.name,
            "mobileNumber":each_grievance.mobileNumber,
            "complaint":each_grievance.complaint,
            "status":each_grievance.status
            }
            grievanceList.append(grievance_dict)

        data_status["result"] = "Grievance data fetched successfully!"
        data_status["responseStatus"] = 1
        data_status["grievanceList"] = grievanceList
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to fetch grievance data!!"
        return data_status

@users.route("/check_user_tpin",methods=["POST"])
@encrypt_decrypt_after_login
def check_user_tpin():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        tPin = data.get("tPin")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if not userId and not tPin:
        data_status["result"]="Required fields are missing!!"
        return data_status
    try:
        user_queryset = Users.objects(id=userId,tPin=tPin,status=1).first()
        if user_queryset:
            data_status["responseStatus"] = 1
            data_status["result"] = "Tpin is valid!"
            return data_status
        else:
            data_status["result"]="Tpin is invalid!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Tpin is invalid!!"
        return data_status


@users.route("/create_agent",methods=["POST"])
@encrypt_decrypt_after_login
def create_agent():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        fullName = data.get("fullName","")
        phoneNumber = data.get("phoneNumber","")
        email = data.get("email","")
        address = data.get("address","")
        stateId = data.get("stateId","")
        cityId = data.get("cityId","")
        blockPoId = data.get("blockPoId","")
        pincodeId = data.get("pincodeId","")
        password = data.get("password","")
        parentId = data.get("parentId","")
        entityTypeId = data.get("entityTypeId",None)
        merchantType = data.get("merchantType","customer")
        siteTitle = data.get("siteTitle","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if fullName and phoneNumber and email and password and address and stateId and cityId and blockPoId and pincodeId and parentId and entityTypeId and merchantType:
        try:
            user_queryset=None
            check_mobile_number=None
            parent_queryset=None
            if siteTitle:
                print('if page')
                site_queryset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
                if not site_queryset:
                    data_status["result"] = "Invalid App Request.Contact to admin support."
                    return data_status
                user_queryset = Users.objects(email__iexact=email,siteTitle=siteTitle).first()
                if user_queryset:
                    data_status["result"]="Email id already exist!!"
                    return data_status
                check_mobile_number = Users.objects(phoneNumber__iexact=phoneNumber,siteTitle=siteTitle).first()
                if check_mobile_number:
                    data_status["result"]="Phone number already exist!!"
                    return data_status
                parent_queryset = Users.objects(id=parentId,status=1,siteTitle=siteTitle).first()
            else:
                user_queryset = Users.objects(Q(email__iexact=email) & (Q(siteTitle=None) | Q(siteTitle=""))).first()
                if user_queryset:
                    data_status["result"]="Email id already exist!!"
                    return data_status
                check_mobile_number = Users.objects(Q(phoneNumber__iexact=phoneNumber) & (Q(siteTitle=None) | Q(siteTitle=""))).first()
                if check_mobile_number:
                    data_status["result"]="Phone number already exist!!"
                    return data_status
                parent_queryset = Users.objects((Q(id=parentId) & Q(status=1)) & (Q(siteTitle=None) | Q(siteTitle=""))).first()

            if not parent_queryset:
                data_status["result"]="Invalid parent id!!"
                return data_status
            pattern_queryset = Patterns.objects(defaultProfile=True,status__in=[0,1]).first()
            patternId = str(pattern_queryset.id)
            imeiNumber = random_digit_generate(15)
            user_table = Users(
                fullName = fullName,
                phoneNumber  = phoneNumber,
                email  = email,
                password  = generate_password_hash(password), 
                address = address,
                createdOn =datetime.datetime.now(),
                stateId = stateId,
                cityId = cityId,
                blockPoId = blockPoId,
                pincodeId = pincodeId,
                patternId = patternId,
                # userPermissionId = userPermissionId,
                merchantUniqueNumber = generate_next_serial_number(),
                payoutBalance = 0,
                walletBalance = 0,
                merchantType=merchantType,
                entityTypeId=entityTypeId,
                channel="app",
                imeiNumber = imeiNumber,
                parentId=parentId,
                siteTitle=siteTitle,
                status = 1
                )
            save_table = user_table.save()
            agentId = str(save_table.id)
            if agentId:
                user_kyc_table = UserKYC(
                    userId=agentId,
                    channel="app",
                    createdOn =datetime.datetime.now(),
                    submittedDate =datetime.datetime.now(),
                    panStatus="Pending",
                    bankStatus="Pending",
                    aadharStatus="Pending",
                    businessStatus="Pending",
                    agreementVerificationStatus="Pending",
                    videoVerificationStatus="Pending",
                    siteTitle=siteTitle,
                    status = 1
                    )
                save_table = user_kyc_table.save()
            user_queryset = Users.objects(id=agentId).first()
            agentLoginDetails = {
            "id": str(user_queryset.id),
            "stateId": str(user_queryset.stateId.id),
            "userPermissionId": str(user_queryset.patternId.userPermissionId.id),
            "userPermissionName": user_queryset.patternId.userPermissionId.permissionName,
            "fullName": user_queryset.fullName,
            "phoneNumber": user_queryset.phoneNumber,
            "email": user_queryset.email,
            "address": user_queryset.address,
            "createdOn": str(user_queryset.createdOn),
            "status": user_queryset.status,
            "merchantType": user_queryset.merchantType,
            "lastLogin": user_queryset.lastLogin
            }
            if user_queryset.tPin == 0:
                agentLoginDetails["tPin"] = 0
            else:
                agentLoginDetails["tPin"] = user_queryset.tPin

            data_status["responseStatus"] = 1
            data_status["result"] = "Agent signup successfully!"
            data_status["agentLoginDetails"]=agentLoginDetails
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to create agent signup!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status


@users.route("/user_based_commission_transactions",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def user_based_commission_transactions():
    commissionBalance=round(float(0),2)
    data_status = {"responseStatus": 0, "result": "","commissionBalance":commissionBalance}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        startDate = data.get("startDate","")
        endDate = data.get("endDate","")
        transactionsList = []
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        if not userId:
            data_status["result"] = "Transaction details fetched successfully"
            return data_status

        user_queryset=Users.objects(id=str(userId)).first()
        if not user_queryset:
            data_status["result"] = "Transaction details fetched successfully"
            return data_status

        commissionBalance=round(float(user_queryset.commissionBalance),2)
        if startDate and endDate:
            startDate = startDate + " 00:00:00"
            endDate = endDate + " 23:59:59"
            start_date = datetime.datetime.strptime(startDate, "%d-%m-%Y %H:%M:%S")
            end_date = datetime.datetime.strptime(endDate, "%d-%m-%Y %H:%M:%S")
            commission_transactions_queryset = UserCommissions.objects(
                userId=userId,
                createdOn__gte=start_date,
                createdOn__lte=end_date
                ).order_by("-createdOn").all()
        else:
            commission_transactions_queryset = UserCommissions.objects(
                userId=userId,
                ).order_by("-createdOn").all()

        for each_transaction in commission_transactions_queryset:
            transactionDict = fetching_commission_transaction_details(each_transaction)
            transactionsList.append(transactionDict)
        data_status["result"] = "Transaction details fetched successfully"
        data_status["responseStatus"] = 1
        data_status["commissionBalance"] = commissionBalance
        data_status["transactionsList"] = transactionsList
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch transaction data!!"
        return data_status

@users.route("/user_based_transaction_limits",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def user_based_transaction_limits():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        paymentGatewayId = data.get("paymentGatewayId","")
        pgType = data.get("pgType","")
        amount = data.get("amount")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        if pgType and userId and paymentGatewayId and amount:
            check_transaction_limits = merchant_transaction_limit_settings(pgType,paymentGatewayId,userId,amount)
            print(check_transaction_limits,"check_transaction_limits")
            
            data_status["responseStatus"] = check_transaction_limits.get("responseStatus")
            data_status["result"] = check_transaction_limits.get("result")
            return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to check user based transaction limits!!"
        return data_status

@users.route("/check_user_entity", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def check_user_entity():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    if not userId:
        data_status["result"] = "Required fields are missing!!"
        return data_status
    try:
        user_queryset = Users.objects(id=userId,status=1).first()
        if not user_queryset:
            data_status["result"]="Invalid merchant id!!"
            return data_status

        if not user_queryset.entityTypeId:
            data_status["result"]="Please create user entity type in this user!!"
            return data_status

        if user_queryset.entityTypeId.isIndividual == True:
            user_kyc_queryset = UserKYC.objects(userId=str(user_queryset.id)).first()
            if user_kyc_queryset.companyRegistrationStatus == "Approved":
                data_status["responseStatus"]=1
                data_status["result"]="Success!"
                return data_status
            else:
                data_status["responseStatus"]=2
                data_status["result"]="Please go business screen!"
                return data_status
        elif user_queryset.entityTypeId.isIndividual == False:
            data_status["responseStatus"]=2
            data_status["result"]="Please go business screen!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to check user entity!!"
        return data_status


@users.route("/update_bussiness_details", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def update_bussiness_details():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        businessName = data.get("businessName","")
        businessAddress = data.get("businessAddress","")
        companyRegistrationDoc = data.get("companyRegistrationDoc","")
        companyRegistrationStatus = data.get("companyRegistrationStatus","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if userId and companyRegistrationDoc and companyRegistrationStatus and businessName and businessAddress:
        try:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"]="Invalid merchant id!!"
                return data_status

            user_queryset.update(businessName=businessName,businessAddress=businessAddress)

            user_kyc_queryset = UserKYC.objects(userId=str(user_queryset.id)).first()
            if user_kyc_queryset:
                randomNumber = str(random_digit_generate(6))
                pdfFile = upload_pdf_file("companyRegistrationDocs", randomNumber, ".pdf", companyRegistrationDoc)
                if pdfFile:
                    user_kyc_queryset.update(companyRegistrationStatus=companyRegistrationStatus,companyRegistrationDoc=companyRegistrationDoc)

                data_status["responseStatus"]=1
                data_status["result"]="Business details updated successfully!"
                return data_status
            else:
                data_status["result"]="Invalid user id!!"
                return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to update user business details!!"
            return data_status
    else:
        data_status["result"] = "Required fields are missing!!"
        return data_status

@users.route("/check_user_pan_validation",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def check_user_pan_validation():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        panNumber = data.get("panNumber","")
        siteTitle = data.get("siteTitle","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    try:
        if userId and panNumber:
            user_kyc_queryset = UserKYC.objects(userId=userId).first()
            if not user_kyc_queryset:
                data_status["result"]="Invalid user id!!"
            existing_pan_number=None
            if siteTitle:
                print('if page')
                site_queryset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
                if not site_queryset:
                    data_status["result"] = "Invalid App Request.Contact to admin support."
                    return data_status
                existing_pan_number = UserKYC.objects(userId__ne=userId,panNumber=panNumber,siteTitle=siteTitle).first()
            else:
                existing_pan_number = UserKYC.objects((Q(userId__ne=userId) & Q(panNumber=panNumber)) & (Q(siteTitle=None) | Q(siteTitle=""))).first()
            if existing_pan_number:
                data_status["result"]="This pan number is already exist!!"
                return data_status
            else:
                data_status["responseStatus"]=1
                data_status["result"]="Pan is available!"
                return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to check pan validation!!"
        return data_status

@users.route("/check_user_aadhar_validation",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def check_user_aadhar_validation():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        aadharNumber = data.get("aadharNumber","")
        siteTitle = data.get("siteTitle","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        if userId and aadharNumber:
            user_kyc_queryset=None
            if siteTitle:
                site_queryset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
                if not site_queryset:
                    data_status["result"] = "Invalid App Request.Contact to admin support."
                    return data_status
                user_kyc_queryset = UserKYC.objects(userId=userId,siteTitle=siteTitle).first()
            else:
                user_kyc_queryset = UserKYC.objects(Q(userId=userId) & (Q(siteTitle=None) | Q(siteTitle=""))).first()
            
            if not user_kyc_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status

            if siteTitle:
                existing_aadhar_number = UserKYC.objects(userId__ne=userId,aadharNumber=aadharNumber,siteTitle=siteTitle).first()
            else:
                existing_aadhar_number = UserKYC.objects((Q(userId__ne=userId) & Q(aadharNumber=aadharNumber)) & (Q(siteTitle=None) | Q(siteTitle=""))).first()

            if existing_aadhar_number:
                data_status["result"]="This aadhar number is already exist!!"
                return data_status
            else:
                data_status["responseStatus"]=1
                data_status["result"]="Aadhar is available!"
                return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to check aadhar validation!!"
        return data_status

@users.route("/user_kyc_percentage_details", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def user_kyc_percentage_details():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    if not userId:
        data_status["result"] = "User ID is required!"
        return data_status
    
    try:
        user_queryset = Users.objects(id=userId).first()
        if not user_queryset:
            data_status["result"] = "Invalid Request!!"
            return data_status
        user_kyc_queryset = UserKYC.objects(userId=userId).first()
        if not user_kyc_queryset:
            data_status["result"] = "Invalid Request!!"
            return data_status
        profile=25
        businessStatus="Pending"
        try:
            if not user_queryset.entityTypeId:
                profile = 25
            else:
                if user_queryset.entityTypeId.isIndividual==True:
                    profile = 25
                else:
                    profile = 10

                    kycStatusList = []
                    kycStatusList.append(user_kyc_queryset.businessStatus)
                    kycStatusList.append(user_kyc_queryset.shopVideoStatus)

                    if user_kyc_queryset.shopImagesList==[]:
                        kycStatusList.append("Pending")
                    if user_kyc_queryset.documentsList==[]:
                        kycStatusList.append("Pending")

                    for each_image_status in user_kyc_queryset.shopImagesList:
                        shopImageStatus = each_image_status.get("shopImageStatus")
                        kycStatusList.append(shopImageStatus)
                    for each_document_status in user_kyc_queryset.documentsList:
                        documentStatus = each_document_status.get("documentStatus")
                        kycStatusList.append(documentStatus)

                    if any(status == "Rejected" for status in kycStatusList):
                        businessStatus = "Rejected"
                    elif all(status == "Pending" for status in kycStatusList):
                        businessStatus = "Pending"
                    elif all(status == "Approved" for status in kycStatusList):
                        businessStatus = "Approved"
                    elif any(status == "Pending" for status in kycStatusList):
                        businessStatus = "Processing"
                    else:
                        businessStatus = "Submitted"
        except Exception as e:
            profile = 25

        panPercentage = 15 if user_kyc_queryset.panStatus in ["Approved", "Submitted"] else 0
        aadharPercentage = 15 if user_kyc_queryset.aadharStatus in ["Approved", "Submitted"] else 0
        bankPercentage = 15 if user_kyc_queryset.bankStatus in ["Approved", "Submitted"] else 0
        videoPercentage = 15 if user_kyc_queryset.videoVerificationStatus in ["Approved", "Submitted"] else 0
        agreementPercentage = 15 if user_kyc_queryset.agreementVerificationStatus in ["Approved", "Submitted"] else 0
        businessPercentage = 15 if businessStatus in ["Approved", "Submitted"] else 0

        
        
        # Calculate total percentage
        userCyclePercentage = profile + panPercentage + aadharPercentage + bankPercentage + videoPercentage + businessPercentage+agreementPercentage

        print(userCyclePercentage,"userCyclePercentage")
        kycPercentageDict = {
            "userKycPercentage": userCyclePercentage,
            "panStatus": user_kyc_queryset.panStatus,
            "aadharStatus": user_kyc_queryset.aadharStatus,
            "bankStatus": user_kyc_queryset.bankStatus,
            "videoVerificationStatus": user_kyc_queryset.videoVerificationStatus,
            "agreementVerificationStatus": user_kyc_queryset.agreementVerificationStatus,
            "businessStatus": businessStatus
        }
        data_status["responseStatus"] = 1
        data_status["result"] = "User KYC percentage details fetched successfully!"
        data_status["kycPercentageDict"] = kycPercentageDict
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch user KYC percentage!!"
        return data_status


@users.route("/merchant_agreement", methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def merchant_agreement():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId", "")
        signatureImage = data.get("signatureImage", "")
        agreementAutherized = data.get("agreementAutherized")
        agreementVerificationStatus = data.get("agreementVerificationStatus")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        merchant_queryset = Users.objects(id=userId, status=1).first()

        if signatureImage:
            save_file = upload_file_image(signatureImage, "merchantSignatures", str(userId), ".png")
            merchant_queryset.update(signatureImage=save_file, agreementAutherized=agreementAutherized)

            merchant_kyc_queryset = UserKYC.objects(userId=userId).first()
            merchant_kyc_queryset.update(agreementVerificationStatus="Approved")
            cityname=""
            if merchant_queryset.cityId:
                cityname=merchant_queryset.cityId.cityName
            statename=""
            if merchant_queryset.stateId:
                statename=merchant_queryset.stateId.stateName
            blockPoName=""
            pincode=""
            if merchant_queryset.blockPoId:
                blockPoName=merchant_queryset.blockPoId.name

            if merchant_queryset.pincodeId:
                pincode=merchant_queryset.pincodeId.pincode

            merchantName = merchant_queryset.fullName
            merchantId = merchant_queryset.merchantUniqueNumber
            merchantmail = merchant_queryset.email
            merchantaddress = str(merchant_queryset.address) + ","+str(blockPoName)+ ","+str(cityname)+ ","+str(statename)+", INDIA "+ ","+str(pincode)

            # signatureImage = domain + save_file
            # print(signatureImage, "signatureImage")

            documentContent = ""
            document_queryset = Documents.objects(status=1).order_by("-id").first()

            documentContent = document_queryset.documentContent
            startDate=datetime.datetime.now()
            createdDate = startDate.strftime('%d-%m-%Y %H:%M:%S')
            content = remove_html_tags(documentContent).replace("$$$DATE$$$", createdDate)
            content = remove_html_tags(content).replace("$$$USERNAME$$$", merchantName)
            content = remove_html_tags(content).replace("$$$USERID$$$", merchantId)
            content = remove_html_tags(content).replace("$$$USEREMAIL$$$", merchantmail)
            content = remove_html_tags(content).replace("$$$USERADDRESS$$$", merchantaddress)
            # content = re.sub(r'\r\n|\r|\n', '\n', content)
            content = re.sub(r'\n\s*\n', '\n', content)

            # Step 3: Remove problematic characters (e.g., smart quotes)
            content = content.replace('“', '"').replace('”', '"').replace('‘', "'").replace('’', "'")
            content=content.strip()
            # Define media directories
            media_dir = os.path.join(app.config['SITE_ROOT'], "media")
            signature_dir = os.path.join(media_dir, "merchantSignatures")
            agreements_dir = os.path.join(media_dir, "merchantAgreements")

            # Create directories if they don't exist
            os.makedirs(signature_dir, exist_ok=True)
            os.makedirs(agreements_dir, exist_ok=True)

            # Create PDF using FPDF
            pdf = FPDF()
            pdf.add_page()
            pdf.set_font("Arial", size=12)

            #Get page dimensions
            pdf_width = pdf.w - 10  # PDF width minus margins
            pdf_height = pdf.h - 20  # PDF height minus margins

            # Define the width of the text area
            text_width = 190  # Adjust as needed (PDF width - margins)

            # Add text content
            pdf.set_x(10)  # Set starting x position (left margin)
            pdf.multi_cell(text_width, 10, txt=content, border=0, align="L")  # Use multi_cell for wrapping text

            image_path = os.path.join(signature_dir, f"{userId}.png")
            print(image_path, "(((((image_path)))))")

            # Add the signature image at the bottom right
            if os.path.exists(image_path):
                print("IFFFFFFFFFFFF")
                pdf.ln(3)  # Move down by 10 units (adjust as needed)

                # Image dimensions
                img_w = 85
                img_h = 40

                # Calculate x position: PDF width minus image width and margin
                x_pos = pdf_width - img_w - 2
                # Calculate y position: PDF height minus image height and margin
                y_pos = pdf_height - img_h - 2

                pdf.image(image_path, x=x_pos, w=img_w, h=img_h)

                # Add static text signature at the bottom right
                signature_text = "Authorized Signature"
                pdf.set_font("Arial", size=10)
                # Calculate text width and height
                txt_w = pdf.get_string_width(signature_text)
                txt_h = pdf.font_size
                # Position for static text signature
                x_text_pos = pdf_width - txt_w - 30
                y_text_pos = pdf_width - txt_h - 90
                pdf.text(x_text_pos, y_text_pos, signature_text)
            # filename=str(userId)+random_digit_generate(4)
            # Define the path to save the PDF
            pdf_file_path = os.path.join(agreements_dir, f"{userId}.pdf")
            print(pdf_file_path, "????????????????????")

            # Save the PDF file
            pdf.output(pdf_file_path)
            print(f"PDF saved at {pdf_file_path}")

            savePath = f"media/merchantAgreements/{userId}.pdf"
            merchant_queryset.update(agreementDocument=savePath)

        data_status["responseStatus"] = 1
        data_status["result"] = "Merchant agreement successful!"
        # data_status["pdf_file_path"] = domain + savePath
        # data_status["signatureImage"] = signatureImage
        return jsonify(data_status)
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to generate agreement for merchant!"
        return jsonify(data_status)


@users.route("/merchant_aggrement_details",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def merchant_aggrement_details():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        aggrementDict = {}
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    try:
        merchant_queryset = Users.objects(id=userId,status=1).first()
        aggrementDict = {
        "id":str(merchant_queryset.id),
        "merchantName":merchant_queryset.fullName,
        "agreementAutherized":merchant_queryset.agreementAutherized
        }
        if merchant_queryset.agreementDocument:
            aggrementDict["agreementDocument"]=domain+merchant_queryset.agreementDocument
        else:
            aggrementDict["agreementDocument"]=""

        if merchant_queryset.signatureImage:
            aggrementDict["signatureImage"]=domain+merchant_queryset.signatureImage
        else:
            aggrementDict["signatureImage"]=""

        document_queryset = Documents.objects(status=1).order_by("-id").first()

        if document_queryset:
            startDate=datetime.datetime.now()
            createdDate = startDate.strftime('%d-%m-%Y %H:%M:%S')
            cityname=""
            if merchant_queryset.cityId:
                cityname=merchant_queryset.cityId.cityName
            statename=""
            if merchant_queryset.stateId:
                statename=merchant_queryset.stateId.stateName
            blockPoName=""
            pincode=""
            if merchant_queryset.blockPoId:
                blockPoName=merchant_queryset.blockPoId.name

            if merchant_queryset.pincodeId:
                pincode=merchant_queryset.pincodeId.pincode
            documentContent=document_queryset.documentContent
            merchantName = merchant_queryset.fullName
            merchantId = merchant_queryset.merchantUniqueNumber
            merchantmail = merchant_queryset.email
            merchantaddress = str(merchant_queryset.address) + ","+str(blockPoName)+ ","+str(cityname)+ ","+str(statename)+", INDIA "+ ","+str(pincode)
            content = documentContent.replace("$$$DATE$$$", createdDate)
            content = content.replace("$$$USERNAME$$$", merchantName)
            content = content.replace("$$$USERID$$$", merchantId)
            content = content.replace("$$$USEREMAIL$$$", merchantmail)
            content = content.replace("$$$USERADDRESS$$$", merchantaddress)
            aggrementDict["documentContent"]=content
        else:
            aggrementDict["documentContent"]=""

        data_status["responseStatus"]=1
        data_status["result"]="Merchant aggrement data fetched successfully!"
        data_status["aggrementDocumentDetails"]=aggrementDict
        return data_status   
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetched merchant aggrement data!!"
        return data_status

@users.route("/documents_list",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def documents_list():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        documentsList = []
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    try:
        business_documents_queryset = BusinessDocuments.objects(status=1).order_by("-id")
        for each_business_document in business_documents_queryset:
            business_document_dict = fetching_business_document_details(each_business_document)
            documentsList.append(business_document_dict)
        data_status["responseStatus"]=1
        data_status["result"]="Business document details fetched successfully!"
        data_status["documentsList"]=documentsList
        return data_status   
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch business documents data!!"
        return data_status


@users.route("/business_documents_form",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def business_documents_form():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        businessName = data.get("businessName","")
        businessAddress = data.get("businessAddress","")
        businessLocation = data.get("businessLocation","")
        documentsList = data.get("documentsList",[])
        shopImagesList = data.get("shopImagesList",[])
    except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Invalid Request"
            return data_status

    try:
        if len(documentsList)==0 or len(shopImagesList)==0 or businessName=="" or businessAddress=="":
            data_status["result"]="Required fields are missing!!"
            return data_status
        user_kyc_queryset = UserKYC.objects(userId=userId).first()
        if not user_kyc_queryset:
            data_status["result"]="Invalid user id!!"
            return data_status

        user_kyc_queryset.update(businessName=businessName,businessAddress=businessAddress,businessLocation=businessLocation,businessStatus="Approved",submittedDate=datetime.datetime.now())

        if documentsList:
            documentsData = []
            exisitingDocumentsList = user_kyc_queryset.documentsList or []
            for each_record in documentsList:
                if is_base64(each_record.get("image")) == True:
                    fileName = str(random_digit_generate(16))+str(get_epoch_milli_time())
                    documentFile = upload_file_image(each_record.get("image"), "businessDocuments", fileName, ".png")
                    if documentFile:
                        imageDict = {
                        "documentId":each_record.get("documentId"),
                        "documentName":each_record.get("documentName"),
                        "image":documentFile,
                        "documentStatus":"Approved"
                        }
                        exisitingDocumentsList.append(imageDict)
                print(exisitingDocumentsList,"((((((((((exisitingDocumentsList))))))))))")
            user_kyc_queryset.update(documentsList=exisitingDocumentsList,submittedDate=datetime.datetime.now())

        if shopImagesList:
            exisitingShopImagesList = user_kyc_queryset.shopImagesList or []
            
            for each_shop_record in shopImagesList:
                shopImageNumber = each_shop_record.get("shopImageNumber")
                shopImageStatus = each_shop_record.get("shopImageStatus")

                if is_base64(each_shop_record.get("image")):
                    fileName = str(random_digit_generate(16)) + str(get_epoch_milli_time())
                    shopImageFile = upload_file_image(each_shop_record.get("image"), "ShopImages", fileName, ".png")
                    if shopImageFile:
                        shopImageDict = {
                            "image": shopImageFile,
                            "shopImageNumber": shopImageNumber,
                            "shopImageStatus": "Approved"
                        }
                        exisitingShopImagesList.append(shopImageDict)
                print(exisitingShopImagesList, "Updated exisitingShopImagesList")

            user_kyc_queryset.update(shopImagesList=exisitingShopImagesList,submittedDate=datetime.datetime.now())

        data_status["responseStatus"]=1
        data_status["result"]="Business documents form submitted successfully!"
        return data_status   
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to save business documents form data!!"
        return data_status


@users.route("/get_bussiness_verification_video",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def get_bussiness_verification_video():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        businessVideoData = {}
    except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Invalid Request"
            return data_status
    
    if userId:
        try:
            user_kyc_queryset = UserKYC.objects(userId=userId).first()
            if not user_kyc_queryset:
                data_status["result"]="Invalid user id!!"
                return data_status

            businessVideoData = {
            "id":str(user_kyc_queryset.id),
            "merchantName":user_kyc_queryset.userId.fullName
            }
            if user_kyc_queryset.shopVideo:
                businessVideoData["shopVideo"]=domain+user_kyc_queryset.shopVideo
            else:
                businessVideoData["shopVideo"]=""

            # if user_kyc_queryset.shopImagesList:
            #     businessVideoData["shopImagesList"]=[str(domain+each_shop_image) for each_shop_image in user_kyc_queryset.shopImagesList]
            # else:
            #     businessVideoData["shopImagesList"]=[]

            if user_kyc_queryset.shopImagesList:
                businessImagesList = []
                for each_document in user_kyc_queryset.shopImagesList:
                    businessImageDict = {
                    "shopImageNumber":each_document.get("shopImageNumber"),
                    "shopImageStatus":each_document.get("shopImageStatus"),
                    "image":domain+each_document.get("image")
                    }
                    businessImagesList.append(businessImageDict)
                businessVideoData["shopImagesList"]=businessImagesList
            else:
                businessVideoData["shopImagesList"]=[]

            if user_kyc_queryset.documentsList:
                businessDocumentsList = []
                for each_document in user_kyc_queryset.documentsList:
                    businessDocumentDict = {
                    "documentId":each_document.get("documentId"),
                    "documentName":each_document.get("documentName"),
                    "documentStatus":each_document.get("documentStatus"),
                    "image":domain+each_document.get("image")
                    }
                    businessDocumentsList.append(businessDocumentDict)
                businessVideoData["documentsList"]=businessDocumentsList
            else:
                businessVideoData["documentsList"]=[]

            data_status["responseStatus"] = 1
            data_status["result"] = "Business verification video fetched successfully!"
            data_status["businessVideoData"] = businessVideoData
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Unable to fetch business video!!"
            return data_status
    else:
        data_status["result"]="Required fields are missing!!"
        return data_status


@users.route("/bussiness_upload_video",methods=["POST"])
@encrypt_decrypt_after_login
def bussiness_upload_video():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        shopVideo = request.files.get("shopVideo","")
    # shopVideoStatus = request.files.get("shopVideoStatus","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if not userId:
        data_status["result"] = "Required fields are missing!!"
        return data_status
    try:
        user_queryset = Users.objects(id=userId,status=1).first()
        if not user_queryset:
            data_status["result"]="Invalid user id!!"
            return data_status

        user_kyc_queryset = UserKYC.objects(userId=str(user_queryset.id)).first()
        if not user_kyc_queryset:
            data_status["result"]="Invalid user id!!"
            return data_status

        if shopVideo:
            video_file = upload_file_video("uploadBussinessVideos", userId, ".mp4", shopVideo)
            if video_file:
                user_kyc_queryset.update(shopVideo=video_file,submittedDate=datetime.datetime.now(),shopVideoStatus="Approved")

        data_status["responseStatus"] = 1
        data_status["result"] = "Video uploaded successfully!"
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to upload video!!"
        return data_status


# ##business pan api check is not enabled in signzy
# @users.route("/validate_beneficiary_bank_account",methods=["POST"])
# def validate_beneficiary_bank_account():
#     data_status = {"responseStatus": 0, "result": ""}
#     try:
#         accountNumber = request.json.get("accountNumber")
#         ifscCode = request.json.get("ifscCode")
#         bankId = request.json.get("bankId","")
#         userId = request.json.get("userId","")
#         if accountNumber and userId and ifscCode:
#             merchant_queryset = Users.objects(id=userId,status=1).first()
#             if not merchant_queryset:
#                 data_status["result"] = "Invalid user Id"
#                 return data_status
#             # accountHolderName=str(merchant_queryset.fullName)
#             # mobileNumber=str(merchant_queryset.phoneNumber)
#             accountHolderName=""
#             mobileNumber=""
#             payoutPaymentGatewayId = str(merchant_queryset.patternId.payoutPaymentGatewayId.id)

#             payout_gate_way_queryset = TransactionAPI.objects(id=payoutPaymentGatewayId,status=1).first()
#             if not payout_gate_way_queryset:
#                 data_status["result"]="Invalid payment gateway id!!"
#                 return data_status

#             exisit_beneficiary_check = BenificiaryAccounts.objects(creditorAccountNumber=accountNumber,userId=userId).first()
#             if exisit_beneficiary_check:
#                 data_status["result"]="Beneficiary already added!!"
#                 return data_status

            
#             gstInclude = ""
#             gstValue = 0
#             tdsInclude = ""
#             tdsValue = 0
#             amount = 0
#             merchantCharges = 0
#             beneficiaryCharges = 0
#             previousBalance = 0
#             currentBalance = 0
#             commissionCharges = {}
#             benivalidationCheck = {}
#             beneficiary_service_charges = ServiceCharges.objects(chargeType="benificiaryValidation",status=1).first()
#             if beneficiary_service_charges:
#                 amount = float(beneficiary_service_charges.amount)
#                 gstInclude = beneficiary_service_charges.gstInclude
#                 gstValue = float(beneficiary_service_charges.gstValue)
#                 tdsInclude = beneficiary_service_charges.tdsInclude
#                 tdsValue = float(beneficiary_service_charges.tdsValue)

#                 gstAmount  = float(amount*gstValue)/100
#                 tdsAmount  = float(amount*tdsValue)/100

#                 if gstInclude == "Yes":
#                     merchantCharges = float(amount) - float(gstAmount)
#                 else:
#                     merchantCharges = float(amount)

#                 if tdsInclude == "Yes":
#                     merchantCharges = float(merchantCharges) - float(tdsAmount)
#                 else:
#                     merchantCharges = float(merchantCharges)

#                 beneficiaryCharges = float(merchantCharges) + float(gstAmount) + float(tdsAmount)

#                 if float(merchant_queryset.payoutBalance) < float(beneficiaryCharges):
#                     data_status["result"]="Insufficient balance!!"
#                     return data_status

#                 previousBalance = float(merchant_queryset.payoutBalance)
#                 currentBalance = float(previousBalance)-float(beneficiaryCharges)

#                 commissionCharges = {
#                 "aggregatorType":"",
#                 "aggregatorAmount":0,
#                 "commissionType":"",
#                 "commissionAmount":"",
#                 "chargeType":"FLAT",
#                 "chargeValue":amount,
#                 "gstValue":gstValue,
#                 "tdsValue":tdsValue,
#                 "aggregatorValue":0,
#                 "commissionValue":0,
#                 "chargeAmount":round(float(merchantCharges),2),
#                 "transactionAmount":round(float(amount),2),
#                 "gstInclude":gstInclude,
#                 "gstAmount":round(float(gstAmount),2),
#                 "tdsInclude":tdsInclude,
#                 "tdsAmount":round(float(tdsAmount),2),
#                 "priceType":"Fixed",
#                 "slabId":""
#                 }
#             bankStatusDict=verify_bank_account(accountNumber, ifscCode, "Bank", accountHolderName="", mobileNumber="", userId=userId)
#             print(bankStatusDict,"bankStatusDict")
#             if bankStatusDict.get("responseStatus") == 1:
#                 creditorName=str(bankStatusDict.get("beneficiaryName"))
#                 bankrrn=str(bankStatusDict.get("bankRRN"))
#                 if beneficiaryCharges > 0:
#                     merchant_queryset.update(payoutBalance=currentBalance)
#                     merchantReferenceNumber=str(random_digit_generate(15))
#                     transactionReferenceNumber=str(random_digit_generate(15))
#                     bankName = ""
#                     if bankId:
#                         master_bank_queryset = MasterIFSCBank.objects(id=bankId).first()
#                         if master_bank_queryset:
#                             bankName = master_bank_queryset.bankName
#                         else:
#                             bankName = ""

#                     pgOrderId = str(transaction_id_prefix) + str(merchantReferenceNumber)

#                     fund_transfer_table = FundTransfers(
#                         createdBy=None,
#                         userId = str(merchant_queryset.id),
#                         amount = amount,
#                         grandTotal = beneficiaryCharges,
#                         transactionAPIId = payoutPaymentGatewayId,
#                         transferType = "Debit",
#                         userType = "user",
#                         narration = "Beneficiary validation charges for the account holder "+str(creditorName) +" | account number "+str(accountNumber),
#                         transactionUniqueId = transactionReferenceNumber,
#                         createdOn = datetime.datetime.now(),
#                         previousBalance=previousBalance,
#                         currentBalance=currentBalance,
#                         uniqueRequestNumber = "",
#                         beneficiaryName = creditorName,
#                         beneficiaryMail = "",
#                         beneficiaryPhone = "",
#                         bankReferenceNumber=bankrrn,
#                         accountIFSCCode = ifscCode,
#                         fundTransferType = "user",
#                         accountType = "",
#                         accountNumber = accountNumber,
#                         paymentMode = "wallet",
#                         bankBranch = "",
#                         bankName = bankName,
#                         errorMessage = "Beneficiary validation charges for the account holder "+str(creditorName) +" | account number "+str(accountNumber),
#                         internalId = "",
#                         pgOrderId = pgOrderId,
#                         apiType = "api",
#                         siteTitle = str(merchant_queryset.siteTitle),
#                         merchantReferenceNumber = merchantReferenceNumber,
#                         commissionCharges = commissionCharges,
#                         status = 1
#                         )
#                     save_table = fund_transfer_table.save()
                
#                 DeclinedList=["card","cards","credit card","credit cards","creditcard","creditcards","credit","credits","cc","","creditcardsystem"]
#                 if creditorName.lower() in DeclinedList or "card" in creditorName.lower() or "credit" in creditorName.lower():
#                     invalidbenny_table=InvalidBenificiaryLogs(
#                         userId=str(merchant_queryset.id),
#                         accountNumber=accountNumber,
#                         beneficiaryName=str(bankStatusDict.get("beneficiaryName")),
#                         ifscCode=ifscCode,
#                         status=1
#                         ).save()
#                     data_status["result"] = "Invalid Account Number."
#                 else:
#                     data_status["responseStatus"] = 1
#                     data_status["OriginalBankHolderName"] = str(bankStatusDict.get("beneficiaryName"))
#                     data_status["bankRRN"] = str(bankStatusDict.get("bankRRN"))
#                     data_status["bankResponseData"] = str(bankStatusDict.get("apiResponse"))
#                     data_status["result"] ="success"
#             else:
#                 data_status["result"] = bankStatusDict.get('result')
#             return data_status
#         else:
#             data_status["result"]="Required field is missing!!"
#             return data_status
#     except Exception as e:
#         print(traceback.format_exc())
#         data_status["result"] = "Unable to verify Account number."
#         return data_status


@users.route("/validate_beneficiary_bank_account",methods=["POST"])
@encrypt_decrypt_after_login
def validate_beneficiary_bank_account():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        accountNumber = data.get("accountNumber")
        ifscCode = data.get("ifscCode")
        bankId = data.get("bankId","")
        userId = data.get("userId")
        if accountNumber and userId and ifscCode:
            merchant_queryset = Users.objects(id=userId,status=1).first()
            if not merchant_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status
            # accountHolderName=str(merchant_queryset.fullName)
            # mobileNumber=str(merchant_queryset.phoneNumber)
            accountHolderName=""
            mobileNumber=""
            payoutPaymentGatewayId = str(merchant_queryset.patternId.payoutPaymentGatewayId.id)

            payout_gate_way_queryset = TransactionAPI.objects(id=payoutPaymentGatewayId,status=1).first()
            if not payout_gate_way_queryset:
                data_status["result"]="Invalid payment gateway id!!"
                return data_status

            existingAccount=0
            creditorName=""
            bankrrn=""
            bankerror=""
            apiResponse=""

            gstInclude = ""
            gstValue = 0
            tdsInclude = ""
            tdsValue = 0
            amount = 0
            merchantCharges = 0
            beneficiaryCharges = 0
            previousBalance = 0
            currentBalance = 0
            commissionCharges = {}
            benivalidationCheck = {}
            beneficiary_service_charges = ServiceCharges.objects(chargeType="benificiaryValidation",status=1).first()
            if beneficiary_service_charges:
                amount = float(beneficiary_service_charges.amount)
                gstInclude = beneficiary_service_charges.gstInclude
                gstValue = float(beneficiary_service_charges.gstValue)
                tdsInclude = beneficiary_service_charges.tdsInclude
                tdsValue = float(beneficiary_service_charges.tdsValue)

                gstAmount  = float(amount*gstValue)/100
                tdsAmount  = float(amount*tdsValue)/100

                if gstInclude == "Yes":
                    merchantCharges = float(amount) - float(gstAmount)
                else:
                    merchantCharges = float(amount)

                if tdsInclude == "Yes":
                    merchantCharges = float(merchantCharges) - float(tdsAmount)
                else:
                    merchantCharges = float(merchantCharges)

                beneficiaryCharges = float(merchantCharges) + float(gstAmount) + float(tdsAmount)
                print(beneficiaryCharges,"beneficiaryCharges")
                print(merchant_queryset.payoutBalance,"merchant_queryset.payoutBalance")
                if float(merchant_queryset.payoutBalance) < float(beneficiaryCharges):
                    data_status["result"]="Insufficient balance!!"
                    return data_status

            exisit_beneficiary_check = Beneficiaries.objects(accountNumber=accountNumber).first()
            if exisit_beneficiary_check:
                existingUsers=[str(eachuser.id) for eachuser in exisit_beneficiary_check.userIdsList]
                if str(userId) in existingUsers:
                    data_status["result"]="Beneficiary already added!!"
                    return data_status
                else:
                    creditorName=str(exisit_beneficiary_check.beneficiaryName)
                    bankrrn=str(exisit_beneficiary_check.transactionReferenceNumber)
                    apiResponse=str(exisit_beneficiary_check.beniValidationData)
                    existingAccount=1
            else:
                bankStatusDict=verify_bank_account(accountNumber,ifscCode,accountHolderName,mobileNumber)
                if bankStatusDict.get("responseStatus") == 1:
                    creditorName=str(bankStatusDict.get("beneficiaryName"))
                    bankrrn=str(bankStatusDict.get("bankRRN"))
                    apiResponse=str(bankStatusDict.get("apiResponse"))
                    bankerror=bankStatusDict.get('result')
                    existingAccount=1
            if existingAccount==1:
                previousBalance = float(merchant_queryset.payoutBalance)
                currentBalance = float(previousBalance)-float(beneficiaryCharges)
                commissionCharges = {
                "aggregatorType":"",
                "aggregatorAmount":0,
                "commissionType":"",
                "commissionAmount":"",
                "chargeType":"FLAT",
                "chargeValue":amount,
                "gstValue":gstValue,
                "tdsValue":tdsValue,
                "aggregatorValue":0,
                "commissionValue":0,
                "chargeAmount":round(float(merchantCharges),2),
                "transactionAmount":round(float(amount),2),
                "gstInclude":gstInclude,
                "gstAmount":round(float(gstAmount),2),
                "tdsInclude":tdsInclude,
                "tdsAmount":round(float(tdsAmount),2),
                "priceType":"Fixed",
                "slabId":""
                }

                if beneficiaryCharges > 0:
                    merchant_queryset.update(payoutBalance=currentBalance)
                    merchantReferenceNumber=str(random_digit_generate(15))
                    transactionReferenceNumber=str(random_digit_generate(15))
                    bankName = ""
                    if bankId:
                        master_bank_queryset = MasterIFSCBank.objects(id=bankId).first()
                        if master_bank_queryset:
                            bankName = master_bank_queryset.bankName
                        else:
                            bankName = ""

                    pgOrderId = str(transaction_id_prefix) + str(merchantReferenceNumber)
                
                    fund_transfer_table = FundTransfers(
                        createdBy=None,
                        userId = str(merchant_queryset.id),
                        amount = amount,
                        grandTotal = beneficiaryCharges,
                        transactionAPIId = payoutPaymentGatewayId,
                        transferType = "Debit",
                        userType = "user",
                        narration = "Beneficiary validation charges for the account holder "+str(creditorName) +" | account number "+str(accountNumber),
                        transactionUniqueId = transactionReferenceNumber,
                        createdOn = datetime.datetime.now(),
                        previousBalance=previousBalance,
                        currentBalance=currentBalance,
                        uniqueRequestNumber = "",
                        beneficiaryName = creditorName,
                        beneficiaryMail = "",
                        beneficiaryPhone = "",
                        bankReferenceNumber=bankrrn,
                        accountIFSCCode = ifscCode,
                        fundTransferType = "beneficiary",
                        accountType = "",
                        accountNumber = accountNumber,
                        paymentMode = "wallet",
                        bankBranch = "",
                        bankName = bankName,
                        errorMessage = "Beneficiary validation charges for the account holder "+str(creditorName) +" | account number "+str(accountNumber),
                        internalId = "",
                        pgOrderId = pgOrderId,
                        apiType = "api",
                        siteTitle = str(merchant_queryset.siteTitle),
                        merchantReferenceNumber = merchantReferenceNumber,
                        commissionCharges = commissionCharges,
                        status = 1
                        )
                    save_table = fund_transfer_table.save()
                
                DeclinedList=["card","cards","credit card","credit cards","creditcard","creditcards","credit","credits","cc","","creditcardsystem"]
                if creditorName.lower() in DeclinedList or "card" in creditorName.lower() or "credit" in creditorName.lower():
                    invalidbenny_table=InvalidBenificiaryLogs(
                        userId=str(merchant_queryset.id),
                        accountNumber=accountNumber,
                        beneficiaryName=str(creditorName),
                        ifscCode=ifscCode,
                        status=1
                        ).save()
                    data_status["result"] = "Invalid Account Number."
                else:
                    data_status["responseStatus"] = 1
                    data_status["OriginalBankHolderName"] = str(creditorName)
                    data_status["bankRRN"] = str(bankrrn)
                    data_status["bankResponseData"] = str(apiResponse)
                    data_status["result"] ="success"
            else:
                data_status["result"] = bankerror
            return data_status
        else:
            data_status["result"]="Required field is missing!!"
            return data_status
    except Exception as e:
        print(traceback.format_exc())
        data_status["result"] = "Unable to verify Pan."
        return data_status


# @users.route("/create_benificiary",methods=["POST"])
# @user_required
# def create_benificiary():
#     data_status = {"responseStatus": 0, "result": ""}
#     userId = request.json.get("userId","")
#     name = request.json.get("name","")
#     bankId = request.json.get("bankId","")
#     accountNumber = request.json.get("accountNumber","")
#     ifscCode = request.json.get("ifscCode","")
#     comment = request.json.get("comment","")

#     try:
#         if userId and ifscCode and accountNumber and name and bankId:
#             merchant_queryset = Users.objects(id=userId,status=1).first()
#             if not merchant_queryset:
#                 data_status["result"]="Invalid user id!!"
#                 return data_status

#             payoutPaymentGatewayId = str(merchant_queryset.patternId.payoutPaymentGatewayId.id)
#             gstInclude = ""
#             gstValue = 0
#             tdsInclude = ""
#             tdsValue = 0
#             amount = 0
#             merchantCharges = 0
#             beneficiaryCharges = 0
#             previousBalance = 0
#             currentBalance = 0
#             commissionCharges = {}
#             benivalidationCheck = {}

#             transactionUniqueId = str(random_digit_generate(15))
#             merchantReferenceNumber = str(random_digit_generate(15))

#             master_bank_queryset = MasterIFSCBank.objects(id=bankId).first()
#             if master_bank_queryset:
#                 bankName = master_bank_queryset.bankName
#             else:
#                 bankName = ""

            
#             exisit_beneficiary_check = BenificiaryAccounts.objects(creditorAccountNumber=accountNumber,userId=userId).first()
#             if exisit_beneficiary_check:
#                 data_status["result"]="Beneficiary already added!!"
#                 return data_status
#             else:
#                 beneficiary_service_charges = ServiceCharges.objects(chargeType="benificiaryValidation",status=1).first()
#                 if beneficiary_service_charges:
#                     amount = float(beneficiary_service_charges.amount)
#                     gstInclude = beneficiary_service_charges.gstInclude
#                     gstValue = float(beneficiary_service_charges.gstValue)
#                     tdsInclude = beneficiary_service_charges.tdsInclude
#                     tdsValue = float(beneficiary_service_charges.tdsValue)

#                     gstAmount  = float(amount*gstValue)/100
#                     tdsAmount  = float(amount*tdsValue)/100

#                     if gstInclude == "Yes":
#                         merchantCharges = float(amount) - float(gstAmount)
#                     else:
#                         merchantCharges = float(amount)

#                     if tdsInclude == "Yes":
#                         merchantCharges = float(merchantCharges) - float(tdsAmount)
#                     else:
#                         merchantCharges = float(merchantCharges)

#                     beneficiaryCharges = float(merchantCharges) + float(gstAmount) + float(tdsAmount)

                    

#                     if float(merchant_queryset.payoutBalance) < float(beneficiaryCharges):
#                         data_status["result"]="Insufficient balance!!"
#                         return data_status

#                     previousBalance = float(merchant_queryset.payoutBalance)
#                     currentBalance = float(previousBalance)-float(beneficiaryCharges)

#                     commissionCharges = {
#                     "aggregatorType":"",
#                     "aggregatorAmount":0,
#                     "commissionType":"",
#                     "commissionAmount":"",
#                     "chargeType":"FLAT",
#                     "chargeValue":amount,
#                     "gstValue":gstValue,
#                     "tdsValue":tdsValue,
#                     "aggregatorValue":0,
#                     "commissionValue":0,
#                     "chargeAmount":round(float(merchantCharges),2),
#                     "transactionAmount":round(float(amount),2),
#                     "gstInclude":gstInclude,
#                     "gstAmount":round(float(gstAmount),2),
#                     "tdsInclude":tdsInclude,
#                     "tdsAmount":round(float(tdsAmount),2),
#                     "priceType":"Fixed",
#                     "slabId":""
#                     }

#                 beneficiary_check = BenificiaryAccounts.objects(creditorAccountNumber=accountNumber,userId__ne=userId).first()
#                 if beneficiary_check:
#                     creditorAccountNumber = beneficiary_check.creditorAccountNumber
#                     creditorName = beneficiary_check.creditorName
#                     transactionReferenceNumber = beneficiary_check.transactionReferenceNumber
#                     beniValidationData = beneficiary_check.beniValidationData

#                     if beneficiary_check.bankId:
#                         bankName = beneficiary_check.bankId.bankName
#                     else:
#                         bankName = ""

#                     exisit_benificiary_account_table = BenificiaryAccounts(
#                         userId=userId,
#                         creditorAccountNumber=accountNumber,
#                         ifscCode=ifscCode,
#                         creditorName=creditorName,
#                         transactionReferenceNumber=transactionReferenceNumber,
#                         name=name,
#                         bankId=bankId,
#                         beniValidationData=beniValidationData,
#                         createdOn=datetime.datetime.now(),
#                         status=1
#                         ).save()

#                     if beneficiaryCharges > 0:
#                         merchant_queryset.update(payoutBalance=currentBalance)

#                         fund_transfer_table = FundTransfers(
#                             createdBy=None,
#                             userId = str(merchant_queryset.id),
#                             amount = amount,
#                             grandTotal = beneficiaryCharges,
#                             transactionAPIId = payoutPaymentGatewayId,
#                             transferType = "Debit",
#                             userType = "user",
#                             narration = "Beneficiary validation charges for the account holder "+str(creditorName) +" | account number "+str(accountNumber),
#                             transactionUniqueId = transactionReferenceNumber,
#                             createdOn = datetime.datetime.now(),
#                             previousBalance=previousBalance,
#                             currentBalance=currentBalance,
#                             uniqueRequestNumber = "",
#                             beneficiaryName = creditorName,
#                             beneficiaryMail = "",
#                             beneficiaryPhone = "",
#                             accountIFSCCode = ifscCode,
#                             fundTransferType = "user",
#                             accountType = "",
#                             accountNumber = accountNumber,
#                             paymentMode = "wallet",
#                             bankBranch = "",
#                             bankName = bankName,
#                             errorMessage = "Beneficiary validation charges for the account holder "+str(creditorName) +" | account number "+str(accountNumber),
#                             internalId = "",
#                             pgOrderId = "",
#                             apiType = "api",
#                             merchantReferenceNumber = merchantReferenceNumber,
#                             commissionCharges = commissionCharges,
#                             status = 1
#                             )
#                         save_table = fund_transfer_table.save()

#                     data_status["responseStatus"] = 1
#                     data_status["result"] = "Beneficiary created successfully!"
#                     return data_status

#             client_id = ""
#             secretKey = ""
#             kid = ""
#             get_base_url = ""
#             aud_url = ""
#             auth_url = ""
#             grant_type = ""
#             scope = ""
#             source = ""
#             client_assertion_type = ""
#             debitAcountNumber = ""
#             remitterName = ""
#             transactionId = str(random_digit_generate(15))

#             # payout_gate_way_queryset = TransactionAPI.objects(code="Idfc_Payout",status=1).first()
#             payout_gate_way_queryset = TransactionAPI.objects(id=payoutPaymentGatewayId,status=1).first()
#             if not payout_gate_way_queryset:
#                 data_status["result"]="Invalid payment gateway id!!"
#                 return data_status

#             if payout_gate_way_queryset.code == "Idfc_Payout":
#                 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()
#                     if get_key == "remitter_mobile_number":
#                         remitter_mobile_number = each_key.get("value").strip()

#                 benivalidationCheck = idfc_benivalidation(source,kid,aud_url,client_id,auth_url,grant_type,scope,client_assertion_type,secretKey,ifscCode,accountNumber,debitAcountNumber,remitterName,remitter_mobile_number,comment,transactionId)


#             if benivalidationCheck.get("responseStatus") == 1:
#                 creditorAccountId = benivalidationCheck.get("creditorAccountId")
#                 beniValidationData = benivalidationCheck.get("beniValidationData")
#                 creditorName = benivalidationCheck.get("creditorName")
#                 transactionReferenceNumber = benivalidationCheck.get("transactionReferenceNumber")
#                 scorecheck=0.6
#                 if creditorName=="":
#                     data_status["result"]="Given Account holder name does not match with the benificiary name."
#                     return data_status
#                 name_match_response = name_match_check(creditorName,name,scorecheck)
#                 if name_match_response.get("responseStatus") == 0:
#                     data_status["result"]="Given Account holder name does not match with the benificiary name as "+str(creditorName)
#                     return data_status

#                 benificiary_account_table = BenificiaryAccounts(
#                     userId=userId,
#                     creditorAccountNumber=creditorAccountId,
#                     ifscCode=ifscCode,
#                     creditorName=creditorName,
#                     transactionReferenceNumber=transactionReferenceNumber,
#                     name=name,
#                     bankId=bankId,
#                     beniValidationData=beniValidationData,
#                     createdOn=datetime.datetime.now(),
#                     status=1
#                     ).save()

#                 if beneficiaryCharges > 0:
#                     merchantDebitAmount = float(merchant_queryset.payoutBalance)-float(beneficiaryCharges)

#                     merchant_queryset.update(payoutBalance=merchantDebitAmount)

#                     fund_transfer_table = FundTransfers(
#                         createdBy=None,
#                         userId = str(merchant_queryset.id),
#                         amount = amount,
#                         grandTotal = beneficiaryCharges,
#                         transactionAPIId = payoutPaymentGatewayId,
#                         transferType = "Debit",
#                         userType = "user",
#                         narration = "Beneficiary validation charges for the account holder "+str(creditorName) +" | account number "+str(accountNumber),
#                         transactionUniqueId = transactionReferenceNumber,
#                         createdOn = datetime.datetime.now(),
#                         previousBalance=previousBalance,
#                         currentBalance=currentBalance,
#                         uniqueRequestNumber = "",
#                         beneficiaryName = creditorName,
#                         beneficiaryMail = "",
#                         beneficiaryPhone = "",
#                         accountIFSCCode = ifscCode,
#                         fundTransferType = "user",
#                         accountType = "",
#                         accountNumber = accountNumber,
#                         paymentMode = "wallet",
#                         bankBranch = "",
#                         bankName = bankName,
#                         errorMessage = "Beneficiary validation charges for the account holder "+str(creditorName) +" | account number "+str(accountNumber),
#                         internalId = "",
#                         pgOrderId = "",
#                         apiType = "api",
#                         merchantReferenceNumber = merchantReferenceNumber,
#                         commissionCharges = commissionCharges,
#                         status = 1
#                         )
#                     save_table = fund_transfer_table.save()

                
#                 data_status["responseStatus"] = 1
#                 data_status["result"] = "Beneficiary created successfully!"
#                 return data_status
#             else:
#                 data_status["result"]=benivalidationCheck.get("message")
#                 return data_status
#         else:
#             data_status["result"]="Required fields are missing!!"
#             return data_status
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         data_status["result"] = "unable to create beneficiary data!!"
#         return data_status

@users.route("/create_benificiary",methods=["POST"])
@encrypt_decrypt_after_login
# @user_required
def create_benificiary():
    # print(request.json,"create_benificiary")
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        name = data.get("name","")
        bankId = data.get("bankId","")
        accountNumber = data.get("accountNumber","")
        bankrrn = data.get("bankRRN","")
        ifscCode = data.get("ifscCode","")
        comment = data.get("comment","")
        beniValidationData = data.get("beniValidationData","")
        beniValidationDataDict=[]
        transactionReferenceNumber=""
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    if beniValidationData!="":
        beniValidationDataDict = ast.literal_eval(beniValidationData)
    print(beniValidationDataDict,"beniValidationDataDict")
    print(type(beniValidationDataDict),"beniValidationDataDict type")
    try:
        if userId and ifscCode and accountNumber and name and bankId:
            exisit_beneficiary_check = Beneficiaries.objects(accountNumber=accountNumber).first()
            if exisit_beneficiary_check:
                if userId in exisit_beneficiary_check.userIdsList:
                    data_status["result"]="Beneficiary already added!!"
                    return data_status
                else:
                    exisit_beneficiary_check.userIdsList.append(ObjectId(userId))
                    exisit_beneficiary_check.save()
            else:
                req_bene_code="BENI"+str(random_digit_generate(15))
                benificiary_account_table = Beneficiaries(
                    userIdsList=[ObjectId(userId)],
                    accountNumber=accountNumber,
                    ifscCode=ifscCode,
                    beneficiaryName=name,
                    transactionReferenceNumber=bankrrn,
                    beneficiaryId=req_bene_code,
                    beneCodeList =[],
                    masterBankId=bankId,
                    beniValidationData=beniValidationDataDict,
                    createdOn=datetime.datetime.now(),
                    status=1
                    ).save()
            try:
                bankName=""
                if bankId:
                    master_bank_queryset = MasterIFSCBank.objects(id=bankId).first()
                    if master_bank_queryset:
                        bankName = master_bank_queryset.bankName
                    else:
                        bankName = ""
                autobeneficiary=autoBenificiaryCreation(userId,accountNumber,ifscCode,name,bankId,bankName)
            except Exception as e:
                pass
            data_status["responseStatus"] = 1
            data_status["result"] = "Beneficiary created successfully!"
            return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to create beneficiary data!!"
        return data_status


@users.route("/view_all_benificiaries",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def view_all_benificiaries():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    if not userId:
        data_status["result"] = "Required fields are missing!!"
        return data_status
    try:
        user_queryset = Users.objects(id=userId,status=1).first()
        if not user_queryset:
            data_status["result"]="Invalid user id!!"
            return data_status

        benificiariesList = []
        beneficiary_accounts_queryset = Beneficiaries.objects(userIdsList__in=[userId],status=1).order_by("-id")
        for each_benificary in beneficiary_accounts_queryset:
            beneficiaryDict = {
            "id":str(each_benificary.id),
            "creditorAccountNumber":each_benificary.accountNumber,
            "creditorName":str(each_benificary.beneficiaryName),
            "ifscCode":each_benificary.ifscCode,
            "name":str(each_benificary.beneficiaryName),
            "transactionReferenceNumber":each_benificary.transactionReferenceNumber,
            "createdOn":str(each_benificary.createdOn),
            "userName":str(each_benificary.beneficiaryName)
            }
            if each_benificary.masterBankId:
                beneficiaryDict["bankId"]=str(each_benificary.masterBankId.id)
                beneficiaryDict["bankName"]=each_benificary.masterBankId.bankName
            else:
                beneficiaryDict["bankId"]=""
                beneficiaryDict["bankName"]=""
            benificiariesList.append(beneficiaryDict)

        data_status["responseStatus"] = 1
        data_status["result"] = "Beneficiaries data fetched successfully!"
        data_status["benificiariesList"]=benificiariesList
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to fetch beneficiary data!!"
        return data_status


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


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

    paymentgatewayresponseDict = {}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        upload_csv_file = request.files.get("upload_csv_file")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    # 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

    try:
        if userId and upload_csv_file:
            merchant_queryset = Users.objects(id=userId,status=1).first()
            if not merchant_queryset:
                data_status["result"]="Invalid merchant id!!"
                return data_status

            check_kyc_status = merchant_kyc_status(str(merchant_queryset.id))
            if check_kyc_status.get("responseStatus") != 1:
                data_status["result"]="Merchant KYC is not completed please contact to admin!!"
                return data_status

            kycStatus = check_kyc_status.get("merchantKycDetails", {}).get("kycStatus")
            if kycStatus == False:
                data_status["result"]="Merchant KYC is not completed please contact to admin!!"
                return data_status

            userId = str(merchant_queryset.id)

            try:
                if not merchant_queryset.patternId.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.patternId.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


            merchantUniqueNumber=str(merchant_queryset.merchantUniqueNumber)
            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 = ()


            # Read the file content
            file_content = upload_csv_file.read().decode('utf-8')
            
            # Use StringIO to read the string as a file object
            csvfile = StringIO(file_content)
            csvreader = csv.DictReader(csvfile)
            print(csvreader,"(((((((((((((csvreader)))))))))))))")
            bulkTransferList = []
            for each_row in csvreader:
                print(each_row,"(((((((EACH ROW)))))))")
                req_bank_name=each_row.get("beneBankName")
                req_merchant_reference_number=each_row.get("Customer Ref no.")
                req_account_number=each_row.get("Beneficary Accunt no.")
                req_ifsc_code=each_row.get("IFSC code")
                req_account_name=each_row.get("Beneficary Name")
                req_amount=each_row.get("Amount")
                req_customer_email=each_row.get("Beneficary email id")
                req_customer_phone=each_row.get("Beneficiary mobile no.")
                req_transfer_type=each_row.get("Payment Type")
                req_remark=each_row.get("Remarks")
                req_bene_code=each_row.get("BENE_ID")
                total_amount=total_amount + float(req_amount)
                total_txn_count = total_txn_count + 1
                clientOrderId = transaction_id_prefix + mid_extracted + str(get_epoch_milli_time())
                amount = req_amount

                print(req_bene_code,"((((((((((req_bene_code))))))))))")

                
                
                if req_bene_code:
                    benecode = Beneficiaries.objects(beneficiaryId=req_bene_code).first()
                
                if req_transfer_type not in ["NEFT","RTGS","IMPS"]:
                    errorList.append("transfer should be ones in ['NEFT','RTGS','IMPS'] " +req_account_number)

                if req_merchant_reference_number in seen_merchant_ref_numbers:
                    errorList.append("Two or more transactions have same Reference Number for Account Number" +req_account_number)

                merchant_ref_numbers.add(req_merchant_reference_number)

                checkorder_queryset = FundTransfers.objects(merchantReferenceNumber=req_merchant_reference_number,userId=str(userId)).first()
                if checkorder_queryset:
                    errorList.append("Duplicate Merchant Reference Number for Account Number "+req_account_number)
               
                if len(req_account_number) < 11 and 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)

                check_transaction_limits = merchant_transaction_limit_settings("Payout",payOutPaymentGatewayId,userId,amount)

                if check_transaction_limits.get("responseStatus") == 0:
                    errorList.append(check_transaction_limits.get("result")+req_account_number)
                    
                ###################################################### Slab Calculation for payout code ###########################################################
                payment_mode_queryset = PaymentMode.objects(paymentMode=req_transfer_type).first()
                if not payment_mode_queryset:
                    errorList.append(check_transaction_limits.get("result"),req_account_number)
                    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={}
                commissionCharges = slab_calculation_for_payout_merchant(amount,paymentModeId,subPaymentModeId,patternId)
                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+float(transactionAmount)
                ####################################################################################################################################################


                ############################################################# Aggregator Calculation For Payout #######################################################################
                overallCommissionAmount = 0
                aggregatorCharges = aggregator_calculation_for_payout(amount,paymentModeId,subPaymentModeId,payOutPaymentGatewayId)
                if aggregatorCharges.get("apiSetupchargeId") == None:
                    apiSetupchargeId = None
                    chargeAmount = 0
                else:
                    apiSetupchargeId = aggregatorCharges.get("apiSetupchargeId")
                    chargeAmount = float(aggregatorCharges.get("chargeAmount"))

                overallCommissionAmount = float(commissionCharges.get("chargeAmount")) - float(aggregatorCharges.get("chargeAmount"))

                ##################################################################################################################################################################
               
                bulkTransferDict = {
                "txnPaymode":req_transfer_type,
                "merchant_reference_number":req_merchant_reference_number,
                "amount":req_amount,
                "beneficiaryName":req_account_name,
                "beneCode":req_bene_code,
                "beneAccNum":req_account_number,
                "accountIFSCCode":req_ifsc_code,
                "commissionCharges":commissionCharges,
                "aggregatorCharges":aggregatorCharges,
                "overallCommissionAmount":overallCommissionAmount,
                "grandTotal":transactionAmount,
                "pgOrderId":clientOrderId
                }
                bulkTransferList.append(bulkTransferDict)
                print(bulkTransferList,"(((((((((((bulkTransferList)))))))))))")

            fund_transfer_table = BulkFundTransfers(
                userId = str(merchant_queryset.id),
                BulkTransactionId = transactionId,
                BatchNumber = 0,
                BulkCsvFileUpload = "",
                status = 2,
                totalAmount = total_amount,
                totalTransactionAmount = total_transaction_amount,
                totalTransactionCount = total_txn_count,
                clientRequestData = bulkTransferList,
                requestData = bulkTransferList,
                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 = total_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
                                   
            try:
                payout_balance_queryset = PayoutBalances.objects(userId=userId,transactionAPIId=payOutPaymentGatewayId).first()
                if payout_balance_queryset.currentBalance:
                    userPayoutBalance = payout_balance_queryset.currentBalance
                else:
                    userPayoutBalance = 0
            except Exception as e:
                userPayoutBalance = 0

            if float(userPayoutBalance) < float(total_amount + float(merchant_queryset.capBalance)):
                insufficient_table = InsufficientBalanceLogs(
                    userId=userId,
                    orderId=transactionId, # id generated in our side for bulk
                    orderAmount=total_amount,
                    walletAmount=float(merchant_queryset.payoutBalance),
                    createdOn=datetime.datetime.now(),
                    status=1
                    ).save()
                data_status["result"]="Insufficient balance!!"
                fund_transfer_table.errorMessage = ["Insufficient balance!!"]
                fund_transfer_table.ErrorType = "Internal"
                fund_transfer_table.status = 0
                fund_transfer_table.save(update_fields=["errorMessage", "ErrorType", "status"])
                return data_status

            if float(merchant_queryset.payoutBalance) < float(total_amount + float(merchant_queryset.capBalance)):
                insufficient_table = InsufficientBalanceLogs(
                    userId=userId,
                    orderId=transactionId, # id generated in our side for bulk
                    orderAmount=total_amount,
                    walletAmount=float(merchant_queryset.payoutBalance),
                    createdOn=datetime.datetime.now(),
                    status=1
                    ).save()

                data_status["result"]="Insufficient balance!!"
                fund_transfer_table.errorMessage = ["Insufficient balance!!"]
                fund_transfer_table.ErrorType = "Internal"
                fund_transfer_table.status = 0
                fund_transfer_table.save(update_fields=["errorMessage", "ErrorType", "status"])
                return data_status

            totalCapBalance = float(merchant_queryset.capBalance) + float(total_amount)
            merchant_queryset.update(capBalance=totalCapBalance)
            
            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,bulkTransferList,bulk_transactionId=transactionId)
                ################################################################################################################################################################

            else:
                data_status["result"]="Please contact to admin to enable payout option!!"
                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 = BulkFundTransfers.objects(id=BulkTransferId).first()

                for each_bulk_record in latest_bulk_fund_transfer_queryset.requestData:
                    balanceResult=user_payout_balance_update(str(merchant_queryset.id),float(each_bulk_record.get("grandTotal")),"Debit",str(payOutPaymentGatewayId))
                    if balanceResult.get('responseStatus')==0:
                        data_status["result"]="Insufficient balance!!"
                        return data_status

                    totalCapBalance = float(merchant_queryset.capBalance) - float(total_amount)
                    merchant_queryset.update(capBalance=totalCapBalance)

                    fund_transfer_table = FundTransfers(
                        userId=str(merchant_queryset.id),
                        transactionAPIId=payOutPaymentGatewayId,
                        bankId=None,
                        bankName=None,
                        merchantReferenceNumber=each_bulk_record.get("merchant_reference_number"),
                        pgOrderId=each_bulk_record.get("pgOrderId"), ### pgorderId starting with GP
                        fundTransferType="bulk",
                        accountType="bank",
                        apiType="api",
                        slabId=slabId,
                        transferType="Debit",
                        bankBranch=None,
                        accountNumber=each_bulk_record.get("beneAccNum"),
                        accountIFSCCode=each_bulk_record.get("accountIFSCCode"),
                        beneficiaryName=each_bulk_record.get("beneficiaryName"),
                        uniqueRequestNumber=None,
                        amount=round(float(each_bulk_record.get("amount")),2),
                        grandTotal=round(float(each_bulk_record.get("grandTotal")),2),
                        previousBalance = round(float(balanceResult.get('userPreviousBalance')),2),
                        currentBalance = round(float(balanceResult.get('userCurrentBalance')),2),
                        beneficiaryMail=None,
                        beneficiaryPhone=None,
                        paymentMode=each_bulk_record.get("txnPaymode"),
                        narration="",
                        createdOn=datetime.datetime.now(),
                        userType="user",
                        status=2,
                        clientIp=client_ip,
                        transactionUniqueId = "",
                        statusCheckId=each_bulk_record.get("pgOrderId"),
                        commissionCharges=each_bulk_record.get("commissionCharges"),
                        aggregatorCharges=each_bulk_record.get("aggregatorCharges"),
                        overallCommissionAmount=each_bulk_record.get("overallCommissionAmount")
                        )
                    save_table = fund_transfer_table.save()
                    instantTransferId = str(save_table.id)

                    responseDict = {
                    "status":"Processing",
                    "merchant_reference_number":each_bulk_record.get("merchant_reference_number"),
                    "account_name":each_bulk_record.get('beneficiaryName'),
                    "amount":each_bulk_record.get('amount'),
                    "account_number":each_bulk_record.get('beneAccNum'),
                    "ifsc_code":each_bulk_record.get('beneAccNum'),
                    "bank_reference_number":bank_reference_number,
                    "transfer_type":each_bulk_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")
                return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to upload csv transfer payout data!!"
        return data_status



@users.route("/add_utility_transaction",methods=["POST"])
@encrypt_decrypt_after_login
def add_utility_transaction():
    data_status = {"responseStatus": 0, "result": ""}
    # print(request.json,"add_utility_transaction")
    try:
        data = request.decrypted_data
        # data = request.get_json() 
        print(data,"======") 
        userId = data.get("userId","")
        categoryId = data.get("categoryId",None)
        serviceId = data.get("serviceId",None)
        operatorId = data.get("operatorId",None)
        # transactionAPIId = data.get("transactionAPIId",None)
        billPayment = data.get("billPayment",0)
        payload = data.get("payload",'')
        headers = data.get("headers",'')
        mobileNumber = data.get("mobileNumber","")
        categoryName = data.get("categoryName","")
        serviceName = data.get("serviceName","")
        operatorName = data.get("operatorName","")
        amount = data.get("amount")
        operatorReference = data.get("operatorReference","")
        errorMessage = data.get("errorMessage","")
        status = data.get("status")
        customeParamsList = data.get("customeParamsList",{})
        paymentType = data.get("paymentType","")
        
        location = data.get("location","")
        ccnum = data.get("ccnum","")
        ccname = data.get("ccname","")
        ccvv = data.get("ccvv","")
        ccexpmon = data.get("ccexpmon","")
        ccexpyr = data.get("ccexpyr","")
        vpa = data.get("vpa","")
        bankId = data.get("bankId","")
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status

    required_fields = [categoryName,serviceName, operatorName,mobileNumber,amount,operatorId]
    if not all(required_fields):
        data_status["responseStatus"] = 0
        data_status["result"] = "Required fields are missing."
        return data_status   

    
    bbps_setup = PrepaidMobileSetup.objects(serviceType="BBPS", status=1).first()
    if not bbps_setup or not bbps_setup.enablePrepaid:
        data_status["result"] = "BBPS Payment Setup is not enabled!"
        return data_status
    

   
    authtokenresp=getBbpsAuthorizationToken()
    authorizationToken=authtokenresp.get('accessToken')

    headers = {
        "content-type": "application/json",
        "authorization": "Bearer "+str(authorizationToken),
        }
            

    paymentGateWayCode=bbps_setup.prepaidPgId.code
    transactionAPIId=str(bbps_setup.prepaidPgId.id)
    paymentChannel=bbps_setup.prepaidPgId.apiName
    
    print("=============",paymentGateWayCode,paymentChannel,payload,headers)
    
    if amount is None:
        amount = 0
    else:
        amount = float(amount)

    if amount < 0:
        data_status["result"]="Insufficient amount!!"
        return data_status
    bankCode=""
    if paymentType == "NET BANKING":
        if not bankId:
            data_status["result"] = "Required fields are missing!!"
            return data_status
        master_bank_queryset = BankCodes.objects(transactionApiIdsList__in=[str(transactionAPIId)],bankId=str(bankId)).first()
        if not master_bank_queryset:
            data_status["result"] = "Required fields are missing!!"
            return data_status
        if master_bank_queryset:
            bankCode=master_bank_queryset.bankCode
            bankName=master_bank_queryset.bankId.bankName
    elif paymentType == "UPI":
        if not vpa:
            data_status["result"] = "Required fields are missing!!"
            return data_status
    else:
        if not ccnum or not ccname or not ccvv or not ccexpmon or not ccexpyr:
            data_status["result"]="Required fields are missing!!"
            return data_status

    
    print(paymentType,"===========paymentType===========")
    
    
    card_type=""
    if paymentType=="CARD":
        productDetails={
        "cardNum":ccnum,
        "cardCvv" :ccvv,
        "customerName" :ccname,
        "cardExpMonth":ccexpmon,
        "cardExpYear":ccexpyr
        }
        cardmasked=mask_account_number(ccnum)
        print(productDetails,"==========",cardmasked)
        paymentDetailsEncrypted=combined_encrypt(json.dumps(productDetails),encSecretKey)

        paymentDetailsDecrypted = combined_decrypt(paymentDetailsEncrypted, encSecretKey)

        print(paymentDetailsDecrypted,"(((((((((((((((((paymentDetailsDecrypted in payu response)))))))))))))))))",paymentDetailsEncrypted)

        # card_number=ccnum.replace(" ", "")
        print(ccnum)

        
        card_category=""
        card_type=""
        paymentType=""
        issuing_bank=""
        is_domestic="0"
        additonalCardType=""
  
        card_bin_response = card_bin_check(ccnum)
        print(card_bin_response,"card_bin_response123")
        if card_bin_response.get("responseStatus") == 1:
            card_category = card_bin_response.get("data").get("cardCategory")
            card_type = card_bin_response.get("data").get("cardType")
            is_domestic = card_bin_response.get("data").get("isDomestic")
            issuing_bank = card_bin_response.get("data").get("issuingBank")
            additonalCardType = card_bin_response.get("data").get("additonalCardType")
            if additonalCardType!=None:
                if issuing_bank=="HDFC":
                    card_type=str(additonalCardType)+"_"+str(issuing_bank)+"_"+str(card_type)
                else:
                    card_type=str(additonalCardType)+"_"+str(card_type)
            elif issuing_bank=="HDFC":
                card_type=str(issuing_bank)+"_"+str(card_type)

        print(card_type,"card_type")
        print(is_domestic,"is_domestic")
        if is_domestic!="1":
            print('is_domestic')
            data_status["result"] = "Only Accepts domestic cards only!!"
            return data_status

        if card_category!="":
            if card_category == "creditcard":
                paymentType = "CREDIT CARD"
            elif card_category == "debitcard":
                paymentType = "DEBIT CARD"
            else:
                data_status["result"] = "Invalid Card Type!!"
                return data_status
    try:
        user_queryset = Users.objects(id=userId,status=1).first()
        if not user_queryset:
            data_status["result"] = "Invalid user Id"
            return data_status
        firstname=str(user_queryset.fullName)
        email=str(user_queryset.email)
        phone=str(user_queryset.phoneNumber)

        
        
        # transactionId = transaction_id_prefix + str(mid_extracted) +str( get_epoch_milli_time())
        orderId = str(get_epoch_milli_time())+random_digit_generate(2)
        transactionId = random_digit_generate(15)
        merchantUniqueNumber=str(user_queryset.merchantUniqueNumber)
        mid_extracted = merchantUniqueNumber[1:].lstrip("0")
        pgOrderId=str(transaction_id_prefix)+str(mid_extracted)+str(orderId)
        
        commissionCharges = {}
        chargeAmount = 0.0
        commissionDictResult=operator_based_commission_details(userId,operatorId,transactionAPIId)
        if commissionDictResult.get('responseStatus')==1:
            commissionDict=commissionDictResult.get('commissionDict')
            if commissionDict:
                if commissionDict.get("chargeType") == "Percentage":
                    chargeAmount = (float(amount)*float(commissionDict.get("chargeValue")))/100
                elif commissionDict.get("chargeType") == "Fixed":
                    chargeAmount = float(commissionDict.get("chargeValue"))
                if commissionDict.get("commissionType") == "Percentage":
                    commissionAmount = (float(amount)*float(commissionDict.get("commissionValue")))/100
                elif commissionDict.get("commissionType") == "Fixed":
                    commissionAmount = float(commissionDict.get("commissionValue"))
                    
                    commissionCharges = {
                    "chargeType": commissionDict.get("chargeType"),
                    "chargeValue": commissionDict.get("chargeValue"),
                    "commissionType": commissionDict.get("commissionType"),
                    "commissionValue": commissionDict.get("commissionValue"),
                    "chargeAmount": chargeAmount,
                    "commissionAmount": commissionAmount
                    }
                    
        #Calulate total amount
        # // billPaymentRequestData=[]
        # // billPaymentResponseData=[]
        totalAmount = float(amount) - float(chargeAmount)
  
        
        transactionData={
            "userId":userId,
            "paymentChannel":paymentChannel,
            "location":location,
            "amount":amount,
            "transactionApiId":transactionAPIId,
            "email":email,
            "firstname":firstname,
            "phone":phone,
            "vpa":vpa,
            "bankId":bankId,
            "cardType":card_type,
            "paymentDetailsEncrypted":paymentDetailsEncrypted
            }

        
            
        transaction_table = Transactions(
            userId = userId,
            categoryId = categoryId,
            serviceId = serviceId,
            operatorId = operatorId,
            categoryName = categoryName,
            serviceName = serviceName,
            operatorName = operatorName,
            # // paymentCategory  = paymentCategory,
            cardNumber  = cardmasked,
            customerVpa  = vpa,
             # // walletName  = walletName,
             # // accountNumber  = accountNumber,
             # // ifscCode  = ifscCode,
            customeParamsList  = customeParamsList,
             # // paymentGatewayId = paymentGatewayId,
            transactionAPIId = transactionAPIId,
            transactionId = str(transactionId),
            pgOrderId= str(pgOrderId),
            # transactionData = transactionData,
            billPayment = str(billPayment),
            statusCheckId= str(pgOrderId),
            # billPaymentRequestData = billPaymentRequestData,
             # // billPaymentResponseData = billPaymentResponseData,
            mobileNumber = mobileNumber,
            paymentType=paymentType,
            amount = amount,
            customerName=firstname,
            bankCode=bankCode,
            customerEmail=email,
            totalAmount = totalAmount,
            cardDetails=paymentDetailsEncrypted,
            commissionCharges = commissionCharges,
            operatorReference = operatorReference,
            createdOn = datetime.datetime.now(),
            errorMessage=errorMessage,
            payload=payload,
            headers= headers,
            paymentStatus=2,
            bbpsPaymentStatus=2,
            refundStatus=2,
            status = 2
            ).save()
        
        transactionTableId = str(transaction_table.id)
        print(transactionTableId,"transactionTableId=====",transactionId,pgOrderId)
        if transactionTableId:
            upi_intent_url=""
            currency="INR"
            client_ip="125.40.25.126"
            print("(((paymentGateWayCode)))",paymentGateWayCode )

            if paymentGateWayCode == "Lyra_Payin":
                get_client = ""
                get_secret = ""
                get_base_url = ""
                user_name = ""
                get_base_url = ""
                password = ""
                webhook_url = ""
                return_url = ""
                for each_key in payin_gate_way_queryset.paramsList:
                    
                    
                    get_key = each_key.get("key")
                    if get_key == "api_key":
                        get_client = each_key.get("value")
                    if get_key == "secret_key":
                        get_secret = each_key.get("value")
                    if get_key == "base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "webhook_url":
                        webhook_url = each_key.get("value")
                    if get_key == "return_url":
                        return_url = each_key.get("value")
                    if get_key == "user_name":
                        user_name = each_key.get("value")
                    if get_key == "password":
                        password = each_key.get("value")
                ###################################################### Lyra Payin Code #########################################################################
                # paymentgatewayresponseDict = lyra_payin_payment_intent(get_base_url,pgOrderId,note,amount,currency,merchant_queryset.fullName,merchant_queryset.phoneNumber,merchant_queryset.email,webhook_url,return_url,userId,payInPaymentGatewayId,client_ip,"api",user_name,password)
                paymentgatewayresponseDict = lyra_payin_payment_intent(get_base_url,pgOrderId,amount,currency,firstname,phone,email,webhook_url,return_url,userId,transactionAPIId,client_ip,user_name,password)
                ################################################################################################################################################
            
                if paymentgatewayresponseDict.get("responseStatus") == 1:
                    transactionId = paymentgatewayresponseDict.get("payment_request_id")
                    transactionData = paymentgatewayresponseDict.get("transactionData")
                    paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
                    pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
                    upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
                    transaction_table.update(transactionId=transactionId,transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
                    data_status["responseStatus"]=1
                    data_status["transactionTableId"]=transactionTableId
                    data_status["transactionId"]=pgOrderId
                    data_status["PaymentLink"]=upi_intent_url
                    data_status["gatewayType"]=paymentGateWayCode
                    data_status["result"]="Payin response data saved successfully!"
                    return data_status
                else:
                    errorresult=paymentgatewayresponseDict.get("result")
                    transaction_table.update(errorMessage=errorresult,status=0)
                    data_status["result"]=errorresult
                    return data_status
                ################## PAYU Gateway
            elif paymentGateWayCode == "Payu_Payin":
                upi_intent_url=domain+"api/frontend/bbpspayupayment_dynamic_link/"+str(transactionTableId)
                print(upi_intent_url,"=====upi_intent_url====")
                data_status["responseStatus"]=1
                data_status["transactionId"]=transactionId
                data_status["transactionTableId"]=transactionTableId
                data_status["PaymentLink"]=upi_intent_url
                data_status["gatewayType"]=paymentGateWayCode
                data_status["result"]="Payin response data saved successfully!"
                return data_status

            elif paymentGateWayCode == "Getepay_Payin":
                mid = ""
                get_base_url = ""
                callback_url = ""
                return_url=""
                encryption_key = ""
                encryption_iv = ""
                terminalId = ""
                vpa = ""
                for each_key in payin_gate_way_queryset.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "mid":
                        mid = each_key.get("value")
                    if get_key == "get_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "callback_url":
                        callback_url = each_key.get("value")
                    if get_key == "return_url":
                        return_url = each_key.get("value")
                    if get_key == "encryption_key":
                        encryption_key = each_key.get("value")
                    if get_key == "encryption_iv":
                        encryption_iv = each_key.get("value")
                    if get_key == "terminalId":
                        terminalId = each_key.get("value")
                    if get_key == "vpa":
                        vpa = each_key.get("value")
               
                
                # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+"TPSL"+str(orderId)
                # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+str(orderId)
                transactionType="single"
                ###################################################### Wowpe Payin Code #########################################################################
                paymentgatewayresponseDict = getepayintent(get_base_url,encryption_key,encryption_iv,mid, return_url, callback_url, terminalId,amount,email,firstname,phone,currency,pgOrderId,transactionType,transactionAPIId,client_ip,userId,vpa)

                if paymentgatewayresponseDict.get("responseStatus") == 1:
                    transactionId = paymentgatewayresponseDict.get("payment_request_id")
                    transactionData = paymentgatewayresponseDict.get("transactionData")
                    paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
                    pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
                    upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
                    transaction_table.update(transactionId=transactionId,statusCheckId=str(transactionId),transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
                    data_status["responseStatus"]=1
                    PaymentLink=domain+"api/frontend/bbpspayupayment_dynamic_link/"+str(transactionTableId)
                    data_status["transactionId"]=pgOrderId
                    data_status["transactionTableId"]=transactionTableId
                    data_status["PaymentLink"]=PaymentLink
                    data_status["gatewayType"]=paymentGateWayCode
                    data_status["result"]="Payin response data saved successfully!"
                    return data_status
                else:
                    errorresult=paymentgatewayresponseDict.get("result")
                    transaction_table.update(errorMessage=errorresult,status=0)
                    data_status["result"]=errorresult
                    return data_status

            elif paymentGateWayCode == "Worldline_Payin":
                print("((((((((((((((((((Worldline_Payin))))))))))))))))))")
                get_base_url = ""
                callback_url = ""
                api_key = ""
                secret_key = ""
                merchantIdentifier = ""
                api_encryption_key = ""
                requestType = ""
                transactionType = ""
                encryption_iv = ""
                graampay_check = ""
                for each_key in payin_gate_way_queryset.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "get_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "merchantIdentifier":
                        merchantIdentifier = each_key.get("value")
                    if get_key == "callback_url":
                        callback_url = each_key.get("value")
                    if get_key == "encryption_key":
                        api_encryption_key = each_key.get("value")
                    if get_key == "encryption_iv":
                        encryption_iv = each_key.get("value")
                    if get_key == "transactionType":
                        transactionType = each_key.get("value")
                    if get_key == "requestType":
                        requestType = each_key.get("value")
                    # if get_key == "api_key":
                    #     api_key = each_key.get("value")
                    # if get_key == "secret_key":
                    #     secret_key = each_key.get("value")
                    # if get_key == "graampay_check":
                    #     graampay_check = each_key.get("value")
                cartIdentifier="FIRST"
                note=""
                ###################################################### Wowpe Payin Code #########################################################################
                # paymentgatewayresponseDict = create_campuslinkpro_payment_link_seamless(get_base_url,api_key,secret_key,graampay_check,pgOrderId,productName,amount,currency,firstname,phone,email,transactionApiId,client_ip,agent,userId)
                paymentgatewayresponseDict = worldline_create_seamless_payment_link(merchantIdentifier,get_base_url,callback_url,api_encryption_key,encryption_iv,pgOrderId,amount,cartIdentifier,ccnum,card_type,ccexpyr,ccexpmon,note,transactionType,requestType,ccvv)
                ###############################################################################################################################################

                if paymentgatewayresponseDict.get("responseStatus") == 1:
                    transactionId = paymentgatewayresponseDict.get("payment_request_id")
                    transactionData = paymentgatewayresponseDict.get("transactionData")
                    paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
                    pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
                    upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
                    transaction_table.update(transactionId=transactionId,transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
                    data_status["responseStatus"]=1
                    data_status["transactionId"]=pgOrderId
                    data_status["transactionTableId"]=transactionTableId
                    data_status["PaymentLink"]=upi_intent_url
                    data_status["gatewayType"]=paymentGateWayCode
                    data_status["result"]="Payin response data saved successfully!"
                    return data_status
                else:
                    errorresult=paymentgatewayresponseDict.get("result")
                    transaction_table.update(errorMessage=errorresult,status=0)
                    data_status["result"]=errorresult
                    return data_status
        else:
            data_status["result"]="Unable to save payin response data!!"
            return data_status
      
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Unable to make transaction"
        return data_status


@users.route("/bbpspayupayment_dynamic_link/<transactionTableId>",methods=["GET"])
def bbpspayupayment_dynamic_link(transactionTableId):
    data_status = {"responseStatus": 0, "result": ""}
    
    # walletId = request.json.get("walletId")
    if not transactionTableId:
        data_status["result"] = "Required fields are missing!!"
    
    try:
        transactions_query_set = Transactions.objects(id=ObjectId(transactionTableId),status__in=[2]).first()
        if transactions_query_set:

            txnid = transactions_query_set.pgOrderId
            paymentMode = transactions_query_set.paymentType
            # productinfo =  transactions_query_set.productName
            productinfo =  "Bill Payment"
            amount = transactions_query_set.amount
            email = transactions_query_set.customerEmail
            firstname = transactions_query_set.customerName
            phone = transactions_query_set.mobileNumber
            currency = "INR"
            
            client_ip="125.40.25.126"

            vpa=""
            ccnum=""
            ccname=""
            ccvv=""
            ccexpmon=""
            ccexpyr=""
            bankCode=""
            cardType=""
            if paymentMode=="UPI":
                vpa =  transactions_query_set.customerVpa
            elif paymentMode=="NET BANKING":
                bankCode = transactions_query_set.bankCode
            else:
                paymentDetailsEncrypted = transactions_query_set.cardDetails
                if paymentDetailsEncrypted!="":
                    paymentDetails=combined_decrypt(paymentDetailsEncrypted,encSecretKey)
                    paymentDetails=json.loads(paymentDetails)
                    ccnum = paymentDetails.get("cardNum")
                    ccname = paymentDetails.get("customerName")
                    ccvv = paymentDetails.get("cardCvv")
                    ccexpmon = paymentDetails.get("cardExpMonth")
                    ccexpyr = paymentDetails.get("cardExpYear")
                    cardType = paymentDetails.get("cardType")
            print("paymentMode",paymentMode)
            paymentGatewayId = transactions_query_set.transactionAPIId
            if paymentGatewayId.code == "Payu_Payin":
                key = ""
                salt = ""
                get_base_url = ""
                surl = ""
                furl = ""
                for each_key in paymentGatewayId.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "api_key":
                        key = each_key.get("value")
                    if get_key == "salt":
                        salt = each_key.get("value")
                    if get_key == "dynamic_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "bbpsSurl":
                        surl = each_key.get("value")
                    if get_key == "bbpsfurl":
                        furl = each_key.get("value")
                testresponse = payupayment_dynamic(paymentMode=paymentMode, get_salt=salt,get_base_url=get_base_url, key= key, txnid=txnid, productinfo=productinfo,amount=amount,email=email,firstname=firstname,surl=surl,furl=furl, phone=phone,ccnum=ccnum,ccname=ccname, ccvv=ccvv, ccexpmon=ccexpmon, ccexpyr=ccexpyr, vpa=vpa, bankCode=bankCode, card_type=cardType )
                if testresponse.get('responseStatus')==1:
                    return render_template("frontend/payupaymenttemplate.html",requestDataDict=testresponse.get('result'))
                else:
                    return testresponse

            elif paymentGatewayId.code == "Getepay_Payin":
                mid = ""
                get_base_url = ""
                callback_url = ""
                return_url=""
                encryption_key = ""
                encryption_iv = ""
                terminalId = ""
                encrypted_request = ""
                vpa = ""
                token = ""
                for each_key in paymentGatewayId.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "mid":
                        mid = each_key.get("value")
                    if get_key == "get_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "callback_url":
                        callback_url = each_key.get("value")
                    if get_key == "bbps_returnUrl":
                        return_url = each_key.get("value")
                    if get_key == "encryption_key":
                        encryption_key = each_key.get("value")
                    if get_key == "encryption_iv":
                        encryption_iv = each_key.get("value")
                    if get_key == "terminalId":
                        terminalId = each_key.get("value")
                    if get_key == "vpa":
                        vpa = each_key.get("value")
                token=transactions_query_set.transactionData[0].get('token')
                paymentgatewayresponseDict = getepaypaymentseamless(encryption_key,encryption_iv, return_url,amount,firstname,phone,currency,txnid,client_ip,token,ccnum,ccexpmon,ccexpyr,ccvv,paymentMode)
                if paymentgatewayresponseDict.get('responseStatus')==1:
                    encrypted_request=paymentgatewayresponseDict.get('encrypted_request')
                    return render_template("frontend/getepaypayment.html",get_base_url=get_base_url,mid=mid,terminalId=terminalId,encrypted_data=encrypted_request)
                else:
                    data_status["result"] = "Invalid payment request."
                    return data_status
        else:
            data_status["result"] = "Invalid transaction Id"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to test payu payment"
        return data_status

# @users.route("/add_utility_transaction",methods=["POST"])
# @encrypt_decrypt_after_login
# def add_utility_transaction():
#   data_status = {"responseStatus": 0, "result": ""}
#   # print(request.json,"add_utility_transaction")
#   try:
#       data = request.decrypted_data
#       userId = data.get("userId","")
#       categoryId = data.get("categoryId",None)
#       serviceId = data.get("serviceId",None)
#       operatorId = data.get("operatorId",None)
#       transactionAPIId = data.get("transactionAPIId",None)
#       billPayment = data.get("billPayment",0)
#       payload = data.get("payload",'')
#       headers = data.get("headers",'')
#       mobileNumber = data.get("mobileNumber","")
#       categoryName = data.get("categoryName","")
#       serviceName = data.get("serviceName","")
#       operatorName = data.get("operatorName","")
#       amount = data.get("amount")
#       operatorReference = data.get("operatorReference","")
#       errorMessage = data.get("errorMessage","")
#       status = data.get("status")
#       customeParamsList = data.get("customeParamsList",{})
        
#       setlementId =""
  
    
#       location = data.get("location","")
#       ccnum = data.get("ccnum","")
#       ccname = data.get("ccname","")
#       ccvv = data.get("ccvv","")
#       ccexpmon = data.get("ccexpmon","")
#       ccexpyr = data.get("ccexpyr","")
#       vpa = data.get("vpa","")
#       bankId = data.get("bankId","")
#   except Exception as e:
#       app.logger.error(traceback.format_exc())
#       data_status["result"] = "Invalid Request"
#       return data_status

#   required_fields = [categoryName,serviceName, operatorName,mobileNumber,amount,operatorId,transactionAPIId]
#   if not all(required_fields):
#       data_status["responseStatus"] = 0
#       data_status["result"] = "Required fields are missing."
#       return data_status   

    
#   bbbps_setup = PrepaidMobileSetup.objects(serviceType="bbps", status=1).first()
#   if not bbps_setup or not bbps_setup.enablePrepaid:
#       data_status["result"] = "BBPS Payment Setup is not enabled!"
#       return data_status

#   prepaid_setup = PrepaidMobileSetup.objects(serviceType="prepaid", status=1).first()
#   if not prepaid_setup or not prepaid_setup.enablePrepaid:
#       data_status["result"] = "Prepaid Payment Setup is not enabled!"
#       return data_status
            
#   if amount is None:
#           amount = 0
#   else:
#       amount = float(amount)

#   if amount < 0:
#       data_status["result"]="Insufficient amount!!"
#       return data_status

#   if paymentMode == "NET BANKING":
#       if not bankId:
#           data_status["result"] = "Required fields are missing!!"
#           return data_status
#       master_bank_queryset = BankCodes.objects(bankId=str(bankId),transactionApiIdsList__in=[str(transactionAPIId)]).first()
#       if not master_bank_queryset:
#           data_status["result"] = "Required fields are missing!!"
#           return data_status
#       if master_bank_queryset:
#           bankCode=master_bank_queryset.bankCode
#           bankName=master_bank_queryset.bankId.bankName
#   elif paymentMode == "UPI":
#       if not vpa:
#           data_status["result"] = "Required fields are missing!!"
#           return data_status
#   else:
#       if not ccnum or not ccname or not ccvv or not ccexpmon or not ccexpyr:
#           data_status["result"]="Required fields are missing!!"
#           return data_status

#   payment_mode_queryset = PaymentMode.objects(paymentMode=paymentMode).first()
#   if not payment_mode_queryset:
#       data_status["result"]="Required fields are missing!!"
#       return data_status

#   paymentModeId = str(payment_mode_queryset.id)
#   sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=subPaymentMode).first()
#   if not sub_payment_mode_queryset:
#       data_status["result"]="Required fields are missing!!"
#       return data_status
#   subPaymentModeId = str(sub_payment_mode_queryset.id)
 
#   if paymentMode=="CREDIT CARD" or paymentMode=="DEBIT CARD":
#       productDetails={
#       "cardNum":ccnum,
#       "cardCvv" :ccvv,
#       "customerName" :ccname,
#       "cardExpMonth":ccexpmon,
#       "cardExpYear":ccexpyr
#       }
#       cardmasked=mask_account_number(ccnum)
#       paymentDetailsEncrypted=combined_encrypt(json.dumps(productDetails),encSecretKey)

#       paymentDetailsDecrypted = combined_decrypt(paymentDetailsEncrypted, encSecretKey)

#       print(paymentDetailsDecrypted,"(((((((((((((((((paymentDetailsDecrypted in payu response)))))))))))))))))")

#       # card_number=ccnum.replace(" ", "")
#       print(ccnum)

        
#       card_category=""
#       card_type=""
#       paymentType=""
#       issuing_bank=""
#       is_domestic="0"
#       additonalCardType=""
  
#       card_bin_response = card_bin_check(ccnum)
#       print(card_bin_response,"card_bin_response123")
#       if card_bin_response.get("responseStatus") == 1:
#           card_category = card_bin_response.get("data").get("cardCategory")
#           card_type = card_bin_response.get("data").get("cardType")
#           is_domestic = card_bin_response.get("data").get("isDomestic")
#           issuing_bank = card_bin_response.get("data").get("issuingBank")
#           additonalCardType = card_bin_response.get("data").get("additonalCardType")
#           if additonalCardType!=None:
#               if issuing_bank=="HDFC":
#                   card_type=str(additonalCardType)+"_"+str(issuing_bank)+"_"+str(card_type)
#               else:
#                   card_type=str(additonalCardType)+"_"+str(card_type)
#           elif issuing_bank=="HDFC":
#               card_type=str(issuing_bank)+"_"+str(card_type)

#       print(card_type,"card_type")
#       print(is_domestic,"is_domestic")
#       if is_domestic!="1":
#           print('is_domestic')
#           data_status["result"] = "Only Accepts domestic cards only!!"
#           return data_status

#       if card_category!="":
#           if card_category == "creditcard":
#               paymentType = "CREDIT CARD"
#           elif card_category == "debitcard":
#               paymentType = "DEBIT CARD"
#           else:
#               data_status["result"] = "Invalid Card Type!!"
#               return data_status


#   # payin_gate_way_queryset = TransactionAPI.objects(id=str(transactionAPIId),status=1).first()
#   # if not payin_gate_way_queryset:
#   #   data_status["result"]="Invalid Request."
#   #   return data_status
#   # paymentGateWayCode = payin_gate_way_queryset.code

#   try:
#       user_queryset = Users.objects(id=userId,status=1).first()
#       if not user_queryset:
#           data_status["result"] = "Invalid user Id"
#           return data_status
#       firstname=str(user_queryset.fullName)
#       email=str(user_queryset.email)
#       phone=str(user_queryset.phoneNumber)
#       merchantUniqueNumber = str(user_queryset.merchantUniqueNumber)
#       mid_extracted = merchantUniqueNumber[1:].lstrip("0")
#       transactionId = transaction_id_prefix + str(mid_extracted) +str( get_epoch_milli_time())
#       commissionCharges = {}
#       chargeAmount = 0.0
#       commissionDictResult=operator_based_commission_details(userId,operatorId,transactionAPIId)
#       if commissionDictResult.get('responseStatus')==1:
#           commissionDict=commissionDictResult.get('commissionDict')
#           if commissionDict:
#               if commissionDict.get("chargeType") == "Percentage":
#                   chargeAmount = (float(amount)*float(commissionDict.get("chargeValue")))/100
#               elif commissionDict.get("chargeType") == "Fixed":
#                   chargeAmount = float(commissionDict.get("chargeValue"))
#               if commissionDict.get("commissionType") == "Percentage":
#                   commissionAmount = (float(amount)*float(commissionDict.get("commissionValue")))/100
#               elif commissionDict.get("commissionType") == "Fixed":
#                   commissionAmount = float(commissionDict.get("commissionValue"))
                    
#                   commissionCharges = {
#                   "chargeType": commissionDict.get("chargeType"),
#                   "chargeValue": commissionDict.get("chargeValue"),
#                   "commissionType": commissionDict.get("commissionType"),
#                   "commissionValue": commissionDict.get("commissionValue"),
#                   "chargeAmount": chargeAmount,
#                   "commissionAmount": commissionAmount
#                   }
                    
#       #Calulate total amount
#       # // billPaymentRequestData=[]
#       # // billPaymentResponseData=[]
#       totalAmount = float(amount) - float(chargeAmount)
  
        
#       transactionData={
#           "userId":userId,
#           "paymentChannel":paymentChannel,
            
#           "location":location,
#           "amount":amount,
#           # "otpCheckId":otpCheckId,
#           "productName":productName,
#           "setlementId":setlementId,
#           "paymentMode":paymentMode,
#           "transactionApiId":transactionAPIId,
#           "subPaymentMode":subPaymentMode,
#           "email":email,
#           "firstname":firstname,
#           "phone":phone,
#           "vpa":vpa,
#           "bankId":bankId,
#           "cardType":cardType,
#           "paymentDetailsEncrypted":paymentDetailsEncrypted
#           }

        
            
#       transaction_table = Transactions(
#           userId = userId,
#           categoryId = categoryId,
#           serviceId = serviceId,
#           operatorId = operatorId,
#           categoryName = categoryName,
#           serviceName = serviceName,
#           operatorName = operatorName,
#           paymentType  = paymentType,
#           paymentMode = paymentMode,
#           subPaymentMode =subPaymentMode,
#           cardType=cardType,
#           # // paymentCategory  = paymentCategory,
#           cardNumber  = cardmasked,
#           customerVpa  = vpa,
#           # // walletName  = walletName,
#           # // accountNumber  = accountNumber,
#           # // ifscCode  = ifscCode,
#           customeParamsList  = customeParamsList,
#           # // paymentGatewayId = paymentGatewayId,
#           transactionAPIId = transactionAPIId,
#           transactionId = str(transactionId),
#           # transactionData = transactionData,
#           billPayment = str(billPayment),
#           billPaymentRequestData = billPaymentRequestData,
#           # // billPaymentResponseData = billPaymentResponseData,
#           mobileNumber = mobileNumber,
#           amount = amount,
#           totalAmount = totalAmount,
#               cardDetails=paymentDetailsEncrypted,
#           commissionCharges = commissionCharges,
#           operatorReference = operatorReference,
#           createdOn = datetime.datetime.now(),
#           errorMessage=errorMessage,
#           payload=payload,
#           headers= headers,
#           status = 2
#           ).save()
#       transactionTableId = str(transaction_table.id)
#       if transactionTableId:
#           upi_intent_url=""
#           currency="INR"
#           client_ip="125.40.25.126"
#           print("(((paymentGateWayCode)))",paymentGateWayCode )

#           if paymentGateWayCode == "Lyra_Payin":
#               get_client = ""
#               get_secret = ""
#               get_base_url = ""
#               user_name = ""
#               get_base_url = ""
#               password = ""
#               webhook_url = ""
#               return_url = ""
#               for each_key in payin_gate_way_queryset.paramsList:
                    
                    
#                   get_key = each_key.get("key")
#                   if get_key == "api_key":
#                       get_client = each_key.get("value")
#                   if get_key == "secret_key":
#                       get_secret = each_key.get("value")
#                   if get_key == "base_url":
#                       get_base_url = each_key.get("value")
#                   if get_key == "webhook_url":
#                       webhook_url = each_key.get("value")
#                   if get_key == "return_url":
#                       return_url = each_key.get("value")
#                   if get_key == "user_name":
#                       user_name = each_key.get("value")
#                   if get_key == "password":
#                       password = each_key.get("value")
#               ###################################################### Lyra Payin Code #########################################################################
#               # paymentgatewayresponseDict = lyra_payin_payment_intent(get_base_url,pgOrderId,note,amount,currency,merchant_queryset.fullName,merchant_queryset.phoneNumber,merchant_queryset.email,webhook_url,return_url,userId,payInPaymentGatewayId,client_ip,"api",user_name,password)
#               paymentgatewayresponseDict = lyra_payin_payment_intent(get_base_url,transactionId,amount,currency,firstname,phone,email,webhook_url,return_url,userId,transactionAPIId,client_ip,user_name,password)
#               ################################################################################################################################################
            
#               if paymentgatewayresponseDict.get("responseStatus") == 1:
#                   transactionId = paymentgatewayresponseDict.get("payment_request_id")
#                   transactionData = paymentgatewayresponseDict.get("transactionData")
#                   paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
#                   pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
#                   upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
#                   transaction_table.update(transactionId=transactionId,transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
#                   data_status["responseStatus"]=1
#                   data_status["transactionTableId"]=transactionTableId
#                   data_status["transactionId"]=pgOrderId
#                   data_status["PaymentLink"]=upi_intent_url
#                   data_status["gatewayType"]=paymentGateWayCode
#                   data_status["result"]="Payin response data saved successfully!"
#                   return data_status
#               else:
#                   errorresult=paymentgatewayresponseDict.get("result")
#                   transaction_table.update(errorMessage=errorresult,status=0)
#                   data_status["result"]=errorresult
#                   return data_status
#               ################## PAYU Gateway
#           elif paymentGateWayCode == "Payu_Payin":
#               upi_intent_url=domain+"api/frontend/payupayment_dynamic_link/"+str(transactionTableId)
#               data_status["responseStatus"]=1
#               data_status["transactionId"]=pgOrderId
#               data_status["transactionId"]=transactionId
#               data_status["PaymentLink"]=upi_intent_url
#               data_status["gatewayType"]=paymentGateWayCode
#               data_status["result"]="Payin response data saved successfully!"
#               return data_status

#           elif paymentGateWayCode == "Getepay_Payin":
#               mid = ""
#               get_base_url = ""
#               callback_url = ""
#               return_url=""
#               encryption_key = ""
#               encryption_iv = ""
#               terminalId = ""
#               vpa = ""
#               for each_key in payin_gate_way_queryset.paramsList:
#                   get_key = each_key.get("key")
#                   if get_key == "mid":
#                       mid = each_key.get("value")
#                   if get_key == "get_base_url":
#                       get_base_url = each_key.get("value")
#                   if get_key == "callback_url":
#                       callback_url = each_key.get("value")
#                   if get_key == "return_url":
#                       return_url = each_key.get("value")
#                   if get_key == "encryption_key":
#                       encryption_key = each_key.get("value")
#                   if get_key == "encryption_iv":
#                       encryption_iv = each_key.get("value")
#                   if get_key == "terminalId":
#                       terminalId = each_key.get("value")
#                   if get_key == "vpa":
#                       vpa = each_key.get("value")
               
                
#               # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+"TPSL"+str(orderId)
#               # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+str(orderId)
#               transactionType="single"
#               ###################################################### Wowpe Payin Code #########################################################################
#               paymentgatewayresponseDict = getepayintent(get_base_url,encryption_key,encryption_iv,mid, return_url, callback_url, terminalId,amount,email,firstname,phone,currency,pgOrderId,transactionType,transactionAPIId,client_ip,userId,vpa)

#               if paymentgatewayresponseDict.get("responseStatus") == 1:
#                   transactionId = paymentgatewayresponseDict.get("payment_request_id")
#                   transactionData = paymentgatewayresponseDict.get("transactionData")
#                   paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
#                   pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
#                   upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
#                   transaction_table.update(transactionId=transactionId,statusCheckId=str(transactionId),transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
#                   data_status["responseStatus"]=1
#                   PaymentLink=domain+"api/frontend/payupayment_dynamic_link/"+str(walletId)
#                   data_status["transactionId"]=pgOrderId
#                   data_status["transactionId"]=transactionId
#                   data_status["PaymentLink"]=PaymentLink
#                   data_status["gatewayType"]=paymentGateWayCode
#                   data_status["result"]="Payin response data saved successfully!"
#                   return data_status
#               else:
#                   errorresult=paymentgatewayresponseDict.get("result")
#                   transaction_table.update(errorMessage=errorresult,status=0)
#                   data_status["result"]=errorresult
#                   return data_status

#           elif paymentGateWayCode == "Worldline_Payin":
#               print("((((((((((((((((((Worldline_Payin))))))))))))))))))")
#               get_base_url = ""
#               callback_url = ""
#               api_key = ""
#               secret_key = ""
#               merchantIdentifier = ""
#               api_encryption_key = ""
#               requestType = ""
#               transactionType = ""
#               encryption_iv = ""
#               graampay_check = ""
#               for each_key in payin_gate_way_queryset.paramsList:
#                   get_key = each_key.get("key")
#                   if get_key == "get_base_url":
#                       get_base_url = each_key.get("value")
#                   if get_key == "merchantIdentifier":
#                       merchantIdentifier = each_key.get("value")
#                   if get_key == "callback_url":
#                       callback_url = each_key.get("value")
#                   if get_key == "encryption_key":
#                       api_encryption_key = each_key.get("value")
#                   if get_key == "encryption_iv":
#                       encryption_iv = each_key.get("value")
#                   if get_key == "transactionType":
#                       transactionType = each_key.get("value")
#                   if get_key == "requestType":
#                       requestType = each_key.get("value")
#                   # if get_key == "api_key":
#                   #     api_key = each_key.get("value")
#                   # if get_key == "secret_key":
#                   #     secret_key = each_key.get("value")
#                   # if get_key == "graampay_check":
#                   #     graampay_check = each_key.get("value")
#               cartIdentifier="FIRST"
#               note=""
#               ###################################################### Wowpe Payin Code #########################################################################
#               # paymentgatewayresponseDict = create_campuslinkpro_payment_link_seamless(get_base_url,api_key,secret_key,graampay_check,pgOrderId,productName,amount,currency,firstname,phone,email,transactionApiId,client_ip,agent,userId)
#               paymentgatewayresponseDict = worldline_create_seamless_payment_link(merchantIdentifier,get_base_url,callback_url,api_encryption_key,encryption_iv,pgOrderId,amount,cartIdentifier,ccnum,cardType,ccexpyr,ccexpmon,note,transactionType,requestType,ccvv)
#               ###############################################################################################################################################

#               if paymentgatewayresponseDict.get("responseStatus") == 1:
#                   transactionId = paymentgatewayresponseDict.get("payment_request_id")
#                   transactionData = paymentgatewayresponseDict.get("transactionData")
#                   paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
#                   pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
#                   upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
#                   transaction_table.update(transactionId=transactionId,transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
#                   data_status["responseStatus"]=1
#                   data_status["transactionId"]=pgOrderId
#                   data_status["transactionId"]=transactionId
#                   data_status["PaymentLink"]=upi_intent_url
#                   data_status["gatewayType"]=paymentGateWayCode
#                   data_status["result"]="Payin response data saved successfully!"
#                   return data_status
#               else:
#                   errorresult=paymentgatewayresponseDict.get("result")
#                   transaction_table.update(errorMessage=errorresult,status=0)
#                   data_status["result"]=errorresult
#                   return data_status
#       else:
#           data_status["result"]="Unable to save payin response data!!"
#           return data_status
      
#   except Exception as e:
#       app.logger.error(traceback.format_exc())
#       data_status["result"] = "Unable to make transaction"
#       return data_status
    

##business pan api check is not enabled in signzy
@users.route("/validate_pan_number_and_name",methods=["POST"])
@encrypt_decrypt_after_login
def validate_pan_number_and_name():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        panNumber = data.get("panNumber")
        nameOnPan = data.get("nameOnPan")
        userId = data.get("userId")
        if panNumber and nameOnPan and userId:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status

            panKycResponseStatusDict=verify_individual_pan(panNumber,"IndividualPan",userId)
            if panKycResponseStatusDict.get("responseStatus") == 1:

                if panKycResponseStatusDict.get("panStatus").lower() == "valid":
                    scorecheck=0.6
                    name_match_response = name_match_check(panKycResponseStatusDict.get("name"),nameOnPan,scorecheck)
                    if name_match_response.get("responseStatus") == 1:
                        data_status["responseStatus"] = 1
                        data_status["OriginalBusinessPanName"] = str(panKycResponseStatusDict.get("name"))
                        data_status["panAddress"] = str(panKycResponseStatusDict.get("address"))
                        data_status["panResponseData"] = str(panKycResponseStatusDict.get("responseData"))
                        data_status["result"] ="success"
                    else:
                        data_status["result"] ="Given Name did not match with Pan Name"
                else:
                    data_status["result"] = "pan verification failed"
            else:
                data_status["result"] = "pan verification failed"
            return data_status
        else:
            data_status["result"]="Required field is missing!!"
            return data_status
    except Exception as e:
        print(traceback.format_exc())
        data_status["result"] = "Unable to verify Pan."
        return data_status

##business pan api check is not enabled in signzy
@users.route("/validate_bank_account",methods=["POST"])
@encrypt_decrypt_after_login
def validate_bank_account():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        accountNumber = data.get("accountNumber")
        ifscCode = data.get("ifscCode")
        userId = data.get("userId","")
        if accountNumber and userId and ifscCode:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status
            accountHolderName=str(user_queryset.fullName)
            mobileNumber=str(user_queryset.phoneNumber)
            bankStatusDict=verify_bank_account(accountNumber,ifscCode,"Bank",accountHolderName,mobileNumber,userId)
            print(bankStatusDict,"bankStatusDict")
            if bankStatusDict.get("responseStatus") == 1:
                if bankStatusDict.get("nameMatch")=="" or bankStatusDict.get("nameMatch").lower()=="no":
                    print("if name")
                    scorecheck=0.6
                    name_match_response = name_match_check(bankStatusDict.get("beneficiaryName"),accountHolderName,scorecheck)
                    print(name_match_response,"name_match_response")
                    if name_match_response.get("responseStatus") == 1:
                        data_status["responseStatus"] = 1
                        data_status["OriginalBankHolderName"] = str(bankStatusDict.get("beneficiaryName"))
                        data_status["bankResponseData"] = str(bankStatusDict.get("apiResponse"))
                        data_status["result"] ="success"
                    else:
                        data_status["result"] = "Given Account Number Name does not match with registered Name"

                elif bankStatusDict.get("nameMatch").lower() == "yes":
                    print("else name")
                    data_status["responseStatus"] = 1
                    data_status["OriginalBankHolderName"] = str(bankStatusDict.get("beneficiaryName"))
                    data_status["bankResponseData"] = str(bankStatusDict.get("apiResponse"))
                    data_status["result"] ="success"
                else:
                    data_status["result"] = "Given Account Number Name does not match with registered Name"
            else:
                data_status["result"] = bankStatusDict.get('result')
            return data_status
        else:
            data_status["result"]="Required field is missing!!"
            return data_status
    except Exception as e:
        print(traceback.format_exc())
        data_status["result"] = "Unable to verify Pan."
        return data_status


#business pan api check is not enabled in signzy
@users.route("/validate_aadhar_number",methods=["POST"])
@encrypt_decrypt_after_login
def validate_aadhar_number():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        aadhaar_number = data.get("aadharNumber")
        aadhaar_name = data.get("aadharName")
        if aadhaar_name and userId and aadhaar_number:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status
            aadharMobileResponse=verify_aadhar_number(aadhaar_number,aadhaar_name,"Aadhar","Aadhar",userId)
            if aadharMobileResponse.get('responseStatus')==0 or aadharMobileResponse.get('mobileNumber')=="":
                data_status["result"]="Something went wrong.Please try again."
                return data_status
            mobileNumber=str(user_queryset.phoneNumber)
            mobileNumberlast3digits=mobileNumber[-3:]
            aadharMobileNumber=aadharMobileResponse.get('mobileNumber')
            aadharmobileNumberlast3digits=aadharMobileNumber[-3:]
            if aadharMobileNumber=="" or mobileNumberlast3digits!=aadharmobileNumberlast3digits:
                data_status["responseStatus"] = 5
                data_status["result"]="Aadhar registered mobile number not matched with registered mobile number"
                return data_status

            if aadharMobileResponse.get('responseStatus')==1:
                data_status["responseStatus"] = 1
                data_status["otpenabled"] = aadharMobileResponse.get('otpenabled')
                data_status["kycApiId"] = aadharMobileResponse.get('kycApiId')
                data_status["accessKey"] = aadharMobileResponse.get('accessKey')
                data_status["aadharResponseData"] = str(aadharMobileResponse.get('aadharResponseData'))
                data_status["result"] ="Aadhar verified successfully."
                return data_status
            else:
                data_status["result"] = "aadhar verification failed."
                return data_status
        else:
            data_status["result"]="Required field is missing!!"
            return data_status
    except Exception as e:
        print(traceback.format_exc())
        data_status["result"] = "Unable to verify Aadhar number."
        return data_status

#business pan api check is not enabled in signzy
@users.route("/validate_aadhar_number_otp",methods=["POST"])
@encrypt_decrypt_after_login
def validate_aadhar_number_otp():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        userId = data.get("userId")
        aadhaar_number = data.get("aadharNumber")
        aadhaar_name = data.get("aadharName")
        accessKey = data.get("accessKey")
        otpCode = data.get("otpCode")
        kycApiId = data.get("kycApiId")
        if aadhaar_name and userId and aadhaar_number and otpCode and kycApiId:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"] = "Invalid user Id"
                return data_status
            verifyresponse=verify_aadhar_otp(aadhaar_number,aadhaar_name,accessKey,otpCode,kycApiId,"AadharMobileMatch",userId)
            if verifyresponse.get('responseStatus')==1:
                data_status["responseStatus"] = 1
                data_status["aadharResponseData"] = str(verifyresponse.get('aadharResponseData'))
                data_status["result"] ="Otp verified successfully."
                return data_status
            else:
                data_status["result"] = "Incorrect Otp."
                return data_status
        else:
            data_status["result"]="Required field is missing!!"
            return data_status
    except Exception as e:
        print(traceback.format_exc())
        data_status["result"] = "Incorrect Otp."
        return data_status


@users.route("/graampay_health_check", methods=["GET"])
def graampay_health_check():
    healthCheckDict = {}
    overall_health = "red"  # Default to red
    try:
        if request.method == "GET":
            countries_queryset = Countries.objects(status=1)
            if countries_queryset:
                healthCheckDict = {"database": True}
            else:
                healthCheckDict = {"database": False}

            idfc_api_queryset = TransactionAPI.objects(code="Idfc_Payout").first()
            if idfc_api_queryset:
                client_id = ""
                secretKey = ""
                kid = ""
                get_base_url = ""
                aud_url = ""
                auth_url = ""
                grant_type = ""
                scope = ""
                source = ""
                client_assertion_type = ""
                debitAcountNumber = ""
                remitterName = ""

                for each_key in idfc_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()

                currentBalanceDict = idfc_get_payout_account_balance(debitAcountNumber,source,kid,aud_url,client_id,auth_url,grant_type,scope,client_assertion_type,secretKey)
                if currentBalanceDict.get("responseStatus") == 1:
                    availableBalance = currentBalanceDict.get("availableBalance")
                    healthCheckDict.update({"idfcStatus": True})
                else:
                    healthCheckDict.update({"idfcStatus": False})

            else:
                healthCheckDict.update({"idfcStatus": False})



            axis_api_queryset = TransactionAPI.objects(code="Axis_Payout").first()
            if axis_api_queryset:
                client_id = ""
                client_secret = ""
                get_api_key=""
                channelId=""
                serviceRequestId=""
                corpCode=""
                serviceRequestVersion=""
                get_base_url=""
                corp_account_number=""

                for each_key in axis_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))

                currentBalanceDict = axis_payout_get_account_balance(client_id, client_secret, get_api_key, channelId, get_base_url, requestUUID, serviceRequestId, serviceRequestVersion, corpCode,corp_account_number)
                if currentBalanceDict.get("responseStatus") == 1:
                    availableBalance = currentBalanceDict.get("availableBalance")
                    healthCheckDict.update({"axisStatus": True})
                else:
                    healthCheckDict.update({"axisStatus": False})
            else:
                healthCheckDict.update({"axisStatus": False})


            print(healthCheckDict,"((((((((healthCheckDict))))))))")

            # Determine overall health status
            if all(healthCheckDict.values()):
                overall_health = "green"
            elif any(healthCheckDict.values()):
                overall_health = "orange"

            return render_template(
                "frontend/health_check.html",
                healthCheckDict=healthCheckDict,
                overall_health=overall_health,
            )
    except Exception as e:
        app.logger.error(traceback.format_exc())
        error = "Unable to get health check data!!"
        return render_template(
            "frontend/health_check.html",
            error=error,
            healthCheckDict=healthCheckDict,
            overall_health="red",
        )




@users.route("/getPriceRanges", methods=["POST"])
@encrypt_decrypt_after_login
def getPriceRanges():
    data_status = {"responseStatus":0,"result":""}

    try:
        startDate = datetime.datetime.now()
        availability_check = check_transaction_availability(startDate, "paymentgateway")
        if availability_check.get('responseStatus')==0:
            data_status["result"]="Service Provider is not available. Please try after sometime."
            return data_status

        encryptedBody = request.json.get("encryptedBody")
        ivKey = request.json.get("ivKey")
        if not encryptedBody and not ivKey:
            data_status["result"]="Required fields are missing!!3"
            return data_status

        try:
            decryptResponse=request.decrypted_data
            print(decryptResponse,"((((((((((((((((decryptResponse decryptResponse))))))))))))))))")
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Invalid Request"
            return data_status
        
        userId = decryptResponse.get("userId","")
        amount = decryptResponse.get("amount","")
        paymentMode = decryptResponse.get("paymentMode","")
        ccnum = decryptResponse.get("ccnum","")
        ccname = decryptResponse.get("ccname","")
        ccvv = decryptResponse.get("ccvv","")
        ccexpmon = decryptResponse.get("ccexpmon","")
        ccexpyr = decryptResponse.get("ccexpyr","")
        vpa = decryptResponse.get("vpa","")
        bankId = decryptResponse.get("bankId","")
        siteTitle = decryptResponse.get("siteTitle","pipocash")
        instantSettlement = decryptResponse.get("instantSettlement",2)
        cardCategory=""
        cardType=""
        bankCode=""
        if not userId or not amount or not paymentMode or instantSettlement not in [0,1,2]:
            data_status["result"]="Required fields are missing!!"
            return data_status
        merchant_queryset = Users.objects(id=str(userId),status=1).first()
        if not merchant_queryset:
            data_status["result"]="Invalid Request."
            return data_status

        check_kyc_status = merchant_kyc_status(str(merchant_queryset.id))
        if check_kyc_status.get("responseStatus") != 1:
            data_status["result"]="Merchant KYC is not completed please contact to admin!!"
            return data_status
        kycStatus = check_kyc_status.get("merchantKycDetails", {}).get("kycStatus")
        if kycStatus == False:
            data_status["result"]="Merchant KYC is not completed please contact to admin!!"
            return data_status

        if amount is None:
            amount = 0
        else:
            amount = float(amount)

        if amount < 0:
            data_status["result"]="Insufficient amount!!"
            return data_status

        if paymentMode.lower() == "nb":
            cardCategory="NET BANKING"
            if not bankId:
                data_status["result"] = "Required fields are missing!!"
                return data_status
        elif paymentMode.lower() == "upi":
            cardCategory="UPI"
            if not vpa:
                data_status["result"] = "Required fields are missing!!"
                return data_status
        else:
            if not ccnum and not ccname and not ccvv and not ccexpmon and not ccexpyr:
                data_status["result"]="Required fields are missing!!"
                return data_status
        ccnum=ccnum.replace(" ", "")
        defaultPayinPaymentGatewayId=""
        if merchant_queryset.patternId.payinEnable==True:
            try:
                defaultPayinPaymentGatewayId=str(merchant_queryset.patternId.defaultPayinPaymentGatewayId.id)
            except Exception as e:
                app.logger.error(traceback.format_exc())
                defaultPayinPaymentGatewayId = ""
        print(siteTitle,"siteTitle")
        siteId=""
        instantSettlementtype=None
        if instantSettlement==0 or instantSettlement==1:
            if instantSettlement==0:
                instantSettlementtype=True
            else:
                instantSettlementtype=False
        else:
            instantSettlementtype=None
        if siteTitle:
            site_queryset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
            if not site_queryset:
                data_status["result"] = "Invalid App Request.Contact to admin support."
                return data_status
            siteId=str(site_queryset.id)
            if instantSettlement==2 and site_queryset.defaultSettlement!=None:
                instantSettlementtype=site_queryset.defaultSettlement
        print(instantSettlementtype,"instantSettlementtype")
        print(type(instantSettlementtype),"instantSettlementtype type")
        dynamic_payment_gateway_id_response = get_dynamic_payment_gateway_id(amount=amount,payment_mode=paymentMode,card_number=ccnum,transactionApiId=defaultPayinPaymentGatewayId,siteId=siteId,instantSettlement=instantSettlementtype)
        instantSettlementtype=None
        transactionApiId=""
        if dynamic_payment_gateway_id_response.get("responseStatus") == 1:
            transactionApiId = dynamic_payment_gateway_id_response.get("transactionApiId")
            instantSettlementtype = dynamic_payment_gateway_id_response.get("instantSettlementtype")
            if transactionApiId=="":
                data_status["result"]="Collection Payment Provider Not available!!"
                return data_status

            transaction_data=TransactionAPI.objects(id=str(transactionApiId)).first()
            if not transaction_data:
                data_status["result"]="Error while getting paymentgateway!!"
                return data_status

            paymentModeId=dynamic_payment_gateway_id_response.get('paymentmodeId')   
            subPaymentModeId=dynamic_payment_gateway_id_response.get('subPaymentModeId')

            

            commissionCharges = slab_calculation_for_payin_merchant(amount,paymentModeId,subPaymentModeId,str(merchant_queryset.patternId.id),instantSettlementtype)
            if commissionCharges.get("slabId") == None:
                data_status["result"]="Collection Payment Provider Not available!!"
                return data_status
            else:
                chargeAmount = float(commissionCharges.get("chargeAmount"))
                if chargeAmount<=0:
                    data_status["result"]="Collection Payment Provider Not available!!"
                    return data_status

            randomPrices=[]
            productName="Bill Payment"
            print(transactionApiId,"transactionApiId")
            print(amount,"amount")
            amount=float(amount)
            print(type(amount),"amount type")
            singleTxnLowerLimit=1
            singleTxnUpperLimit=99995
            check_transaction_limits = merchant_transaction_limit_settings("Payin",transactionApiId,userId,amount)
            if check_transaction_limits.get("responseStatus") == 0:
                data_status['result']=check_transaction_limits.get("result")
                return data_status
            singleTxnLowerLimit=check_transaction_limits.get('singleTxnLowerLimit')
            singleTxnUpperLimit=check_transaction_limits.get('singleTxnUpperLimit')
            productData=Products.objects(payinPaymentGatewayId=str(transactionApiId),startingPrice__lte=amount,endingPrice__gte=amount).first()
            if productData:
                productName=productData.productName
            
            print(transaction_data.apiName,"apiName")
            print(transaction_data.priceType,"priceType")
            
            # print(generate_random_prices(amount),"(((((((((((CHECK RANDOM )))))))))))")
            if transaction_data.priceType=="variable":
                print("hiiiiii")
                randomPrices=generate_random_prices(int(amount),singleTxnLowerLimit,singleTxnUpperLimit)
                randomPrices.sort()
            else:
                print(productData,"productData")
                if productData:
                    randomPrices.append(int(productData.price))
                else:
                    randomPrices.append(int(amount))
            print(randomPrices,"randomPrices")
            data_status["responseStatus"]=1
            data_status["randomPrices"]=randomPrices
            data_status["productName"]=productName
            data_status["transactionApiId"]=transactionApiId
            data_status["instantSettlementtype"]=instantSettlementtype
            data_status["issuingBank"]=dynamic_payment_gateway_id_response.get('issuingBank')
            data_status["paymentmode"]=dynamic_payment_gateway_id_response.get('paymentMode')
            data_status["subPaymentMode"]=dynamic_payment_gateway_id_response.get('subPaymentMode')
            data_status["cardType"]=dynamic_payment_gateway_id_response.get('cardType')
            data_status["result"]="Success"
            return data_status
        else:
            data_status["result"]=dynamic_payment_gateway_id_response.get('result')
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        print(traceback.format_exc(),"traceback_error")
        data_status["result"]="Unable to save payin response data!!"
        return data_status


@users.route("/payin_payment_create_intent_seamless", methods=["POST"])
@encrypt_decrypt_after_login
def payin_payment_create_intent_seamless():
    data_status = {"responseStatus":0,"result":""}

    try:
        startDate = datetime.datetime.now()
        availability_check = check_transaction_availability(startDate, "paymentgateway")
        if availability_check.get('responseStatus')==0:
            data_status["result"]="Service Provider is not available. Please try after sometime."
            return data_status

        encryptedBody = request.json.get("encryptedBody")
        ivKey = request.json.get("ivKey")
        if not encryptedBody and not ivKey:
            data_status["result"]="Required fields are missing!!3"
            return data_status

        try:
            decryptResponse=request.decrypted_data
            print(decryptResponse,"((((((((((((((((decryptResponse decryptResponse))))))))))))))))")
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"]="Invalid Request"
            return data_status
        
        print(decryptResponse,"payin_payment_create_intent_seamless")
        userId = decryptResponse.get("userId","")
        paymentChannel = decryptResponse.get("paymentChannel","")
        agent = decryptResponse.get("agent","")
        location = decryptResponse.get("location","")
        
        amount = decryptResponse.get("amount","")
        # otpCheckId = decryptResponse.get("otpCheckId","")
        productName = decryptResponse.get("productName","")
        setlementId =""
        paymentMode = decryptResponse.get("paymentMode","")
        transactionApiId = decryptResponse.get("transactionApiId","")
        subPaymentMode = decryptResponse.get("subPaymentMode","")
        issuingBank = decryptResponse.get("issuingBank","")
        productinfo = productName
        # email = decryptResponse.get("email","")
        # firstname = decryptResponse.get("firstname","")
        # phone = decryptResponse.get("mobileNumber","")
        ccnum = decryptResponse.get("ccnum","")
        ccname = decryptResponse.get("ccname","")
        ccvv = decryptResponse.get("ccvv","")
        ccexpmon = decryptResponse.get("ccexpmon","")
        ccexpyr = decryptResponse.get("ccexpyr","")
        vpa = decryptResponse.get("vpa","")
        bankId = decryptResponse.get("bankId","")
        cardType=decryptResponse.get("cardType","")
        siteTitle=decryptResponse.get("siteTitle","")
        instantSettlement=decryptResponse.get("instantSettlement",2)
        bankCode=""
        bankName=""

        if not userId or not amount or not paymentMode or instantSettlement not in [0,1,2]: # and not firstname and not email and not phone
            data_status["result"]="Required fields are missing!!"
            return data_status
        

        if amount is None:
            amount = 0
        else:
            amount = float(amount)

        if amount < 0:
            data_status["result"]="Insufficient amount!!"
            return data_status

        # currentDateStart = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
        # currentDateEnd = currentDateStart.replace(hour=23, minute=59, second=59, microsecond=999999)

        # checkphoneNumber = WalletTransactions.objects(customerPhonenumber=str(phone),status=1,createdOn__gte=currentDateStart,createdOn__lte=currentDateEnd).first()
        # if checkphoneNumber:
        #     data_status["result"]="Only one transaction is allowed per Phone Number for one customer per day."
        #     return data_status

        # checkEmail = WalletTransactions.objects(customerEmail=str(email),status=1,createdOn__gte=currentDateStart,createdOn__lte=currentDateEnd).first()
        # if checkEmail:
        #     data_status["result"]="Only one transaction is allowed per Email for one customer per day."
        #     return data_status
        
        instantSettlementtype=None
        if instantSettlement==0 or instantSettlement==1:
            if instantSettlement==0:
                instantSettlementtype=True
            else:
                instantSettlementtype=False
        else:
            instantSettlementtype=None

        if paymentMode == "NET BANKING":
            if not bankId:
                data_status["result"] = "Required fields are missing!!"
                return data_status
            master_bank_queryset = BankCodes.objects(transactionApiIdsList__in=[str(transactionApiId)],bankId=str(bankId)).first()
            if not master_bank_queryset:
                data_status["result"] = "Required fields are missing!!"
                return data_status
            if master_bank_queryset:
                bankCode=master_bank_queryset.bankCode
                bankName=master_bank_queryset.bankId.bankName
        elif paymentMode == "UPI":
            if not vpa:
                data_status["result"] = "Required fields are missing!!"
                return data_status
        else:
            bankName=issuingBank
            if not ccnum or not ccname or not ccvv or not ccexpmon or not ccexpyr:
                data_status["result"]="Required fields are missing!!"
                return data_status

        payment_mode_queryset = PaymentMode.objects(paymentMode=paymentMode).first()
        if not payment_mode_queryset:
            data_status["result"]="Required fields are missing!!"
            return data_status

        paymentModeId = str(payment_mode_queryset.id)
        sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=subPaymentMode).first()
        if not sub_payment_mode_queryset:
            data_status["result"]="Required fields are missing!!"
            return data_status
        subPaymentModeId = str(sub_payment_mode_queryset.id)
        #no
        siteId=""
        merchant_queryset=None
        if siteTitle:
            site_queryset = MultipleAppSites.objects(siteCode=siteTitle,status=1).first()
            if not site_queryset:
                data_status["result"] = "Invalid App Request.Contact to admin support."
                return data_status
            siteId=str(site_queryset.id)
            if instantSettlement==2 and site_queryset.defaultSettlement!=None:
                instantSettlementtype=site_queryset.defaultSettlement
            merchant_queryset = Users.objects(id=str(userId),status=1,siteTitle=siteTitle).first()
        else:
            merchant_queryset = Users.objects((Q(id=str(userId)) & Q(status=1)) & (Q(siteTitle=None) | Q(siteTitle=""))).first()

        if not merchant_queryset:
            data_status["result"]="Invalid Request."
            return data_status

        if instantSettlementtype==None:
            get_site_paymentgateway=SiteAssignPaymentgateways.objects(siteId=siteId,paymentModeId=paymentModeId,subPaymentModeId=subPaymentModeId,transactionApiId__ne=None,status=1).first()
            if not get_site_paymentgateway:
                data_status["result"]="Service Provider is not available!!"
                return data_status
            instantSettlementtype=get_site_paymentgateway.instantSettlement

        check_kyc_status = merchant_kyc_status(str(merchant_queryset.id))
        if check_kyc_status.get("responseStatus") != 1:
            data_status["result"]="Merchant KYC is not completed please contact to admin!!"
            return data_status
        kycStatus = check_kyc_status.get("merchantKycDetails", {}).get("kycStatus")
        if kycStatus == False:
            data_status["result"]="Merchant KYC is not completed please contact to admin!!"
            return data_status

        # if merchant_queryset.merchantType=="customer":
        #     if otpCheckId=="":
        #         data_status["result"]="Invalid Request."
        #         return data_status
        #     otpcheck_querryset=OtpChecks.objects(userId=str(userId),id=str(otpCheckId),status=1).first()
        #     if not otpcheck_querryset:
        #         data_status["result"]="Invalid Request."
        #         return data_status
        #     otpcheck_querryset.update(status=2)

        payin_gate_way_queryset = TransactionAPI.objects(id=str(transactionApiId),status=1).first()
        if not payin_gate_way_queryset:
            data_status["result"]="Invalid Request."
            return data_status

        # check_transaction_limits = merchant_transaction_limit_settings("Payin",payInPaymentGatewayId,userId,amount)
        check_transaction_limits = merchant_transaction_limit_settings("Payin",transactionApiId,userId,amount)
        if check_transaction_limits.get("responseStatus") == 0:
            data_status['result']=check_transaction_limits.get("result")
            return data_status

        paymentGateWayCode = payin_gate_way_queryset.code

        random_customer_qry = RandomCcCustomers.objects.aggregate([{ "$sample": { "size": 1 } }])  # Get a random record
        #no
        random_doc=list(random_customer_qry)
        if random_doc: 
            random_customer=random_doc[0]
            firstname=random_customer.get("customerName")
            email=random_customer.get("customerEmail")
            phone=random_customer.get("customerPhoneNumber")
        else:
            firstname=str(merchant_queryset.fullName)
            email=str(merchant_queryset.email)
            phone=str(merchant_queryset.phoneNumber)
        errorMessage="Initiated"
        # paymentMode=""
        customerVpa=""
        # cardType=""
        cardmasked=""
        patternId = str(merchant_queryset.patternId.id)
        slabId = None
        transactionAmount = amount
        commissionCharges={}
        orderId = str(get_epoch_milli_time())+random_digit_generate(2)
        transactionId = random_digit_generate(15)
        
        walletId=""
        productDetails={}
        paymentDetailsEncrypted=''
        if paymentMode=="CREDIT CARD" or paymentMode=="DEBIT CARD":
            productDetails={
            "cardNum":ccnum,
            "cardCvv" :ccvv,
            "customerName" :ccname,
            "cardExpMonth":ccexpmon,
            "cardExpYear":ccexpyr
            }
            cardmasked=mask_account_number(ccnum)
            paymentDetailsEncrypted=combined_encrypt(json.dumps(productDetails),encSecretKey)

            paymentDetailsDecrypted = combined_decrypt(paymentDetailsEncrypted, encSecretKey)

            print(paymentDetailsDecrypted,"(((((((((((((((((paymentDetailsDecrypted in payu response)))))))))))))))))")
        transactionData={
        "userId":userId,
        "paymentChannel":paymentChannel,
        "agent":agent,
        "location":location,
        "amount":amount,
        # "otpCheckId":otpCheckId,
        "productName":productName,
        "setlementId":setlementId,
        "paymentMode":paymentMode,
        "transactionApiId":transactionApiId,
        "subPaymentMode":subPaymentMode,
        "issuingBank":issuingBank,
        "email":email,
        "firstname":firstname,
        "phone":phone,
        "vpa":vpa,
        "bankId":bankId,
        "cardType":cardType,
        "paymentDetailsEncrypted":paymentDetailsEncrypted
        }

        merchantUniqueNumber=str(merchant_queryset.merchantUniqueNumber)
        mid_extracted = merchantUniqueNumber[1:].lstrip("0")
        pgOrderId=str(transaction_id_prefix)+str(mid_extracted)+str(orderId)
        wallet_transaction_table = WalletTransactions(
            userId = userId,
            amount = round_last_digits(float(amount)),
            grandTotal=round_last_digits(float(transactionAmount)),
            paymentGatewayId = transactionApiId,
            currency="INR",
            paymentType = paymentMode,
            subPaymentMode = subPaymentMode,
            creditType = "Credit",
            patternId=patternId,
            transactionId = transactionId,
            transactionData = [transactionData],
            orderId = orderId,
            walletLog="",
            userType="user",
            createdBy = None,
            createdOn = datetime.datetime.now(),
            location = location,
            platform = "app",
            agent = agent,
            customerEmail = email,
            customerName = firstname,
            customerPhonenumber = phone,
            previousBalance=0,
            currentBalance=0,
            paymentLinkId = None,
            PaymentButtonId = None,
            paymentPageId = None,
            errorMessage = errorMessage,
            paymentChannel = paymentChannel,
            bankRefId="",
            cardmasked=cardmasked,
            productName=productName,
            setlementId=setlementId,
            pgOrderId=pgOrderId,
            statusCheckId=pgOrderId,
            customerVpa=vpa,
            commissionCharges=commissionCharges,
            settlementStatus = 1,
            status = 3,
            paymentDetails=paymentDetailsEncrypted,
            comment = productinfo,
            bankCode=bankCode,
            bankName=bankName,
            siteTitle=siteTitle,
            cardType=cardType
            )
        wallet_save=wallet_transaction_table.save()
        wallet_save.update(instantSettlement=instantSettlementtype)
        walletId=str(wallet_save.id)
        upi_intent_url=""
        currency="INR"
        client_ip="125.40.25.126"
        print("(((paymentGateWayCode)))",paymentGateWayCode )
        if walletId:
            if paymentGateWayCode == "Lyra_Payin":
                get_client = ""
                get_secret = ""
                get_base_url = ""
                user_name = ""
                get_base_url = ""
                password = ""
                webhook_url = ""
                return_url = ""
                for each_key in payin_gate_way_queryset.paramsList:
                    
                    
                    get_key = each_key.get("key")
                    if get_key == "api_key":
                        get_client = each_key.get("value")
                    if get_key == "secret_key":
                        get_secret = each_key.get("value")
                    if get_key == "base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "webhook_url":
                        webhook_url = each_key.get("value")
                    if get_key == "return_url":
                        return_url = each_key.get("value")
                    if get_key == "user_name":
                        user_name = each_key.get("value")
                    if get_key == "password":
                        password = each_key.get("value")
                ###################################################### Lyra Payin Code #########################################################################
                # paymentgatewayresponseDict = lyra_payin_payment_intent(get_base_url,pgOrderId,note,amount,currency,merchant_queryset.fullName,merchant_queryset.phoneNumber,merchant_queryset.email,webhook_url,return_url,userId,payInPaymentGatewayId,client_ip,"api",user_name,password)
                paymentgatewayresponseDict = lyra_payin_payment_intent(get_base_url,pgOrderId,productName,amount,currency,firstname,phone,email,webhook_url,return_url,userId,transactionApiId,client_ip,agent,user_name,password)
                ################################################################################################################################################
            
                if paymentgatewayresponseDict.get("responseStatus") == 1:
                    transactionId = paymentgatewayresponseDict.get("payment_request_id")
                    transactionData = paymentgatewayresponseDict.get("transactionData")
                    paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
                    pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
                    upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
                    wallet_save.update(transactionId=transactionId,transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
                    data_status["responseStatus"]=1
                    data_status["transactionId"]=pgOrderId
                    data_status["walletId"]=walletId
                    data_status["PaymentLink"]=upi_intent_url
                    data_status["gatewayType"]=paymentGateWayCode
                    data_status["result"]="Payin response data saved successfully!"
                    return data_status
                else:
                    errorresult=paymentgatewayresponseDict.get("result")
                    wallet_save.update(errorMessage=errorresult,status=0)
                    data_status["result"]=errorresult
                    return data_status
                ################## PAYU Gateway
            elif paymentGateWayCode == "Payu_Payin":
                upi_intent_url=domain+"api/frontend/payupayment_dynamic_link/"+str(walletId)
                data_status["responseStatus"]=1
                data_status["transactionId"]=pgOrderId
                data_status["walletId"]=walletId
                data_status["PaymentLink"]=upi_intent_url
                data_status["gatewayType"]=paymentGateWayCode
                data_status["result"]="Payin response data saved successfully!"
                return data_status

            elif paymentGateWayCode == "Getepay_Payin":
                mid = ""
                get_base_url = ""
                callback_url = ""
                return_url=""
                encryption_key = ""
                encryption_iv = ""
                terminalId = ""
                vpa = ""
                for each_key in payin_gate_way_queryset.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "mid":
                        mid = each_key.get("value")
                    if get_key == "get_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "callback_url":
                        callback_url = each_key.get("value")
                    if get_key == "return_url":
                        return_url = each_key.get("value")
                    if get_key == "encryption_key":
                        encryption_key = each_key.get("value")
                    if get_key == "encryption_iv":
                        encryption_iv = each_key.get("value")
                    if get_key == "terminalId":
                        terminalId = each_key.get("value")
                    if get_key == "vpa":
                        vpa = each_key.get("value")
               
                
                # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+"TPSL"+str(orderId)
                # pgOrderId = merchant_queryset.merchantUniqueNumber+"-"+str(orderId)
                transactionType="single"
                ###################################################### Wowpe Payin Code #########################################################################
                paymentgatewayresponseDict = getepayintent(get_base_url,encryption_key,encryption_iv,mid, return_url, callback_url, terminalId,amount,email,firstname,phone,currency,pgOrderId,transactionType,transactionApiId,client_ip,productName,agent,userId,vpa)

                if paymentgatewayresponseDict.get("responseStatus") == 1:
                    transactionId = paymentgatewayresponseDict.get("payment_request_id")
                    transactionData = paymentgatewayresponseDict.get("transactionData")
                    paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
                    pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
                    upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
                    wallet_save.update(transactionId=transactionId,statusCheckId=str(transactionId),transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
                    data_status["responseStatus"]=1
                    PaymentLink=domain+"api/frontend/payupayment_dynamic_link/"+str(walletId)
                    data_status["transactionId"]=pgOrderId
                    data_status["walletId"]=walletId
                    data_status["PaymentLink"]=PaymentLink
                    data_status["gatewayType"]=paymentGateWayCode
                    data_status["result"]="Payin response data saved successfully!"
                    return data_status
                else:
                    errorresult=paymentgatewayresponseDict.get("result")
                    wallet_save.update(errorMessage=errorresult,status=0)
                    data_status["result"]=errorresult
                    return data_status

            elif paymentGateWayCode == "Worldline_Payin":
                print("((((((((((((((((((Worldline_Payin))))))))))))))))))")
                get_base_url = ""
                callback_url = ""
                api_key = ""
                secret_key = ""
                merchantIdentifier = ""
                api_encryption_key = ""
                requestType = ""
                transactionType = ""
                encryption_iv = ""
                graampay_check = ""
                for each_key in payin_gate_way_queryset.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "get_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "merchantIdentifier":
                        merchantIdentifier = each_key.get("value")
                    if get_key == "callback_url":
                        callback_url = each_key.get("value")
                    if get_key == "encryption_key":
                        api_encryption_key = each_key.get("value")
                    if get_key == "encryption_iv":
                        encryption_iv = each_key.get("value")
                    if get_key == "transactionType":
                        transactionType = each_key.get("value")
                    if get_key == "requestType":
                        requestType = each_key.get("value")
                    # if get_key == "api_key":
                    #     api_key = each_key.get("value")
                    # if get_key == "secret_key":
                    #     secret_key = each_key.get("value")
                    # if get_key == "graampay_check":
                    #     graampay_check = each_key.get("value")
                cartIdentifier="FIRST"
                note=""
                ###################################################### Wowpe Payin Code #########################################################################
                # paymentgatewayresponseDict = create_campuslinkpro_payment_link_seamless(get_base_url,api_key,secret_key,graampay_check,pgOrderId,productName,amount,currency,firstname,phone,email,transactionApiId,client_ip,agent,userId)
                paymentgatewayresponseDict = worldline_create_seamless_payment_link(merchantIdentifier,get_base_url,callback_url,api_encryption_key,encryption_iv,pgOrderId,amount,cartIdentifier,ccnum,cardType,ccexpyr,ccexpmon,note,transactionType,requestType,ccvv)
                ###############################################################################################################################################

                if paymentgatewayresponseDict.get("responseStatus") == 1:
                    transactionId = paymentgatewayresponseDict.get("payment_request_id")
                    transactionData = paymentgatewayresponseDict.get("transactionData")
                    paymentChannel = paymentgatewayresponseDict.get("paymentChannel")
                    pgOrderId=paymentgatewayresponseDict.get("pgOrderId")
                    upi_intent_url=paymentgatewayresponseDict.get("upi_intent_url")
                    wallet_save.update(transactionId=transactionId,transactionData=transactionData,paymentChannel=paymentChannel,paymentLink=upi_intent_url)
                    data_status["responseStatus"]=1
                    data_status["transactionId"]=pgOrderId
                    data_status["walletId"]=walletId
                    data_status["PaymentLink"]=upi_intent_url
                    data_status["gatewayType"]=paymentGateWayCode
                    data_status["result"]="Payin response data saved successfully!"
                    return data_status
                else:
                    errorresult=paymentgatewayresponseDict.get("result")
                    wallet_save.update(errorMessage=errorresult,status=0)
                    data_status["result"]=errorresult
                    return data_status
            else:
                data_status["responseStatus"]=1
                data_status["transactionId"]=orderId
                data_status["walletId"]=walletId
                data_status["PaymentLink"]=upi_intent_url
                data_status["gatewayType"]=paymentGateWayCode
                data_status["result"]="Payin response data saved successfully!"
                return data_status
        else:
            data_status["result"]="Unable to save payin response data!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        print(traceback.format_exc(),"traceback_error")
        data_status["result"]="Unable to save payin response data!!"
        return data_status


@users.route("/checklyraurl", methods=["POST","GET"])
def checklyraurl():
    try:
        url="https://api.in.lyra.com/charge/39628da7208542bcbacefc44cb0a93f4"
        return redirect(url)
    except Exception as e:
        url="https://api.in.lyra.com/charge/39628da7208542bcbacefc44cb0a93f4"
        return redirect(url)

# def get_dynamic_payment_gateway_id(amount,payment_mode,card_number,transactionApiId):
#     data_status = {"responseStatus": 0, "result": "","card_category":"", "card_type": ""}
#     if not amount and not payment_mode:
#         data_status["result"] = "Required fields are missing!!"
#         return data_status
#     try:
#         paymentModeId=""
#         subPaymentModeId=""
#         card_category=""
#         card_type=""
#         paymentType=""
#         subPaymentMode=""
#         issuing_bank=""
#         is_domestic="0"
#         additonalCardType=""
#         if payment_mode.lower() == "card":
#             card_bin_response = card_bin_check(card_number)
#             print(card_bin_response,"card_bin_response123")
#             if card_bin_response.get("responseStatus") == 1:
#                 card_category = card_bin_response.get("data").get("cardCategory")
#                 card_type = card_bin_response.get("data").get("cardType")
#                 is_domestic = card_bin_response.get("data").get("isDomestic")
#                 issuing_bank = card_bin_response.get("data").get("issuingBank")
#                 additonalCardType = card_bin_response.get("data").get("additonalCardType")
#                 if additonalCardType!=None:
#                     if issuing_bank=="HDFC":
#                         card_type=str(additonalCardType)+"_"+str(issuing_bank)+"_"+str(card_type)
#                     else:
#                         card_type=str(additonalCardType)+"_"+str(card_type)
#                 elif issuing_bank=="HDFC":
#                     card_type=str(issuing_bank)+"_"+str(card_type)

#             print(card_type,"card_type")
#             print(is_domestic,"is_domestic")
#             if is_domestic!="1":
#                 print('is_domestic')
#                 data_status["result"] = "Only Accepts domestic cards only!!"
#                 return data_status
            
#             if card_category!="":
#                 if card_category == "creditcard":
#                     paymentType = "CREDIT CARD"
#                 elif card_category == "debitcard":
#                     paymentType = "DEBIT CARD"
#                 else:
#                     data_status["result"] = "Invalid Card Type!!"
#                     return data_status
#         elif payment_mode.lower() == "upi" or payment_mode.lower() == "nb":
#             if payment_mode.lower()=="nb":
#                 paymentType="NET BANKING"
#             else:
#                 paymentType="UPI"
#         else:
#             data_status["result"] = "Unknown payment mode!!"
#             return data_status
#         print(card_category,"card_category")
#         paymentmode_queryset = PaymentMode.objects(paymentMode=paymentType,status=1).first()
#         if paymentmode_queryset:
#             paymentModeId = str(paymentmode_queryset.id)
#             if card_type!="":
#                 subPaymentMode=card_type
#                 sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=str(subPaymentMode)).first()
#                 if sub_payment_mode_queryset:
#                     subPaymentModeId = str(sub_payment_mode_queryset.id)
#             else:
#                 subPaymentMode=paymentType
#                 sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=str(subPaymentMode)).first()
#                 if sub_payment_mode_queryset:
#                     subPaymentModeId = str(sub_payment_mode_queryset.id)
        
#         if subPaymentModeId=="":
#             subPaymentMode=paymentType
#             sub_payment_mode_queryset = SubPaymentModes.objects(paymentModeId=paymentModeId,subPaymentModeType=str(subPaymentMode)).first()
#             if sub_payment_mode_queryset:
#                 subPaymentModeId = str(sub_payment_mode_queryset.id)

#         data_status["paymentMode"] = paymentType
#         data_status["subPaymentMode"] = subPaymentMode
#         data_status["cardType"] = card_type
#         data_status["issuingBank"] = issuing_bank
#         data_status["paymentmodeId"] = paymentModeId
#         data_status["subPaymentModeId"] = subPaymentModeId
#         print(data_status,"data_status")
#         if transactionApiId=="":
#             calculated_charges = slab_calculation_for_payin_api_dynamic(amount,paymentModeId,subPaymentModeId) 
#             if calculated_charges.get("responseStatus") == 1:
#                 transactionApiId =calculated_charges.get('min_transactionApi_id')
#             else:
#                 data_status["result"]=calculated_charges.get("result")
#                 return data_status
                
#         data_status["result"]="success"
#         data_status["transactionApiId"] = transactionApiId
#         data_status["responseStatus"] =1
#         return data_status
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         print("exception")
#         data_status["result"] = "Unable to get PaymentMode id!!"
#         return data_status


@users.route("/pipopayupayment_dynamic_link",methods=["POST"]) ##( not using for now )
@encrypt_decrypt_after_login
def pipopayupayment_dynamic_link():
    print('pipopayupayment_dynamic_link')
    # print(request.json,"data")
    # walletId=request.json.get('txnId')
    data_status = {"responseStatus": 0, "result": ""}
    try:
        data = request.decrypted_data
        walletId = data.get('txnId')
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "Invalid Request"
        return data_status
    
    try:
        wallet_query_set = WalletTransactions.objects(id=ObjectId(walletId),status__in=[3]).first()
        if wallet_query_set:

            txnid = wallet_query_set.pgOrderId
            paymentMode = wallet_query_set.paymentType
            productinfo =  wallet_query_set.productName
            amount = wallet_query_set.amount
            email = wallet_query_set.customerEmail
            firstname = wallet_query_set.customerName
            phone = wallet_query_set.customerPhonenumber
            currency = wallet_query_set.currency
            client_ip="125.40.25.126"

            vpa=""
            ccnum=""
            ccname=""
            ccvv=""
            ccexpmon=""
            ccexpyr=""
            bankCode=""
            cardType=""
            if paymentMode=="UPI":
                vpa =  wallet_query_set.customerVpa
            elif paymentMode=="NET BANKING":
                bankCode = wallet_query_set.bankCode
            else:
                paymentDetailsEncrypted = wallet_query_set.paymentDetails
                if paymentDetailsEncrypted!="":
                    paymentDetails=combined_decrypt(paymentDetailsEncrypted,encSecretKey)
                    paymentDetails=json.loads(paymentDetails)
                    ccnum = paymentDetails.get("cardNum")
                    ccname = paymentDetails.get("customerName")
                    ccvv = paymentDetails.get("cardCvv")
                    ccexpmon = paymentDetails.get("cardExpMonth")
                    ccexpyr = paymentDetails.get("cardExpYear")
                    cardType = paymentDetails.get("cardType")

            paymentGatewayId = wallet_query_set.paymentGatewayId
            if paymentGatewayId.code == "Payu_Payin":
                key = ""
                salt = ""
                get_base_url = ""
                surl = ""
                furl = ""
                for each_key in paymentGatewayId.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "api_key":
                        key = each_key.get("value")
                    if get_key == "salt":
                        salt = each_key.get("value")
                    if get_key == "dynamic_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "surl":
                        surl = each_key.get("value")
                    if get_key == "furl":
                        furl = each_key.get("value")
                testresponse = payupayment_dynamic(paymentMode=paymentMode, get_salt=salt,get_base_url=get_base_url, key= key, txnid=txnid, productinfo=productinfo,amount=amount,email=email,firstname=firstname,surl=surl,furl=furl, phone=phone,ccnum=ccnum,ccname=ccname, ccvv=ccvv, ccexpmon=ccexpmon, ccexpyr=ccexpyr, vpa=vpa, bankCode=bankCode, card_type=cardType)
                return testresponse

            elif paymentGatewayId.code == "Getepay_Payin":
                mid = ""
                get_base_url = ""
                callback_url = ""
                return_url=""
                encryption_key = ""
                encryption_iv = ""
                terminalId = ""
                encrypted_request = ""
                vpa = ""
                token = ""
                for each_key in paymentGatewayId.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "mid":
                        mid = each_key.get("value")
                    if get_key == "get_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "callback_url":
                        callback_url = each_key.get("value")
                    if get_key == "return_url":
                        return_url = each_key.get("value")
                    if get_key == "encryption_key":
                        encryption_key = each_key.get("value")
                    if get_key == "encryption_iv":
                        encryption_iv = each_key.get("value")
                    if get_key == "terminalId":
                        terminalId = each_key.get("value")
                    if get_key == "vpa":
                        vpa = each_key.get("value")
                token=wallet_query_set.transactionData[0].get('token')
                paymentgatewayresponseDict = getepaypaymentseamless(encryption_key,encryption_iv, return_url,amount,firstname,phone,currency,txnid,client_ip,token,ccnum,ccexpmon,ccexpyr,ccvv,paymentMode)
                if paymentgatewayresponseDict.get('responseStatus')==1:
                    encrypted_request=paymentgatewayresponseDict.get('encrypted_request')
                    data_status['responseStatus']=1
                    data_status['result']=encrypted_request
                    return data_status
                    # return render_template("frontend/getepaypayment.html",get_base_url=get_base_url,mid=mid,terminalId=terminalId,encrypted_data=encrypted_request)
                else:
                    data_status["result"] = "Invalid payment request."
                    return data_status
        else:
            data_status["result"] = "Invalid transaction Id"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to test payu payment"
        return data_status


@users.route("/payupayment_dynamic_link/<walletId>",methods=["GET"])
def payupayment_dynamic_link(walletId):
    data_status = {"responseStatus": 0, "result": ""}
    
    # walletId = request.json.get("walletId")
    if not walletId:
        data_status["result"] = "Required fields are missing!!"
    
    try:
        wallet_query_set = WalletTransactions.objects(id=ObjectId(walletId),status__in=[3]).first()
        if wallet_query_set:

            txnid = wallet_query_set.pgOrderId
            paymentMode = wallet_query_set.paymentType
            productinfo =  wallet_query_set.productName
            amount = wallet_query_set.amount
            email = wallet_query_set.customerEmail
            firstname = wallet_query_set.customerName
            phone = wallet_query_set.customerPhonenumber
            currency = wallet_query_set.currency
            client_ip="125.40.25.126"

            vpa=""
            ccnum=""
            ccname=""
            ccvv=""
            ccexpmon=""
            ccexpyr=""
            bankCode=""
            cardType=""
            if paymentMode=="UPI":
                vpa =  wallet_query_set.customerVpa
            elif paymentMode=="NET BANKING":
                bankCode = wallet_query_set.bankCode
            else:
                paymentDetailsEncrypted = wallet_query_set.paymentDetails
                if paymentDetailsEncrypted!="":
                    paymentDetails=combined_decrypt(paymentDetailsEncrypted,encSecretKey)
                    paymentDetails=json.loads(paymentDetails)
                    ccnum = paymentDetails.get("cardNum")
                    ccname = paymentDetails.get("customerName")
                    ccvv = paymentDetails.get("cardCvv")
                    ccexpmon = paymentDetails.get("cardExpMonth")
                    ccexpyr = paymentDetails.get("cardExpYear")
                    cardType = paymentDetails.get("cardType")

            paymentGatewayId = wallet_query_set.paymentGatewayId
            if paymentGatewayId.code == "Payu_Payin":
                key = ""
                salt = ""
                get_base_url = ""
                surl = ""
                furl = ""
                for each_key in paymentGatewayId.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "api_key":
                        key = each_key.get("value")
                    if get_key == "salt":
                        salt = each_key.get("value")
                    if get_key == "dynamic_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "surl":
                        surl = each_key.get("value")
                    if get_key == "furl":
                        furl = each_key.get("value")
                testresponse = payupayment_dynamic(paymentMode=paymentMode, get_salt=salt,get_base_url=get_base_url, key= key, txnid=txnid, productinfo=productinfo,amount=amount,email=email,firstname=firstname,surl=surl,furl=furl, phone=phone,ccnum=ccnum,ccname=ccname, ccvv=ccvv, ccexpmon=ccexpmon, ccexpyr=ccexpyr, vpa=vpa, bankCode=bankCode, card_type=cardType )
                if testresponse.get('responseStatus')==1:
                    return render_template("frontend/payupaymenttemplate.html",requestDataDict=testresponse.get('result'))
                else:
                    return testresponse

            elif paymentGatewayId.code == "Getepay_Payin":
                mid = ""
                get_base_url = ""
                callback_url = ""
                return_url=""
                encryption_key = ""
                encryption_iv = ""
                terminalId = ""
                encrypted_request = ""
                vpa = ""
                token = ""
                for each_key in paymentGatewayId.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "mid":
                        mid = each_key.get("value")
                    if get_key == "get_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "callback_url":
                        callback_url = each_key.get("value")
                    if get_key == "return_url":
                        return_url = each_key.get("value")
                    if get_key == "encryption_key":
                        encryption_key = each_key.get("value")
                    if get_key == "encryption_iv":
                        encryption_iv = each_key.get("value")
                    if get_key == "terminalId":
                        terminalId = each_key.get("value")
                    if get_key == "vpa":
                        vpa = each_key.get("value")
                token=wallet_query_set.transactionData[0].get('token')
                paymentgatewayresponseDict = getepaypaymentseamless(encryption_key,encryption_iv, return_url,amount,firstname,phone,currency,txnid,client_ip,token,ccnum,ccexpmon,ccexpyr,ccvv,paymentMode)
                if paymentgatewayresponseDict.get('responseStatus')==1:
                    encrypted_request=paymentgatewayresponseDict.get('encrypted_request')
                    return render_template("frontend/getepaypayment.html",get_base_url=get_base_url,mid=mid,terminalId=terminalId,encrypted_data=encrypted_request)
                else:
                    data_status["result"] = "Invalid payment request."
                    return data_status
        else:
            data_status["result"] = "Invalid transaction Id"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to test payu payment"
        return data_status

@users.route("/checkekycDemo",methods=["GET"])
def checkekycDemo():
    responsedata={"status":0}
    try:
        print("entered")
        url = "https://65.0.63.92/web/sign"
        payload = {
        "orgId": "200374"}
        headers = {
        "accept": "application/json",
        "content-type": "application/json"
        }
        response = requests.post(url, json=payload, headers=headers, verify=False)
        print(response.text,"response.text")
        responsedata=json.loads(response.text)
        return render_template("frontend/ekycDemo.html", responsedata=responsedata)
    except Exception as e:
        app.logger.error(traceback.format_exc())
        return render_template("frontend/ekycDemo.html", responsedata=responsedata)


@users.route("/banners_list",methods=["POST"])
@encrypt_decrypt_after_login
def banners_list():
    data_status = {"responseStatus":0,"result":""}
    bannersList = []
    try:
        ################# For Banners Data ##################
        banners_queryset = AdminBanners.objects(status=1).order_by("sorting").all()
        for each_banner in banners_queryset:
            banner_dict={
            "id":str(each_banner.id),
            "name":each_banner.name,
            "isBanner":each_banner.isBanner,
            "externalLink":each_banner.externalLink,
            "status":each_banner.status,
            "googleScript":each_banner.googleScript
            }
            if each_banner.createdOn:
                banner_dict["createdOn"] = each_banner.createdOn.strftime("%m-%d-%Y")
            else:
                banner_dict["createdOn"] = ""

            if each_banner.image:
                banner_dict["bannerImage"] = domain+each_banner.image
            else:
                banner_dict["bannerImage"] = ""

            try:
                if each_banner.isGrievance:
                    banner_dict["isGrievance"]=each_banner.isGrievance
                else:
                    banner_dict["isGrievance"]=False
            except Exception as e:
                banner_dict["isGrievance"]=False
            
            bannersList.append(banner_dict)

        data_status["responseStatus"]=1
        data_status["result"]="banners data fetched successfully!"
        data_status["bannersList"]=bannersList
        return data_status   
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch banners data!!"
        return data_status

@users.route("/get_available_timings",methods=["POST"])
@encrypt_decrypt_after_login
def get_available_timings():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        userId=data.get('userId')
        transactionType=data.get('transactionType')
        if not userId and not transactionType and transactionType not in ['payout','paymentgateway']:
            data_status["result"]="Service Provider is not available. Please try after sometime."
            return data_status

        user_queryset=Users.objects(id=str(userId),status=1).first()
        if not user_queryset:
            data_status["result"]="Service Provider is not available. Please try after sometime."
            return data_status
        
        startDate = datetime.datetime.now()
        availability_check = check_transaction_availability(startDate, transactionType)
        if availability_check.get('responseStatus')==0:
            data_status["result"]="Service Provider is not available. Please try after sometime."
            return data_status
        else:
            data_status["responseStatus"]=1
            data_status["result"]="Service Provider is available."
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Service Provider is not available. Please try after sometime."
        return data_status

@users.route("/randomusers",methods=["POST"])
def randomusers():
    data_status = {"responseStatus":0,"result":""}
    try:
        random_record_qry = RandomCcCustomers.objects.aggregate([{ "$sample": { "size": 1 } }])  # Get a random record
        random_record=list(random_record_qry)[0]
        print("random_record",random_record)
        # full_file_name = app.config['SITE_ROOT']+"/static/randomNames.json"
        # data=[]
        # with open(full_file_name, "r") as file:
        #     json_string = file.read()
        # data = json.loads(json_string)
        #     # for line in file:
        #     #     data = json.loads(line)
        #     #     print('rowData',data)
        #     #     pass
        # for each_data in data:
        #     save_data=RandomCcCustomers(
        #         customerName=str(each_data.get('fullName')),
        #         customerEmail=str(each_data.get('emailAddress')),
        #         customerPhoneNumber=str(each_data.get('mobileNumber'))
        #         ).save()
        data_status['responseStatus']=1
        data_status['result']=str(random_record.get('customerName'))
        data_status['resultcount']=len(random_record)
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Service Provider is not available. Please try after sometime."
        return data_status

@users.route("/mobile_apk_version",methods=["POST"])
@encrypt_decrypt_after_login
def mobile_apk_version():
    data_status = {"responseStatus":0,"result":""}
    try:
        data_status['responseStatus']=1
        data_status['result']="Success"
        data_status['versionNumber']="8.0.0"
        data_status['link']="https://we.tl/t-2AKHOXCajg"
        return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch mobile version number!!"
        return data_status

@users.route("/merchant_total_payin_payout_balance",methods=["POST"])
# @user_required
@encrypt_decrypt_after_login
def merchant_total_payin_payout_balance():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        startDate = data.get("startDate","")
        endDate = data.get("endDate","")
        userId = data.get("userId","")
        if startDate and endDate and userId:
            startDate = startDate + " 00:00:00"
            endDate = endDate + " 23:59:59"
            try:
                start_date = datetime.datetime.strptime(startDate, "%d-%m-%Y %H:%M:%S")
                end_date = datetime.datetime.strptime(endDate, "%d-%m-%Y %H:%M:%S")
            except Exception as e:
                app.logger.error(traceback.format_exc())
                data_status["result"]="Please give proper dates!!"
                return data_status

            total_user_payin_balances = WalletTransactions.objects(userId=userId,createdOn__gte=start_date,createdOn__lte=end_date,creditType="Credit").sum("amount")
            total_user_payout_balances = FundTransfers.objects(userId=userId,createdOn__gte=start_date,createdOn__lte=end_date,transferType="Debit").sum("amount")

            data_status['responseStatus']=1
            data_status['result']="Users balances fetched successfully!"
            data_status["totalPayinBalance"]=formatINR("{:.2f}".format(float(total_user_payin_balances)))
            data_status["totalPayoutBalance"]=formatINR("{:.2f}".format(float(total_user_payout_balances)))
            return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch balance!!"
        return data_status

@users.route("/update_user_mobile_number",methods=["POST"])
@encrypt_decrypt_after_login
def update_user_mobile_number():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        newMobileNumber = data.get("newMobileNumber","")
        # optCheckId = request.json.get("optCheckId","")
        if userId and newMobileNumber:
            print("userId",userId)
            print("newMobileNumber",newMobileNumber)
            user_queryset = Users.objects(id=ObjectId(userId)).first()
            if not user_queryset:
                data_status["result"]="Invalid User Id!!"
                return data_status
            
            user_queryset_check = Users.objects(phoneNumber__iexact=newMobileNumber).first()
            if user_queryset_check:
                data_status["result"]="Mobile Number already exist!!"
                return data_status
            
            # otpcheck_querryset=OtpChecks.objects(userId=str(userId),id=str(otpCheckId),status=1).first()
            # if not otpcheck_querryset:
            #     data_status["result"]="Invalid Otp Check Id."
            #     return data_status
            # otpcheck_querryset.update(status=2)
            
            user_queryset.update(phoneNumber=newMobileNumber)
           
            data_status["responseStatus"]=1
            data_status["result"]="User Mobile Number Updated Successfully!"
          
            return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to Update Mobile Number!!"
        return data_status


from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
import redis

redis_client = redis.StrictRedis(host='localhost', port=6379, db=0, decode_responses=True)


def get_user_identifier():
    print("get_user_identifier")
    user_id = request.json.get("userId")  # Extract user_id from headers
    user_code = request.json.get("usercode")  # Extract user_code from headers
    print(user_id,"user_id")
    print(user_code,"user_code")
    if user_id and user_code:
        return f"{user_id}:{user_code}"  # Unique identifier (user_id:user_code)
    return get_remote_address()  # Fallback to IP if no user_id or user_code

# Initialize Limiter with custom key function
limiter = Limiter(
    key_func=get_user_identifier,
    app=app,
    storage_uri="redis://localhost:6379/0",
    default_limits=[],  # Example: Allow 1 request per second per user
)

@users.route("/restricted_api", methods=["GET","POST"])
@limiter.limit("1 per minute")  # Restrict to 1 request per second per user
def restricted_api():
    return jsonify({"message": "Success! You can access this API."})

# Custom error handler for rate limit exceeded
@users.errorhandler(429)
def ratelimit_handler(e):
    return jsonify({"error": "Too many requests! Please slow down."}), 429


@users.route("/prepaid_availble_check",methods=["POST"])
@encrypt_decrypt_after_login
def prepaid_availble_check():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        if userId:
            user_queryset = Users.objects(id=userId).first()
            if not user_queryset:
                data_status["result"]="Invalid User Id!!"
                return data_status
            
            prepaid_mobile_setup_queryset = PrepaidMobileSetup.objects(status=1).first()  
            if not prepaid_mobile_setup_queryset:
                data_status["result"]="Service provider not available please contact to admin!!"
                return data_status

            prepaidAvailableResponse={}
            prepaidAvailableResponse={
            "enablePrepaid":prepaid_mobile_setup_queryset.enablePrepaid,
            "prepaidProviderId":str(prepaid_mobile_setup_queryset.prepaidProviderId.id),
            "prepaidPgId":str(prepaid_mobile_setup_queryset.prepaidPgId.id),
            "prepaidProviderName":prepaid_mobile_setup_queryset.prepaidProviderId.apiName,
            "prepaidPgName":prepaid_mobile_setup_queryset.prepaidProviderId.apiName
            }
            data_status["responseStatus"]=1
            data_status["prepaidAvailableResponse"]=prepaidAvailableResponse
            data_status["result"]="Prepaid availablity data fetched successfully!"
            return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch prepaid available data!!"
        return data_status


@users.route("/prepaid_circles_list",methods=["POST"])
@encrypt_decrypt_after_login
def prepaid_circles_list():
    data_status = {"responseStatus":0,"result":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        if userId:
            user_queryset = Users.objects(id=userId).first()
            if not user_queryset:
                data_status["result"]="Invalid User Id!!"
                return data_status
            circlesList = []
            prepaid_circles_queryset = Circles.objects(status=1).order_by("-id")  
            for each_prepaid_circle in prepaid_circles_queryset:
                circleDict = {
                "id":str(each_prepaid_circle.id),
                "name":each_prepaid_circle.name,
                "circleRefId":each_prepaid_circle.circleRefId
                }
                if each_prepaid_circle.paymentGatewayId:
                    circleDict["paymentGatewayId"]=str(each_prepaid_circle.paymentGatewayId.id)
                    circleDict["paymentGatewayName"]=str(each_prepaid_circle.paymentGatewayId.apiName)
                else:
                    circleDict["paymentGatewayId"]=""
                    circleDict["paymentGatewayName"]=""
                circlesList.append(circleDict)

            data_status["responseStatus"]=1
            data_status["circlesList"]=circlesList
            data_status["result"]="Prepaid circles data fetched successfully!"
            return data_status
        else:
            data_status["result"]="Required fields are missing!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch prepaid circles data!!"
        return data_status


# @users.route("/fetch_operator_based_circle_information",methods=["POST"])
# @user_required
# def fetch_operator_based_circle_information():
#     data_status = {"responseStatus":0,"result":""}
#     try:
#         userId = request.json.get("userId","")
#         if userId:
#             user_queryset = Users.objects(id=userId).first()
#             if not user_queryset:
#                 data_status["result"]="Invalid User Id!!"
#                 return data_status
            
#             transaction_api_queryset = TransactionAPI.objects(id=paymentGatewayId,status=1).first()
#             if not transaction_queryset:
#                 data_status["result"]="Invalid paymentgateway id!!"
#                 return data_status

#             if transaction_api_queryset.code == "PAYU-BBPS":
#                 client_id = ""
#                 client_secret = ""
#                 get_base_url = ""
#                 agentId = ""
#                 for each_key in transaction_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 == "get_base_url":
#                         get_base_url = each_key.get("value")
#                     if get_key == "agentId":
#                         agentId = each_key.get("value")



#             data_status["responseStatus"]=1
#             data_status["result"]="Prepaid circles data fetched successfully!"
#             return data_status
#         else:
#             data_status["result"]="Required fields are missing!!"
#             return data_status
#     except Exception as e:
#         app.logger.error(traceback.format_exc())
#         data_status["result"]="Unable to fetch prepaid circles data!!"
#         return data_status

@users.route("/decryptDetails", methods=["GET","POST"])
def decryptDetails():
    data_status={"responseStatus":0,"result":""}
    try:
        paymentDetailsEncrypted=request.json.get('encdata')
        paymentDetails=combined_decrypt(paymentDetailsEncrypted,encSecretKey)
        data_status['result']=paymentDetails
    except Exception as e:
        raise e
    return data_status 

@users.route("/recent_bills_fetching_data",methods=["POST","GET"])
@encrypt_decrypt_after_login
def recent_bills_fetching_data():
    data_status = {"responseStatus": 0, "result": ""}
    data = request.decrypted_data
    userId = data.get("userId","")
    serviceId = data.get("serviceId","")
    userServicesList = []
    if userId and serviceId:
        try:
            user_queryset = Users.objects(id=userId,status=1).first()
            if not user_queryset:
                data_status["result"] = "Invalid user id!!"
                return data_status

            user_services_queryset = UsersSavedServices.objects(userId=userId,serviceId=serviceId)
            for each_user_service in user_services_queryset:
                userServiceDict = {
                "id":str(each_user_service.id),
                "operatorId":str(each_user_service.operatorId.id),
                "operatorName":each_user_service.operatorName,
                "operatorNumber":each_user_service.operatorNumber,
                "fetchResponseList":each_user_service.fetchResponseList,
                "operatorCustomerParametersDict":each_user_service.operatorCustomerParametersDict,
                "image":domain+each_user_service.serviceId.file,
                "date":each_user_service.createdOn.strftime("%d-%m-%Y %H:%M:%S")
                }
                userServicesList.append(userServiceDict)

            data_status["responseStatus"] = 1
            data_status["result"] = "Bill fetched data successfully!"
            data_status["userServicesList"]=userServicesList
            return data_status
        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "Unable to fetch bill data!!"
            return data_status
    else:
        data_status["result"] = "The required field is missing!!"
        return data_status


@users.route("/billfetchrequest", methods=["POST"])
@encrypt_decrypt_after_login
def billfetchrequest():
    data_status = {"responseStatus":0,"result":"","authorizationToken":""}
    try:
        data = request.decrypted_data
        userId = data.get("userId","")
        operatorId = data.get("operatorId","")
        operatorNumber = data.get("operatorNumber","")
        payload = data.get("payload",{})
        serviceId = data.get("serviceId","")
        # authorizationToken = data.get("authorizationToken","")
        # clientCode = data.get("clientCode","")
        authorizationToken = ""
        authtokenresp=getBbpsAuthorizationToken()
        authorizationToken=authtokenresp.get('accessToken')
        print(userId,'=====userId=====')

        if (not userId) or (not payload) or (not operatorId) or (not operatorNumber) or (not authorizationToken) or (not serviceId):
            data_status["result"]="Required fields are missing!!1234"
            return data_status
        # if authorizationToken=="":

        print(authorizationToken,"((((((((authorizationToken))))))))")
        operator_queryset = Operators.objects(id=operatorId,status=1).first()
        if not operator_queryset:
            data_status["result"]="Invalid operator id!!"
            return data_status

        if payload.get('billerId')=="EDU010815MAH01":
            todayDate=datetime.datetime.now()
            formatted_date = todayDate.strftime("%Y-%m-%d")
            print(todayDate,"todayDate")
            payuresponseData={'code': 200, 'status': 'SUCCESS', 'payload': {'refId': payload.get('refId'), 'requestTimeStamp': formatted_date, 'amount': 25000.00, 'accountHolderName': 'Yadati Samuel John', 'dueDate': '2025-04-10', 'billDate': '2025-01-04', 'billerId': 'EDU010815MAH01', 'additionalParams': {}, 'billNumber': 'Term Fee', 'billPeriod': 'NA', 'approvalRefNum': 'AB123456'}}
            data_status["responseStatus"]=1
            data_status["result"]="Bill request data fetched successfully!"
            data_status["payuresponseData"]=payuresponseData
            data_status["authorizationToken"]=authorizationToken
            return data_status

        bbps_prepaid_mobile_setup_queryset = PrepaidMobileSetup.objects(status__in=[0,1],serviceType="BBPS").first()
        if bbps_prepaid_mobile_setup_queryset.enablePrepaid ==True:
            prepaid_api_queryset = TransactionAPI.objects(id=str(bbps_prepaid_mobile_setup_queryset.prepaidProviderId.id),transactionType="Service",status=1).first()
            if not prepaid_api_queryset:
                data_status["result"]="Please enable prepaid provider option!!"
                return data_status
            payin_paymentgateway_queryset = TransactionAPI.objects(id=str(bbps_prepaid_mobile_setup_queryset.prepaidPgId.id),status=1).first()
            if not payin_paymentgateway_queryset:
                data_status["result"]="Please enable payin paymentgateway option!!"
                return data_status

            if prepaid_api_queryset.code == "PayU_BBPS":
                client_id = ""
                client_secret = ""
                get_base_url = ""
                agentId = ""
                for each_key in prepaid_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 == "get_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "agentId":
                        agentId = each_key.get("value")

                print(get_base_url,"(((((((((((get_base_url)))))))))))")
                # url = get_base_url+"/payu-nbc/v1/nbc/billfetchrequest"
                # url = "https://nbc.payu.in/payu-nbc/v1/nbc/billfetchrequest"
                
                # print(payload,"PAYLOAD")
                # headers = {
                # "content-type": "application/json",
                # "authorization": "Bearer "+str(authorizationToken),
                # "clientCode": client_id
                # }
                # print(headers,"headers")
                ##################################################################
                url = "https://graampay.com/api/frontend/billfetchrequest"
                final_payLoad={
                # "userId": "66c43d14b131cbb3c5aba543",
                "userId":userId,
                "payload": payload,
                # "authorizationToken": authorizationToken,
                "clientCode": "35e731ff20e6bc521de9f29618b22c1240a4c69f6350c50e0fcb8e6b7d6c1bec",
                }
                print(final_payLoad,'===final_payLoad====')
                print("userId: " , userId)
                print("clientCode: " , client_id)
                print("payload: ", payload)
                # print("authorizationToken: ", authorizationToken)
                
                if not userId and not payload  and not client_id:
                    data_status["result"]="Required fields are missing!!!"
                    return data_status
                headers = {
                    "content-type": "application/json",
                }
                print(headers,"headers")
                
                payuresponse = requests.post(url, json=final_payLoad, headers=headers)
                print(payuresponse.text,"(((((((((((((payuresponse)))))))))))))")
                payuresponseData = json.loads(payuresponse.text)
    
                print(payuresponseData,"-----------payuresponseData----------")

                # operatorNumber = payload.get('billerId')
                operatorCustomerParametersdict = payload.get("customerParams")
                fetchResponseList = [payuresponseData]
                payloadList = [payload]
               

                operatorName = operator_queryset.operatorName

                checkServiceSaveReponse=save_user_services_data(userId,operatorId,operatorCustomerParametersdict,operatorName,operatorNumber,fetchResponseList,payloadList,serviceId)

                data_status["responseStatus"]=1
                data_status["result"]="Bill request data fetched successfully!"
                data_status["payuresponseData"]=payuresponseData
                data_status["authorizationToken"]=authorizationToken
                data_status["transactionApiId"]=str(bbps_prepaid_mobile_setup_queryset.prepaidPgId.id)
                return data_status
            else:
                data_status["result"]="Service provider not available please contact to admin!!"
                return data_status
        else:
            data_status["result"]="Service provider not available please contact to admin!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"]="Unable to fetch bill request data!!"
        return data_status

@users.route("/bbps_payment_dynamic_link/<transactionTableId>",methods=["GET"])
def bbps_payment_dynamic_link(transactionTableId):
    data_status = {"responseStatus": 0, "result": ""}
    if not transactionTableId:
        data_status["result"] = "Required fields are missing!!"
        return data_status
    
    try:
        transaction_queryset = Transactions.objects(id=transactionTableId,status=3).first()
        if transaction_queryset:
            txnid = transaction_queryset.pgOrderId
            paymentMode = transaction_queryset.paymentType
            productinfo =  transaction_queryset.productName
            amount = transaction_queryset.amount
            email = transaction_queryset.customerEmail
            firstname = transaction_queryset.customerName
            phone = transaction_queryset.customerPhonenumber
            currency = transaction_queryset.currency
            client_ip="125.40.25.126"

            vpa=""
            ccnum=""
            ccname=""
            ccvv=""
            ccexpmon=""
            ccexpyr=""
            bankCode=""
            cardType=""
            if paymentMode=="UPI":
                vpa =  transaction_queryset.customerVpa
            elif paymentMode=="NET BANKING":
                bankCode = transaction_queryset.bankCode
            else:
                paymentDetailsEncrypted = transaction_queryset.paymentDetails
                if paymentDetailsEncrypted!="":
                    paymentDetails=combined_decrypt(paymentDetailsEncrypted,encSecretKey)
                    paymentDetails=json.loads(paymentDetails)
                    ccnum = paymentDetails.get("cardNum")
                    ccname = paymentDetails.get("customerName")
                    ccvv = paymentDetails.get("cardCvv")
                    ccexpmon = paymentDetails.get("cardExpMonth")
                    ccexpyr = paymentDetails.get("cardExpYear")
                    cardType = paymentDetails.get("cardType")

            paymentGatewayId = transaction_queryset.paymentGatewayId
            if paymentGatewayId.code == "Payu_Payin":
                key = ""
                salt = ""
                get_base_url = ""
                surl = ""
                furl = ""
                for each_key in paymentGatewayId.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "api_key":
                        key = each_key.get("value")
                    if get_key == "salt":
                        salt = each_key.get("value")
                    if get_key == "dynamic_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "surl":
                        surl = each_key.get("value")
                    if get_key == "furl":
                        furl = each_key.get("value")
                testresponse = payupayment_dynamic(paymentMode=paymentMode, get_salt=salt,get_base_url=get_base_url, key= key, txnid=txnid, productinfo=productinfo,amount=amount,email=email,firstname=firstname,surl=surl,furl=furl, phone=phone,ccnum=ccnum,ccname=ccname, ccvv=ccvv, ccexpmon=ccexpmon, ccexpyr=ccexpyr, vpa=vpa, bankCode=bankCode, card_type=cardType )
                if testresponse.get('responseStatus')==1:
                    return render_template("frontend/payupaymenttemplate.html",requestDataDict=testresponse.get('result'))
                else:
                    return testresponse

            elif paymentGatewayId.code == "Getepay_Payin":
                mid = ""
                get_base_url = ""
                callback_url = ""
                return_url=""
                encryption_key = ""
                encryption_iv = ""
                terminalId = ""
                encrypted_request = ""
                vpa = ""
                token = ""
                for each_key in paymentGatewayId.paramsList:
                    get_key = each_key.get("key")
                    if get_key == "mid":
                        mid = each_key.get("value")
                    if get_key == "get_base_url":
                        get_base_url = each_key.get("value")
                    if get_key == "callback_url":
                        callback_url = each_key.get("value")
                    if get_key == "return_url":
                        return_url = each_key.get("value")
                    if get_key == "encryption_key":
                        encryption_key = each_key.get("value")
                    if get_key == "encryption_iv":
                        encryption_iv = each_key.get("value")
                    if get_key == "terminalId":
                        terminalId = each_key.get("value")
                    if get_key == "vpa":
                        vpa = each_key.get("value")
                token=wallet_query_set.transactionData[0].get('token')
                paymentgatewayresponseDict = getepaypaymentseamless(encryption_key,encryption_iv, return_url,amount,firstname,phone,currency,txnid,client_ip,token,ccnum,ccexpmon,ccexpyr,ccvv,paymentMode)
                if paymentgatewayresponseDict.get('responseStatus')==1:
                    encrypted_request=paymentgatewayresponseDict.get('encrypted_request')
                    return render_template("frontend/getepaypayment.html",get_base_url=get_base_url,mid=mid,terminalId=terminalId,encrypted_data=encrypted_request)
                else:
                    data_status["result"] = "Invalid payment request."
                    return data_status
        else:
            data_status["result"] = "Invalid transaction id!!"
            return data_status
    except Exception as e:
        app.logger.error(traceback.format_exc())
        data_status["result"] = "unable to test payu payment"
        return data_status

def service_charge_calculation(amount,type,paymentModeId,subPaymentModeId,transactionAPIId,holidaytype=False):
    serviceCharges = {}
    try:
        # transactionAmount = 0
        amountType = ""
        Amount = 0
        chargeAmount = 0
        gstInclude = ""
        tdsInclude = ""
        gstAmount = 0
        tdsAmount = 0
        gstValue = 0
        tdsValue = 0
        serviceChargesID = None
        serviceChargesList=[]

        service_charge_qureyset=ServiceCharges.objects(chargeType=type,status=1).all()

        for each_qurey in service_charge_qureyset:
            # transactionAmount = float(amount)
            serviceChargesName=str(each_qurey.chargeName)
            amountType = each_qurey.amountType
            Amount = float(each_qurey.amount)
            gstInclude = each_qurey.gstInclude
            tdsInclude = each_qurey.tdsInclude
            gstValue = float(each_qurey.gstValue)
            tdsValue = float(each_qurey.tdsValue)

            if amount > 0:
                
                if amountType=="Flat":
                    chargeAmount=Amount

                else:
                    chargeAmount = (float(amount)*float(Amount))/100

                # transactionAmount=float(transactionAmount) + float(chargeAmount)

                if gstValue>0:   
                    gstAmount = (float(chargeAmount)*float(gstValue))/100

                if tdsValue>0:
                    tdsAmount = (float(chargeAmount)*float(tdsValue))/100

                if gstInclude == "Yes":
                    chargeAmount = float(chargeAmount)-float(gstAmount)
                # else:
                #     transactionAmount = float(transactionAmount)+float(gstAmount)

                if tdsInclude == "Yes":
                    chargeAmount = float(chargeAmount)-float(tdsAmount)
                # else:
                #     transactionAmount = float(transactionAmount)+float(tdsAmount)

            serviceCharges = {
            "chargeType" : amountType,
            "chargeValue" :Amount,
            "chargeAmount":round(float(chargeAmount),2),
            "gstInclude":gstInclude,
            "gstAmount":round(float(gstAmount),2),
            "tdsInclude":tdsInclude,
            "tdsAmount":round(float(tdsAmount),2),
            "name":serviceChargesName,
            "gstValue":gstValue,
            "tdsValue":tdsValue,
            }
            serviceChargesList.append(serviceCharges)

        pg_charge_calculation = slab_calculation_for_aggregator(amount,paymentModeId,subPaymentModeId,transactionAPIId,holidaytype=False)

        # total = 0
        pgChargesFormattedDict = {
            "name": "pg charges",
            "chargeType":"Flat" if pg_charge_calculation.get("chargeType") == "FLAT" else "Percentage",
            "chargeValue":pg_charge_calculation.get("chargeValue"),      
            "chargeAmount":pg_charge_calculation.get("chargeAmount"),      
            "gstInclude":pg_charge_calculation.get("gstInclude"),      
            "gstAmount":pg_charge_calculation.get("gstAmount"),      
            "tdsInclude":pg_charge_calculation.get("tdsInclude"),      
            "tdsAmount":pg_charge_calculation.get("tdsAmount"),      
            "gstValue":pg_charge_calculation.get("gstValue"),
            "tdsValue":pg_charge_calculation.get("tdsValue"),
            
        }
        serviceChargesList.append(pgChargesFormattedDict)

        # for each_record in service_charge_qureyset:
        #     total += each_record['amount']
        # data_status["responseStatus"]=1
        # data_status["result"]="calculated successfully"
        # data_status["total"]= total
        # return data_status

    
    except Exception as e:
        app.logger.error(traceback.format_exc())
    return serviceChargesList
    
@users.route("/utility_service_charges_calculation",methods=["GET","POST"])
@encrypt_decrypt_after_login
def utility_service_charges_calculation():
    data_status = {"responseStatus": 0, "result": "" ,"utilityServiceCharges":""}
    data = request.decrypted_data
    amount = data.get("amount",0)
    paymentModeId = data.get("paymentModeId","")
    subPaymentModeId = data.get("subPaymentModeId","")
    transactionAPIId = data.get("transactionAPIId","")
    holidaytype = data.get("holidaytype",False)
    serviceCalculationList = []
    if amount and paymentModeId and subPaymentModeId and transactionAPIId and holidaytype:
        try:
            type="BbpsCharges"

            service_calculation = service_charge_calculation(amount=amount,type=type,paymentModeId=paymentModeId,subPaymentModeId=subPaymentModeId,transactionAPIId=transactionAPIId,holidaytype=holidaytype)
            if service_calculation:
                for item in service_calculation:
                    serviceCalculationList.append(item)
                data_status["responseStatus"] = 1
                data_status["result"] = "calculated successfully"
                data_status["utilityServiceCharges"] = serviceCalculationList
                return data_status
            else:
                data_status["result"] = "Failed to calculate BbpsCharges"
                return data_status

        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "unable to calculate BbpsCharges"
            return data_status
    else:
        data_status["result"] = "The required field is missing!!"
        return data_status


@users.route("/digital_Gold_service_charges_calculation",methods=["GET","POST"])
@encrypt_decrypt_after_login
def digital_Gold_service_charges_calculation():
    data_status = {"responseStatus": 0, "result": "" ,"utilityServiceCharges":""}
    data = request.decrypted_data
    amount = data.get("amount",0)
    paymentModeId = data.get("paymentModeId","")
    subPaymentModeId = data.get("subPaymentModeId","")
    transactionAPIId = data.get("transactionAPIId","")
    holidaytype = data.get("holidaytype",False)
    serviceCalculationList = []
    if amount and paymentModeId and subPaymentModeId and transactionAPIId and holidaytype:
        try:
            type="DigitalGoldCharges"

            service_calculation = service_charge_calculation(amount=amount,type=type,paymentModeId=paymentModeId,subPaymentModeId=subPaymentModeId,transactionAPIId=transactionAPIId,holidaytype=holidaytype)
            if service_calculation:
                for item in service_calculation:
                    serviceCalculationList.append(item)
                data_status["responseStatus"] = 1
                data_status["result"] = "calculated successfully"
                data_status["digitalGoldCharges"] = serviceCalculationList
                return data_status
            else:
                data_status["result"] = "Failed to calculate DigitalGoldCharges"
                return data_status

        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "unable to calculate DigitalGoldCharges"
            return data_status
    else:
        data_status["result"] = "The required field is missing!!"
        return data_status

@users.route("/prepaid_service_charges_calculation",methods=["GET","POST"])
@encrypt_decrypt_after_login
def prepaid_service_charges_calculation():
    data_status = {"responseStatus": 0, "result": "" ,"utilityServiceCharges":""}
    data = request.decrypted_data
    amount = data.get("amount",0)
    paymentModeId = data.get("paymentModeId","")
    subPaymentModeId = data.get("subPaymentModeId","")
    transactionAPIId = data.get("transactionAPIId","")
    holidaytype = data.get("holidaytype",False)
    serviceCalculationList = []
    if amount and paymentModeId and subPaymentModeId and transactionAPIId and holidaytype:
        try:
            type="PrepaidCharges"
            
            service_calculation = service_charge_calculation(amount=amount,type=type,paymentModeId=paymentModeId,subPaymentModeId=subPaymentModeId,transactionAPIId=transactionAPIId,holidaytype=holidaytype)
            if service_calculation:
                for item in service_calculation:
                    serviceCalculationList.append(item)
                data_status["responseStatus"] = 1
                data_status["result"] = "calculated successfully"
                data_status["prepaidCharges"] = serviceCalculationList
                return data_status
            else:
                data_status["result"] = "Failed to calculate PrepaidCharges"
                return data_status

        except Exception as e:
            app.logger.error(traceback.format_exc())
            data_status["result"] = "unable to calculate PrepaidCharges"
            return data_status
    else:
        data_status["result"] = "The required field is missing!!"
        return data_status

@users.route("/delete_user",methods=["GET","POST"])
@encrypt_decrypt_after_login
def delete_user():
    data_status = {"responseStatus": 0, "result": ""}
    data = request.decrypted_data
    userId = data.get("userId")
    reason = data.get("reason")

    if not userId or not reason:
        data_status["result"] = "Required fields are missing!!!"
        return data_status

    user_queryset  = Users.objects(id=userId,status__ne=2).first()
    if not user_queryset:
        data_status["result"] = "Invalid user Id!!!"
    
    user_queryset.update(status=2
                        #  ,reason=reason
                         )

    data_status["responseStatus"] = 1
    data_status["result"] = "User Deleted Successfully!!!"
    return data_status


 
# @users.route("/sendemail",methods=["POST","GET"])
# def sendemails():
#     data_status = {"responseStatus": 0, "result": ""}
#     try:
#         media_dir = os.path.join(app.config['SITE_ROOT'], "media")
#         base_dir = os.path.join(media_dir, "courses")

#         temp_csv_file_name = "/home/ubuntu/graampay/appservices/media/courses/test14.csv"
#         app.logger.error(f"test {temp_csv_file_name}")  
#         request_count = 0
#         with open(temp_csv_file_name, mode='r', encoding='utf-8') as csvfile:
#             csvreader = csv.DictReader(csvfile)
#             for row in csvreader:
               
#                 app.logger.error(f"{row} {type(row)}")
#                 CustomerName = row.get("CustomerName", "").strip()
#                 Email = row.get("Email", "").strip()
#                 TransectionId = row.get("TransectionId", "").strip()
#                 Amount = row.get("Amount", "").strip()
#                 courseName = row.get("courseName", "").strip()
#                 InvoiceDate = row.get("InvoiceDate", "").strip()
#                 TransactionDate = row.get("TransactionDate", "").strip()
#                 if Email and Amount and TransectionId:
#                     InvoiceId = random.randint(100000, 999999)
                    
#                     # Define courseLink before using it
#                     courseLink = "https://courseloft.in/lp-profile"

#                     # Generate mail template data
#                     templates_name = "sendmailtemplates/email_template1.html"


#                     dict_data = {
#                         "CustomerName": CustomerName,
#                         "Email": Email,
#                         "TransectionId": TransectionId,
#                         "InvoiceId": InvoiceId,
#                         "Amount": Amount,
#                         "courseName": courseName,
#                         "courseLink": courseLink,
#                         "InvoiceDate": InvoiceDate,
#                         "TransactionDate": TransactionDate
#                     }

#                     rendered_html = render_template(templates_name, **dict_data)

#                     # Remove tags and do string replacement
#                     content = remove_html_tags(rendered_html)
#                     content = content.replace("$$CustomerName$$", CustomerName)
#                     content = content.replace("$$courseLink$$", courseLink)
#                     content = content.replace("$$Email$$", Email)
#                     content = content.replace("$$TransectionId$$", TransectionId)
#                     content = content.replace("$$InvoiceId$$", str(InvoiceId))
#                     content = content.replace("$$InvoiceDate$$", InvoiceDate)
#                     content = content.replace("$$TransactionDate$$", TransactionDate)
#                     content = content.replace("$$Amount$$", Amount)

#                     content = re.sub(r'\n\s*\n', '\n', content)
#                     content = re.sub(r'[^\x00-\x7F]+', '', content)

#                     # Step 3: Remove problematic characters (e.g., smart quotes)
#                     content = content.replace('“', '"').replace('”', '"').replace('‘', "'").replace('’', "'")
#                     content=content.strip()


#                     pdf = FPDF()
#                     pdf.add_page()
#                     pdf.set_font("Arial", size=12)

#                     #Get page dimensions
#                     pdf_width = pdf.w - 10  # PDF width minus margins
#                     pdf_height = pdf.h - 20  # PDF height minus margins

#                     # Define the width of the text area
#                     text_width = 190  # Adjust as needed (PDF width - margins)

#                     # Add text content
#                     pdf.set_x(10)  # Set starting x position (left margin)
#                     pdf.multi_cell(text_width, 10, txt=content, border=0, align="L") 
#                     # os.makedirs(base_dir, exist_ok=True)

                
#                     pdf.multi_cell(190, 10, txt=content, border=0, align="L")

#                     pdf_file_path = os.path.join(base_dir, f"{TransectionId}.pdf")
#                     print(pdf_file_path, "????????????????????")

#                     # Save the PDF file
#                     pdf.output(pdf_file_path)
#                     print(f"PDF saved at {pdf_file_path}")

#                     savePath = f"media/courses/{TransectionId}.pdf"
#                     print(savePath,"========savePath======")
                    
                

#         app.logger.error(f" MailCount2025")
#         data_status["responseStatus"]=1
#         data_status["result"]="success"
#         return data_status
           
#     except Exception as e:
#         data_status["result"] = "Unable to fecth transaction api data!!"
#         app.logger.error(traceback.format_exc())
#         return data_status
 
# import pdfkit
# WKHTMLTOPDF_PATH = "/usr/local/bin/wkhtmltopdf" # Set to None to let pdfkit try to find it in PATH

# # Initialize pdfkit configuration once at app startup
# pdfkit_config = pdfkit.configuration(wkhtmltopdf='/usr/bin/wkhtmltopdf') if '/usr/bin/wkhtmltopdf' else None


# # Helper function to ensure static images exist (creates dummy if not)
# def ensure_static_images_exist(static_dir):
#     os.makedirs(static_dir, exist_ok=True)
#     for img_name in ['logo.png', 'facebook.png', 'twitter.png', 'instagram.png']:
#         img_path = os.path.join(static_dir, img_name)
#         if not os.path.exists(img_path):
#             try:
#                 app.logger.info(f"Creating dummy image: {img_path}")
#                 if img_name == 'logo.png':
#                     img = Image.new('RGB', (150, 40), color='salmon') # Larger for logo
#                 else:
#                     img = Image.new('RGB', (24, 24), color='lightblue') # Smaller for social icons
#                 img.save(img_path)
#             except Exception as e:
#                 app.logger.warning(f"Failed to create dummy image '{img_name}': {e}. "
#                                    "Please ensure Pillow is installed (`pip install Pillow`) "
#                                    "or place your own images in the 'static' folder.")

# @users.route("/sendemail", methods=["POST", "GET"])
# def sendemails():

#     data_status = {"responseStatus": 0, "result": ""}
    
#     # Define paths
#     media_dir = os.path.join(app.config['SITE_ROOT'], "media")
#     base_pdf_output_dir = os.path.join(media_dir, "courses") # This will be where PDFs saved
    
#     # The static directory path relative to your app.py for image access
#     static_content_dir = "/graampay/appservices/templates/sendmailtemplates/"
    
#     # Ensure necessary directories exist
#     # os.makedirs(f'sendmailtemplates/{base_pdf_output_dir}', exist_ok=True)
#     # ensure_static_images_exist(static_content_dir)

#     # `wkhtmltopdf` needs an absolute file URL for local images.
#     # The `replace(os.sep, '/')` handles path separators for different OS.
#     # The `file:///` prefix makes it an absolute file URL read by wkhtmltopdf.
#     domain_url_for_pdf = f"file:///{static_content_dir.replace(os.sep, '/')}/"


#     try:
#         # NOTE: Your CSV path seems hardcoded `/home/ubuntu/graampay/appservices/media/courses/test14.csv`
#         # This will only work on that specific server path.
#         # It's better to make it relative to app.config['SITE_ROOT'] or configurable.
#         # For this example, I'll keep your hardcoded path, but be aware of it.
#         temp_csv_file_name = "/home/ubuntu/graampay/appservices/media/courses/test14.csv"
#         app.logger.info(f"Processing CSV file: {temp_csv_file_name}")

#         request_count = 0 
#         with open(temp_csv_file_name, mode='r', encoding='utf-8') as csvfile:
#             csvreader = csv.DictReader(csvfile)
#             for row in csvreader:
#                 app.logger.debug(f"Processing row: {row}") # Changed to debug, can be noisy
                
#                 CustomerName = row.get("CustomerName", "").strip()
#                 Email = row.get("Email", "").strip()
#                 TransectionId = row.get("TransectionId", "").strip()
#                 Amount = row.get("Amount", "").strip()
#                 courseName = row.get("courseName", "Unknown Course").strip() # Default if empty
#                 InvoiceDate = row.get("InvoiceDate", datetime.date.today().strftime("%B %d, %Y")).strip()
#                 TransactionDate = row.get("TransactionDate", datetime.date.today().strftime("%B %d, %Y")).strip()
                
#                 # Check for essential data
#                 if not (Email and Amount and TransectionId):
#                     app.logger.warning(f"Skipping row due to missing essential data: {row}")
#                     continue

#                 InvoiceId = random.randint(100000, 999999) # Using random for InvoiceId

#                 courseLink = "https://courseloft.in/lp-profile" # Static course link

#                 # Data dictionary for rendering the Jinja2 template
#                 dict_data = {
#                     "CustomerName": CustomerName,
#                     "Email": Email,
#                     "TransectionId": TransectionId,
#                     "InvoiceId": str(InvoiceId), # Ensure it's a string for template
#                     "Amount": Amount,
#                     "courseName": courseName,
#                     "courseLink": courseLink,
#                     "InvoiceDate": InvoiceDate,
#                     "TransactionDate": TransactionDate,
#                     "domainUrl": domain_url_for_pdf # Pass the absolute path for images
#                 }

#                 templates_name = "sendmailtemplates/email_template1.html"

#                 # Render the HTML template using Flask's render_template
#                 rendered_html = render_template(templates_name, **dict_data)
                
#                 # --- PDF Generation using pdfkit ---
#                 # Options for pdfkit (these are good defaults)
#                 pdf_options = {
#                     'page-size': 'A4',
#                     'margin-top': '10mm',
#                     'margin-right': '10mm',
#                     'margin-bottom': '10mm',
#                     'margin-left': '10mm',
#                     'encoding': "UTF-8",
#                     'enable-local-file-access': None, # Critical: allows wkhtmltopdf to access local files (like images)
#                 }

#                 pdf_file_path = os.path.join(base_pdf_output_dir, f"{TransectionId}.pdf")
                
#                 app.logger.info(f"Generating PDF for {Email} at {pdf_file_path}")
#                 try:
#                     pdfkit.from_string(rendered_html, pdf_file_path, configuration=pdfkit_config, options=pdf_options)
#                     app.logger.info(f"PDF successfully saved at {pdf_file_path}")
#                     request_count += 1
#                 except Exception as pdf_e:
#                     app.logger.error(f"Failed to generate PDF for {Email} (Transaction ID: {TransectionId}): {pdf_e}")
#                     # You might want to log the HTML content here for debugging if PDF generation frequently fails.
#                     # app.logger.error(f"HTML content that failed: {rendered_html[:500]}...")


#         app.logger.info(f"Finished processing CSV. Generated {request_count} PDFs.")
#         data_status["responseStatus"] = 1
#         data_status["result"] = f"Successfully generated {request_count} PDFs."
#         return jsonify(data_status) # Return JSON response for Flask routes
            
#     except FileNotFoundError:
#         data_status["result"] = f"CSV file not found at {temp_csv_file_name}"
#         app.logger.error(traceback.format_exc())
#         return jsonify(data_status)
#     except Exception as e:
#         data_status["result"] = "An unexpected error occurred during PDF generation."
#         app.logger.error(traceback.format_exc())
#         return jsonify(data_status)
import pdfkit
WKHTMLTOPDF_PATH = "/usr/local/bin/wkhtmltopdf" # Set to None to let pdfkit try to find it in PATH

# Initialize pdfkit configuration once at app startup
pdfkit_config = pdfkit.configuration(wkhtmltopdf='/usr/bin/wkhtmltopdf') if '/usr/bin/wkhtmltopdf' else None

# Helper function to ensure static images exist (creates dummy if not)
def ensure_static_images_exist(static_dir):
    os.makedirs(static_dir, exist_ok=True)
    for img_name in ['logo.png', 'facebook.png', 'twitter.png', 'instagram.png']:
        img_path = os.path.join(static_dir, img_name)
        if not os.path.exists(img_path):
            try:
                app.logger.info(f"Creating dummy image: {img_path}")
                if img_name == 'logo.png':
                    img = Image.new('RGB', (150, 40), color='salmon') # Larger for logo
                else:
                    img = Image.new('RGB', (24, 24), color='lightblue') # Smaller for social icons
                img.save(img_path)
            except Exception as e:
                app.logger.warning(f"Failed to create dummy image '{img_name}': {e}. "
                                   "Please ensure Pillow is installed (`pip install Pillow`) "
                                   "or place your own images in the '{static_dir}' folder.")

@users.route("/sendemail", methods=["POST", "GET"])
def sendemails():
    data_status = {"responseStatus": 0, "result": ""}

    # Define paths
    media_dir = os.path.join(app.config['SITE_ROOT'], "media")
    base_pdf_output_dir = os.path.join(media_dir, "courses") # Where PDFs will be saved

    # --- CRITICAL CORRECTION HERE ---
    # `static_content_dir` should point to your application's global 'static' folder.
    # Assuming 'static' is at the same level as 'app.py' and 'templates'.
    static_content_dir = os.path.join(app.config['SITE_ROOT'], "static")

    # Ensure necessary directories exist
    os.makedirs(base_pdf_output_dir, exist_ok=True)
    
    # --- UNCOMMENT AND USE THIS ---
    # Ensure static images exist (creates dummy if they don't, requires Pillow)
    ensure_static_images_exist(static_content_dir)

    # `wkhtmltopdf` needs an absolute file URL for local images.
    # The `replace(os.sep, '/')` handles path separators for different OS.
    # The `file:///` prefix makes it an absolute file URL read by wkhtmltopdf.
    domain_url_for_pdf = f"file:///{static_content_dir.replace(os.sep, '/')}/"

    try:
        # Your CSV path seems hardcoded, which works but might be fragile.
        # Consider making it relative to app.config['SITE_ROOT'] for better portability.
        temp_csv_file_name = "/home/ubuntu/graampay/appservices/media/courses/test14.csv"
        app.logger.info(f"Processing CSV file: {temp_csv_file_name}")

        request_count = 0 
        with open(temp_csv_file_name, mode='r', encoding='utf-8') as csvfile:
            csvreader = csv.DictReader(csvfile)
            for row in csvreader:
                app.logger.debug(f"Processing row: {row}") 
                
                CustomerName = row.get("CustomerName", "").strip()
                Email = row.get("Email", "").strip()
                TransectionId = row.get("TransectionId", "").strip()
                Amount = row.get("Amount", "").strip()
                # Corrected 'Item' in invoice table to use 'courseName'
                courseName = row.get("courseName", "Online Course: Generic").strip() # Default if empty
                # Using datetime.date.today() as fallback for missing dates
                InvoiceDate = row.get("InvoiceDate", datetime.date.today().strftime("%B %d, %Y")).strip()
                TransactionDate = row.get("TransactionDate", datetime.date.today().strftime("%B %d, %Y")).strip()
                
                # Check for essential data
                if not (Email and Amount and TransectionId):
                    app.logger.warning(f"Skipping row due to missing essential data: {row}")
                    continue

                InvoiceId = random.randint(100000, 999999)

                courseLink = "https://courseloft.in/lp-profile"

                dict_data = {
                    "CustomerName": CustomerName,
                    "Email": Email,
                    "TransectionId": TransectionId,
                    "InvoiceId": str(InvoiceId),
                    "Amount": Amount,
                    "courseName": courseName, # Used as 'Item' in invoice
                    "courseLink": courseLink,
                    "InvoiceDate": InvoiceDate,
                    "TransactionDate": TransactionDate,
                    "domainUrl": domain_url_for_pdf # THIS IS KEY FOR LOCAL IMAGE PATHS
                }

                templates_name = "sendmailtemplates/email_template1.html"

                rendered_html = render_template(templates_name, **dict_data)
                
                # --- PDF Generation using pdfkit ---
                pdf_options = {
                    'page-size': 'A4',
                    'margin-top': '10mm',
                    'margin-right': '10mm',
                    'margin-bottom': '10mm',
                    'margin-left': '10mm',
                    'encoding': "UTF-8",
                    'enable-local-file-access': None, # Enables loading local files (like images)
                }

                pdf_file_path = os.path.join(base_pdf_output_dir, f"{TransectionId}.pdf")
                
                app.logger.info(f"Generating PDF for {Email} (Tran ID: {TransectionId}) at {pdf_file_path}")
                try:
                    pdfkit.from_string(rendered_html, pdf_file_path, configuration=pdfkit_config, options=pdf_options)
                    app.logger.info(f"PDF successfully saved at {pdf_file_path}")
                    request_count += 1
                except Exception as pdf_e:
                    app.logger.error(f"Failed to generate PDF for {Email} (Transaction ID: {TransectionId}): {pdf_e}")
                    # Log the HTML content if debugging problematic rows:
                    # app.logger.error(f"HTML content that failed: {rendered_html[:500]}...")


        app.logger.info(f"Finished processing CSV. Generated {request_count} PDFs.")
        data_status["responseStatus"] = 1
        data_status["result"] = f"Successfully generated {request_count} PDFs."
        return jsonify(data_status)
            
    except FileNotFoundError:
        data_status["result"] = f"CSV file not found at {temp_csv_file_name}. " \
                                "Please ensure the path is correct and file exists."
        app.logger.error(traceback.format_exc())
        return jsonify(data_status)
    except Exception as e:
        data_status["result"] = "An unexpected error occurred during PDF generation."
        app.logger.error(traceback.format_exc())
        return jsonify(data_status)

# Path for saving uploaded PDFs
UPLOAD_FOLDER = os.path.join(app.config['SITE_ROOT'], 'media')
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# Ensure the 'uploads' directory exists
if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)

class MyHTMLParser(HTMLParser):
    def __init__(self, pdf):
        super().__init__()
        self.pdf = pdf
        self.first_page = True  # Flag to check if a page is already added

    def handle_starttag(self, tag, attrs):
        if self.first_page:
            self.pdf.add_page()  # Add a new page if it's the first one
            self.first_page = False
            self.pdf.set_font("NotoSans", size=12)  # Set a Unicode-compatible font

    def handle_endtag(self, tag):
        pass

    def handle_data(self, data):
        # Ensure a page is open before adding content
        if self.first_page:
            self.pdf.add_page()
            self.first_page = False
        
        # Ensure font is set before adding content
        self.pdf.set_font("NotoSans", size=12)  # Set font before adding text content

        # Adjust the width of multi_cell dynamically based on the page width
        page_width = self.pdf.w - 2 * self.pdf.l_margin  # Page width minus left and right margin
        print(data,"before_data")
        data = ''.join([char if ord(char) < 128 else ' ' for char in data])
        print(data,"after_data")
        self.pdf.multi_cell(page_width, 10, data)

# Function to convert HTML content to PDF
def html_to_pdf(html_content, output_filename):
    pdf = FPDF()
    pdf.set_auto_page_break(auto=True, margin=15)
    FONT_PATH = os.path.join(app.config['SITE_ROOT'], 'static','Noto_Sans','static', 'NotoSans-Regular.ttf')
    print(FONT_PATH,"FONT_PATH")
    if not os.path.exists(FONT_PATH):
        raise FileNotFoundError(f"Font file not found: {FONT_PATH}")

    pdf.add_font('NotoSans', '', FONT_PATH, uni=True) # Initialize HTML parser with the FPDF object
    parser = MyHTMLParser(pdf)

    # Feed HTML content into the parser
    parser.feed(html_content)

    # Save the PDF to the uploads folder
    output_path = os.path.join(app.config['UPLOAD_FOLDER'], output_filename)
    pdf.output(output_path)
    return output_path

@users.route('/htmltopdfconvert',methods=['POST','GET'])
def htmltopdfconvert():
    title = "Welcome to Flask"
    content = "This is an example of reading and rendering HTML from the templates folder."

    # Render the template with the data
    html_content = render_template('sendmailtemplates/email_template1.html', title=title, content=content)
    print(html_content,"html_content")
    # Convert the HTML content to PDF and save it in the uploads folder
    pdf_filename = 'output.pdf'
    pdf_path = html_to_pdf(html_content, pdf_filename)

    # Return the generated PDF file as a response
    return send_from_directory(directory=UPLOAD_FOLDER, path=pdf_filename, as_attachment=True)




@users.route('/renderemailtemplate',methods=['POST','GET'])
def renderemailtemplate():
    filepath=request.args.get('fileName')
    print(filepath,"filepath")
    # temp_csv_file_name = "/home/ubuntu/graampay/appservices/media/courses/test14.csv"
    temp_csv_file_name = os.path.join(app.config['SITE_ROOT'], 'media','courses',filepath)
    data_status={"responseStatus":0,"result":""}
    app.logger.info(f"Processing CSV file: {temp_csv_file_name}")
    request_count = 0 
    # return data_status
    with open(temp_csv_file_name, mode='r', encoding='utf-8') as csvfile:
        csvreader = csv.DictReader(csvfile)
        for row in csvreader:
            print(f"Processing row: {row}") 
            
            CustomerName = row.get("CustomerName", "").strip()
            Email = row.get("Email", "").strip()
            TransectionId = row.get("TransectionId", "").strip()
            Amount = row.get("Amount", "").strip()
            # Corrected 'Item' in invoice table to use 'courseName'
            courseName = row.get("courseName", "Online Course: Generic").strip() # Default if empty
            # Using datetime.date.today() as fallback for missing dates
            InvoiceDate = row.get("InvoiceDate", datetime.date.today().strftime("%B %d, %Y")).strip()
            TransactionDate = row.get("TransactionDate", datetime.date.today().strftime("%B %d, %Y")).strip()

        print(csvreader,"csvreader")
        return data_status
    templates_name = "sendmailtemplates/email_template1.html"
    rendered_html = render_template(templates_name,domainUrl=domain)
    return rendered_html



@users.route("/sendemailsid",methods=["POST","GET"])
def sendemailsid():
    data_status = {"responseStatus": 0, "result": ""}
    try:
        
        temp_csv_file_name = "/home/ubuntu/graampay/appservices/media/courses/test1.csv"
        app.logger.error(f"test {temp_csv_file_name}")  
        request_count = 0
        with open(temp_csv_file_name, mode='r', encoding='utf-8') as csvfile:
            csvreader = csv.DictReader(csvfile)
            for row in csvreader:
                app.logger.error(f"{row} {type(row)}")
                CustomerName = row.get("CustomerName", "").strip()
                Email = row.get("Email", "").strip() 
                TransectionId = row.get("TransectionId", "").strip() 
                Amount = row.get("Amount", "").strip() 
                courseName = row.get("courseName", "").strip() 
                InvoiceDate = row.get("InvoiceDate", "").strip() 
                TransactionDate = row.get("TransactionDate", "").strip() 
                if Email and Amount and TransectionId:
                    InvoiceId = random.randint(100000,999999)
                    app.logger.error(f" ======= {CustomerName}=={Email}=={TransectionId}")
                    recipients_list=[Email]
                    cc_list=["hello@courseloft.in"]
                    subject="Your Courseloft Access Is Ready – Let’s Get Started!"
                    templates_name="sendmailtemplates/email_template1.html"
                    mail_data={
                        "CustomerName":CustomerName,
                        "Email":Email,
                        "TransectionId":TransectionId,
                        "InvoiceId":InvoiceId,
                        "Amount":Amount,
                        "courseName":courseName,
                        "courseLink":"https://courseloft.in/lp-profile",
                        "InvoiceDate":InvoiceDate,
                        "TransactionDate":TransactionDate
                        
                    }
                    checkMailStatus=send_asynchronous_email(subject, recipients_list, templates_name,mail_data,cc_list)
                    time.sleep(0.3)
                    request_count += 1 
        app.logger.error(f" MailCount2025 {request_count}")
        data_status["responseStatus"]=1
        data_status["result"]="Mail Sended SuccessFully"
        return data_status
            
    except Exception as e:
        data_status["result"] = "Unable to fecth transaction api data!!"
        app.logger.error(traceback.format_exc())
        return data_status



