Untitled
raw download clone
TEXT
views 4
,
size 26624 b
from copy import error
from django.http.response import HttpResponse
from django.shortcuts import render
from rest_framework import views

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import IsAuthenticated, IsAdminUser  # <-- Here
from rest_framework.authtoken.models import Token

from .DataFunctions.VendingMedium import vending_medium

from .DataFunctions.ValidateDataField import data_validate
from .models import *
from .serializers import *
import json, requests
from requests.auth import HTTPBasicAuth
from django.contrib.auth import authenticate
from django.contrib.auth.hashers import check_password
from django.db.models import Q


from django.template.loader import get_template
from .utils import render_to_pdf

# pdf
def generatePdf(request, id):

    pdf = render_to_pdf("receipt.html", id)
    return HttpResponse(pdf, content_type="application/pdf")


def index(request):
    return HttpResponse("<h1>Server is ready </h1>")


########## USER LOGIN API START HERE ##########
class UserLogin(APIView):
    def post(self, request):
        username = request.data.get("username")
        password = request.data.get("password")

        if not username:
            return Response({"message": "Please enter valid username"}, status=400)

        elif not password:
            return Response({"message": "Please enter your password"}, status=400)

        try:
            user = CustomUser.objects.get(username__iexact=username)
            pwd_valid = check_password(password, user.password)
            if pwd_valid:
                user_serializer = CustomUserSerializer(user).data
                return Response(user_serializer)
            else:
                return Response(
                    {"message": "Unable to log in with provided credentials."},
                    status=400,
                )

        except CustomUser.DoesNotExist:
            return Response(
                {"message": "Unable to log in with provided credentials."}, status=400
            )


########## USER LOGIN API ENDS HERE ##########


########## REGISTRATION API START HERE ##########
class CustomerRegistration(APIView):
    def post(self, request, format="json"):

        serializer = CustomUserSerializer(data=request.data)
        errors = {}
        if CustomUser.objects.filter(
            username__iexact=request.data.get("username")
        ).exists():
            errors["error"] = "This username has been taken"
            raise (errors)

        elif CustomUser.objects.filter(
            email__iexact=request.data.get("email")
        ).exists():
            errors["error"] = "This email has been taken"
            raise (errors)

        elif CustomUser.objects.filter(
            phone__iexact=request.data.get("phone")
        ).exists():
            errors["error"] = "This phone number has been taken"
            raise (errors)

        if serializer.is_valid():
            user = serializer.save()
            if user:
                token = Token.objects.create(user=user)
                json = serializer.data
                json["token"] = token.key
                return Response(json, status=201)

        return Response(serializer.errors, status=400)


########## REGISTRATION API ENDS HERE ##########


########## CUSTOMER DETAILS API START HERE ##########
class CustomerDetails(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):

        try:
            user_serializer = CustomUserSerializer(request.user)
            return Response(
                user_serializer.data,
            )

        except CustomUser.DoesNotExist:
            return Response(status=404)

    def put(self, request, format=None):

        user = request.user
        serializer = CustomUserSerializer(
            user, data=request.data, context={"request": request}, partial=True
        )
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)

        return Response(serializer.errors, status=400)

    def post(self, request, format=None):

        user = request.user
        file_obj = request.FILES["image"]

        if file_obj:
            user.passport_photogragh = file_obj
            user.save()
            user = request.user
            serializer = CustomUserSerializer(user)
            return Response(serializer.data)

        return Response(
            {"message": "something went wrong ,profile update not successful"},
            status=400,
        )


class KycAPI(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):

        try:
            kyc = KYC.objects.get(user=request.user)
            kyc_serializer = KycSerializer(kyc)
            return Response(
                kyc_serializer.data,
            )

        except KYC.DoesNotExist:
            return Response(status=404)

    def post(self, request, format=None):
        user = request.user
        kycdata = request.GET.get("kycdata")

        if kycdata == "IDCARD":
            file_obj = request.FILES["idcard"]
            if file_obj:

                if KYC.objects.filter(user=request.user):
                    kyc = KYC.objects.get(user=request.user)
                    kyc.identity_card = file_obj
                    kyc.idcardstatus = "pending"
                    kyc.idcardmessage = "Id Card verification in progress"
                    kyc.save()
                    kyc_serializer = KycSerializer(kyc)
                else:
                    kyc = KYC()
                    kyc.user = request.user
                    kyc.identity_card = file_obj
                    kyc.idcardstatus = "pending"
                    kyc.idcardmessage = "Id Card verification in progress"
                    kyc.save()
                    kyc_serializer = KycSerializer(kyc)
            else:

                return Response(
                    {"message": "ID CARD is required"},
                    status=400,
                )

        elif kycdata == "UTILITY":
            file_obj = request.FILES["utility"]
            if file_obj:

                if KYC.objects.filter(user=request.user):
                    kyc = KYC.objects.get(user=request.user)
                    kyc.utility_bill = file_obj
                    kyc.utilitystatus = "pending"
                    kyc.utilitymessage = "Utility Bill verification in progress"
                    kyc.save()
                    kyc_serializer = KycSerializer(kyc)
                else:
                    kyc = KYC()
                    kyc.user = request.user
                    kyc.utility_bill = file_obj
                    kyc.utilitystatus = "pending"
                    kyc.utilitymessage = "Utility Bill verification in progress"
                    kyc.save()
                    kyc_serializer = KycSerializer(kyc)
            else:

                return Response(
                    {"message": "ID CARD is required"},
                    status=400,
                )

        elif kycdata == "ACCOUNT":
            bank_name = request.data.get("bank_name")
            bank_code = request.data.get("bank_code")
            bvn = request.data.get("bvn")
            account = request.data.get("account")
            name = ""

            if not bank_name:
                return Response(
                    {"message": "Bank name is required"},
                    status=400,
                )

            if not bank_code:
                return Response(
                    {"message": "Bank Code is required"},
                    status=400,
                )

            elif not bvn:
                return Response(
                    {"message": "Account bvn is required"},
                    status=400,
                )

            elif KYC.objects.filter(bvn=bvn).exists():
                return Response(
                    {"message": "BVN has been used by another customer"},
                    status=400,
                )

            elif not account:
                return Response(
                    {"message": "Account account number is required"},
                    status=400,
                )

            try:
                auth = requests.post(
                    "https://api.monnify.com/api/v1/auth/login",
                    auth=HTTPBasicAuth(
                        f"MK_PROD_49RAC87A32", f"GSFBU2HGLKNS9Q64STVBF5K3Y2D27CNY"
                    ),
                )
                authdata = json.loads(auth.text)
                headers = {
                    "Content-Type": "application/json",
                    "Authorization": "Bearer {}".format(
                        authdata["responseBody"]["accessToken"]
                    ),
                }
                payload = {
                    "bankCode": bank_code,
                    "accountNumber": account,
                    "bvn": bvn,
                }

                response = requests.post(
                    "https://api.monnify.com/api/v1/vas/bvn-account-match",
                    headers=headers,
                    data=json.dumps(payload),
                )

                resp = json.loads(response.text)

                if "requestSuccessful" in resp and resp["requestSuccessful"] == True:
                    if (
                        request.user.firstname.lower()
                        in resp["responseBody"]["accountName"].lower()
                        and request.user.lastname.lower()
                        in resp["responseBody"]["accountName"].lower()
                    ):
                        if KYC.objects.filter(user=request.user):
                            kyc = KYC.objects.get(user=request.user)
                            kyc.customer_name = resp["responseBody"]["accountName"]
                            kyc.bank_name = bank_name
                            kyc.bank_code = bank_code
                            kyc.bvn = bvn
                            kyc.account = account
                            kyc.save()
                            kyc_serializer = KycSerializer(kyc)

                        else:
                            kyc = KYC()
                            kyc.user = request.user
                            kyc.customer_name = resp["responseBody"]["accountName"]
                            kyc.bank_name = bank_name
                            kyc.bank_code = bank_code
                            kyc.bvn = bvn
                            kyc.account = account
                            kyc.save()
                            kyc_serializer = KycSerializer(kyc)
                    else:
                        return Response(
                            {
                                "message": "your bank Account name doest not correspond with your  register firstname and lastname"
                            },
                            status=400,
                        )
                else:
                    return Response(
                        {"message": resp["responseMessage"]},
                        status=400,
                    )
            except:
                return Response(
                    {
                        "message": "something went wrong ,our system could not connect to service provider"
                    },
                    status=400,
                )

        return Response(
            kyc_serializer.data,
        )


class PasswordChnage(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):

        oldpassword = request.data.get("oldpassword", None)
        newpassword = request.data.get("newpassword", None)
        user = request.user
        if not oldpassword:
            return Response(
                {"message": "Please enter your current password"},
                status=400,
            )
        elif not newpassword:
            return Response(
                {"message": "Please enter your new password"},
                status=400,
            )

        elif not (
            re.search(
                "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[?!~|'@#$%^&+=])(?=.{8,})",
                newpassword,
            )
        ):
            return Response(
                {
                    "message": "Enter a valid Password Must contain at least one  number and one uppercase and lowercase letter,one special character and at least 8 or more characters, i.e Test2001?"
                },
                status=400,
            )

        pwd_valid = check_password(oldpassword, user.password)
        if pwd_valid:
            user.set_password(newpassword)
            user.save()
            user_serializer = CustomUserSerializer(user).data
            return Response(user_serializer)
        else:
            return Response(
                {"message": "current password is not correct"},
                status=400,
            )


class VerifyPhone(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):

        phone_verify = request.data.get("phone_verify", None)

        user = request.user
        if not phone_verify:
            return Response(
                {"message": "All fields required"},
                status=400,
            )

        user.phone_verify = phone_verify
        user.save()
        user_serializer = CustomUserSerializer(user).data
        return Response(user_serializer)


class UpdateNotificationOption(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):

        allow_two_factor_auth = request.data.get("allow_two_factor_auth", None)
        allow_email_notification = request.data.get("allow_email_notification", None)
        allow_sms_notification = request.data.get("allow_sms_notification", None)
        user = request.user

        print(allow_sms_notification)
        if allow_two_factor_auth == True or allow_two_factor_auth == False:
            user.allow_two_factor_auth = allow_two_factor_auth
            user.save()

        elif allow_email_notification == True or allow_email_notification == False:
            user.allow_email_notification = allow_email_notification
            user.save()

        elif allow_sms_notification == True or allow_sms_notification == False:

            user.allow_sms_notification = allow_sms_notification
            user.save()
            print(user.allow_sms_notification)

        user_serializer = CustomUserSerializer(user).data
        return Response(user_serializer)


class BankList(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):

        auth = requests.post(
            "https://api.monnify.com/api/v1/auth/login",
            auth=HTTPBasicAuth(
                f"MK_PROD_49RAC87A32", f"GSFBU2HGLKNS9Q64STVBF5K3Y2D27CNY"
            ),
        )
        authdata = json.loads(auth.text)
        headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer {}".format(
                authdata["responseBody"]["accessToken"]
            ),
        }
        data = requests.get(
            "https://sandbox.monnify.com/api/v1/banks",
            headers=headers,
        )

        print(data.text)

        return Response(json.loads(data.text))


########## CUSTOMER DETAILS API ENDS HERE ##########


########## Transactions API START HERE ##########


class TransactionDetailsAPI(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, id, format=None):
        try:
            item = Transaction.objects.filter(user=request.user).get(reference=id)
            serializer = TransactionSerializer(item)
            return Response(serializer.data)
        except Transaction.DoesNotExist:
            return Response({"message": "Transaction does not exist"}, status=404)


class TransactionsAPI(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        search = request.GET.get("query", None)
        filter = request.GET.get("filter", None)
        paginator = PageNumberPagination()
        if search:
            items = (
                Transaction.objects.filter(user=request.user)
                .filter(
                    Q(reference__icontains=search) | Q(description__icontains=search)
                )
                .order_by("-created_date")
            )
            result_page = paginator.paginate_queryset(items, request)
            serializer = TransactionSerializer(result_page, many=True)
            return paginator.get_paginated_response(serializer.data)

        elif filter:
            filterdata = json.loads(filter)
            print(filterdata)

            start_date = filterdata["start_date"]
            end_date = filterdata["end_date"]
            status = filterdata["status"]
            transaction_type = filterdata["transaction_type"]
            service_type = filterdata["service_type"]
            items = Transaction.objects.filter(user=request.user).order_by(
                "-created_date"
            )

            if start_date and end_date:
                items = items.filter(created_date__range=[start_date, end_date])

            if status:
                items = items.filter(status__icontains=status)

            if transaction_type:
                items = items.filter(transaction_type__icontains=transaction_type)

            if service_type:
                items = items.filter(service_type__service_name__icontains=service_type)

            result_page = paginator.paginate_queryset(items, request)
            serializer = TransactionSerializer(result_page, many=True)
            return paginator.get_paginated_response(serializer.data)

        else:

            items = Transaction.objects.filter(user=request.user).order_by(
                "-created_date"
            )

            result_page = paginator.paginate_queryset(items, request)
            serializer = TransactionSerializer(result_page, many=True)
            return paginator.get_paginated_response(serializer.data)

    def post(self, request, format="json"):

        service_type = request.data.get("service", None)
        pin = request.data.get("pin", None)

        if not pin:
            return Response(
                {
                    "error": True,
                    "message": "Transaction pin required",
                },
                status=400,
            )
        if int(pin) != request.user.transaction_pin:
            return Response(
                {
                    "error": True,
                    "message": "Incorrect Pin Entered",
                },
                status=400,
            )

        if service_type == "DATA":
            network = request.data.get("network")
            plan = request.data.get("plan")
            phone = request.data.get("phone")
            user = request.user
            portednumber = request.data.get("portednumber")
            customer_reference = request.data.get("customer_reference", None)

            validate = data_validate(request.user, network, plan, phone, portednumber)

            if validate["error"] != True:
                validatedphone = validate.pop("phone", None)
                validatedamount = validate.pop("amount", None)
                network_obj = Network.objects.get(name=network)
                plan_obj = Plan.objects.get(id=plan)
                service = Services.objects.get(service_name="DATA")

                if network == "MTN":
                    if plan_obj.plan_type.name == "SME":
                        response = vending_medium(network_obj.sme_vending_medium)

                    elif plan_obj.plan_type.name == "GIFTING":
                        response = vending_medium(network_obj.gifting_vending_medium)

                    elif plan_obj.plan_type.name == "CORPORATE GIFTING":
                        response = vending_medium(network_obj.cdg_vending_medium)

                elif network == "GLO":
                    response = vending_medium(network_obj.data_vending_medium)

                elif network == "AIRTEL":
                    response = vending_medium(network_obj.data_vending_medium)

                elif network == "9MOBILE":
                    response = vending_medium(network_obj.data_vending_medium)

                try:
                    previous_balance = user.wallet_balance
                    charge_user_wallet = user.withdraw(user.id, validatedamount)
                    if charge_user_wallet == False:
                        return Response(
                            {
                                "error": True,
                                "message": "insufficient balance ",
                            },
                            status=400,
                        )
                    ##### could not

                    transaction = None
                    if "," in validatedphone:

                        for index, phoneNum in enumerate(validatedphone.split(",")):
                            transaction = Transaction()
                            transaction.user = user
                            transaction.service_type = service
                            transaction.service_logo = network_obj.network_logo.url
                            transaction.description = f"{plan_obj.plan_size}{plan_obj.plan_Volume} {network} Data purchased to {phoneNum}"
                            transaction.transaction_type = "DEBIT"
                            transaction.amount_paid = validatedamount
                            transaction.previous_balance = previous_balance
                            transaction.new_balance = previous_balance - validatedamount
                            transaction.status = response["status"]
                            transaction.reference = (
                                response["ref"] + "-bulk-" + str(index + 1)
                            )
                            transaction.customer_reference = customer_reference
                            transaction.save()
                    else:

                        transaction = Transaction()
                        transaction.user = user
                        transaction.service_type = service
                        transaction.service_logo = network_obj.network_logo.url
                        transaction.description = f"{plan_obj.plan_size}{plan_obj.plan_Volume} {network} Data purchased to {validatedphone}"
                        transaction.transaction_type = "DEBIT"
                        transaction.amount_paid = validatedamount
                        transaction.previous_balance = previous_balance
                        transaction.new_balance = previous_balance - validatedamount
                        transaction.status = response["status"]
                        transaction.reference = response["ref"]
                        transaction.customer_reference = customer_reference
                        transaction.save()

                except:
                    return Response(
                        {
                            "error": True,
                            "message": "something went wrong,contact administrator",
                        },
                        status=400,
                    )

                return Response(
                    {
                        "status": response["status"],
                        "message": response["message"],
                        "data": {
                            "reference": transaction.reference,
                            "status": transaction.status,
                            "service_type": transaction.service_type.service_name,
                            "description": transaction.description,
                            "amount_paid": transaction.amount_paid,
                            "previous_balance": transaction.previous_balance,
                            "new_balance": transaction.new_balance,
                            "customer_reference": transaction.customer_reference,
                            "created_date": transaction.created_date,
                        },
                    },
                    status=response["error_code"],
                )

            else:
                validate.pop("phone", None)
                validate.pop("amount", None)
                return Response(validate, status=400)

        else:
            return Response(
                {"error": True, "message": "service does not exist. "},
                status=400,
            )


########## Transactions API ENDS HERE ##########


class WebConfig(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        user_serializer = CustomUserSerializer(request.user)
        plan_list = Plan.objects.filter(available=True).order_by("plan_amount")
        plan_serializer = PlanSerializer(
            plan_list, many=True, context={"user": request.user}
        )

        ####NETWORK
        networks = Network.objects.all()
        networks_serializer = NetworkSerializer(
            networks, many=True, context={"user": request.user}
        )

        if WebsiteConfiguration.objects.first():
            configset = WebsiteConfiguration.objects.first()
            config = WebsiteConfigurationSerializer(configset).data
        else:
            config = {}

        return Response(
            {
                "customdetails": user_serializer.data,
                "config": config,
                "networks": networks_serializer.data,
                "dataplan": plan_serializer.data,
            }
        )
close fullscreen
Login or Register to edit or fork this paste. It's free.