Exemplo n.º 1
0
 def get(self, request, pk, format=None):
     group = get_object(LoanGroup, pk)
     institution_settings = get_object(InstitutionSettings,
                                       group.institution_id.pk)
     payment_serializer = MemberPaymentsSerializer(institution_settings)
     data_dict = {"fees_to_pay": payment_serializer.data, "status": 200}
     return Response(data_dict, status=status.HTTP_200_OK)
Exemplo n.º 2
0
 def get(self, request, pk, format=None):
     group = get_object(LoanGroup, pk)
     institution_settings = get_object(InstitutionSettings,
                                       group.institution_id.pk)
     savings_payment_expected = MemberSavingsPaymentsSerializer(
         institution_settings)
     data_dict = {
         "amount_to_pay": savings_payment_expected.data,
         "status": 200
     }
     return Response(data_dict, status=status.HTTP_200_OK)
Exemplo n.º 3
0
 def validate_shares_fee(self, value):
     """
     Check that the shares_fee being paid is sufficient to cover the minimum share fee required
     """
     group = get_object(LoanGroup, self.initial_data['group_id'])
     institution_settings = get_object(InstitutionSettings,
                                       group.institution_id.pk)
     if value < institution_settings.share_price:
         raise serializers.ValidationError(
             "Shares fee not sufficient to cover minimum share amount")
     return value
Exemplo n.º 4
0
 def validate_membership_fee(self, value):
     """
     Check that the membership fee being paid is equal or more than the group membership fee 
     """
     group = get_object(LoanGroup, self.initial_data['group_id'])
     institution_settings = get_object(InstitutionSettings,
                                       group.institution_id.pk)
     if value < institution_settings.membership_fee:
         raise serializers.ValidationError(
             "Membership fee not sufficient to join group")
     return value
Exemplo n.º 5
0
 def validate_amount_paid(self, value):
     savings_account = get_object(
         SavingsAccount, self.initial_data['savings_account_related'])
     group = get_object(LoanGroup,
                        savings_account.group_member_related.group_id.pk)
     institution_settings = get_object(InstitutionSettings,
                                       group.institution_id.pk)
     if value < institution_settings.savings_amount:
         raise serializers.ValidationError(
             "Saving fee not sufficient for the cycle")
     return value
Exemplo n.º 6
0
 def put(self, request, pk, format=None):
     loan_group = get_object(Loans, pk)
     serializer = LoansSerializer(loan_group, data=request.data)
     if serializer.is_valid():
         serializer.save()
         return Response(serializer.data)
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Exemplo n.º 7
0
 def get(self, request, pk, format=None):
     loan_group = get_object(Loans, pk)
     serializer = LoansSerializer(loan_group)
     data_with_link = dict(
         serializer.data)  #["member"] = 'groups/{}/members/'.format(pk)
     links = {'members': 'api/v1/groups/{}/members/'.format(pk)}
     data_with_link['links'] = links
     data_dict = {"data": data_with_link, "status": 200}
     return Response(data_dict, status=status.HTTP_200_OK)
Exemplo n.º 8
0
 def get(self, request, pk, format=None):
     institution_settings = get_object(InstitutionSettings, pk)
     if institution_settings:
         institution_settings_serializer = InstitutionSettingsCreateSerializer(
             institution_settings)
         return Response(institution_settings_serializer.data,
                         status=status.HTTP_200_OK)
     else:
         return Response("Institution doesnot exist",
                         status=status.HTTP_404_NOT_FOUND)
Exemplo n.º 9
0
    def post(self, request):
        withraw_data = request.data.copy()
        account_number = withraw_data.pop('account_number')
        savings_account_related = SavingsAccount.objects.get(
            account_number=account_number[0])

        savings_withdrawal_serilizer = SavingsWithdrawalSerializer(
            data=request.data)
        if savings_withdrawal_serilizer.is_valid():
            savings_withdrawal_serilizer.save(
                savings_account_related=savings_account_related)

            saving_amount_update = {
                "account_balance":
                float(savings_account_related.account_balance) -
                float(savings_withdrawal_serilizer.data['amount_withdrawn']),
                "running_balance":
                float(savings_account_related.running_balance) -
                float(savings_withdrawal_serilizer.data['amount_withdrawn']),
            }

            SavingsAccount.objects.update_or_create(
                id=savings_account_related.pk, defaults=saving_amount_update)

            savings_account_updated = get_object(SavingsAccount,
                                                 savings_account_related.pk)

            #send twilio sms with payment details
            phone_number = "{}{}".format(
                savings_account_related.group_member_related.
                phone_dialing_code,
                savings_account_related.group_member_related.phone_number)
            message = "You have withdrawn {} from Savings account Number {}. Your Balance is {}".format(
                savings_withdrawal_serilizer.data['amount_withdrawn'],
                savings_account_updated.account_number,
                savings_account_updated.account_balance)
            try:
                send_sms(phone_number, message)
            except:
                print("Message Not sending")

            data_dict = {
                "status": 200,
                "data": savings_withdrawal_serilizer.data,
                "savings_account": savings_account_updated.account_balance
            }
            return Response(data_dict, status=status.HTTP_201_CREATED)
        else:
            savings_withdraw_dict = {
                "status": 400,
                "error": savings_withdrawal_serilizer.errors
            }
        return Response(savings_withdraw_dict, status=status.HTTP_200_OK)
Exemplo n.º 10
0
    def update(self, request, pk, *args, **kwargs):
        instance = get_object(Loans, pk)
        if request.data[
                'loan_status'] == 'Approve' and instance.loan_status == False:
            loan_status = {'loan_status': True}
            serializer = UpdateLoanStatusSerializer(instance=instance,
                                                    data=loan_status)
            serializer.is_valid(raise_exception=True)
            serializer.save()

            # loan approval part auditing
            # loan_approved={'loan_approved':pk, }
            # loan_approver=LoanApprovalSerializer(
            #     data=loan_approved,
            # )

            # loan_approver.is_valid(raise_exception=True)
            # loan_approver.save(approved_by=request.user)

            loan_status_dict = {
                "data": serializer.data,
                "status": 200,
                "message":
                "Loan approved successfully, You can now disburse it"
            }
        elif request.data[
                'loan_status'] == 'Disapprove' and instance.loan_status == True:
            loan_status = {'loan_status': False}
            serializer = UpdateLoanStatusSerializer(instance=instance,
                                                    data=loan_status)
            serializer.is_valid(raise_exception=True)
            serializer.save()

            # loan approval part auditing
            # loan_approved={'loan_approved':pk, }
            # loan_approver=LoanApprovalSerializer(
            #     data=loan_approved,
            # )

            # loan_approver.is_valid(raise_exception=True)
            # loan_approver.save(approved_by=request.user)

            loan_status_dict = {
                "data": serializer.data,
                "status": 200,
                "message": "Loan disapproved successfully"
            }
        else:
            loan_status_dict = {
                "status": 200,
                "error": "Loan has already been approved"
            }
        return Response(loan_status_dict, status=status.HTTP_200_OK)
Exemplo n.º 11
0
 def validate_principal_amount(self, value):
     """
     Check that the principal amount is viable for loan application
     """
     applicant = get_object(GroupMember,
                            self.initial_data['loan_applicant'])
     savings_account = SavingsAccount.objects.get(
         group_member_related=applicant)
     # institution_settings = get_object(InstitutionSettings, group.institution_id.pk)
     if value > savings_account.running_balance * 2:
         raise serializers.ValidationError(
             "You are not eligible to get a loan of this amount")
     return value
Exemplo n.º 12
0
 def get(self, request, pk, format=None):
     institution = get_object(Institution, pk)
     if institution:
         institution_serializer = InstitutionCreateSerializer(institution)
         return Response(institution_serializer.data,
                         status=status.HTTP_200_OK)
     else:
         error_message_dict = {
             "status": 404,
             "error": "Institution doesnot exist"
         }
         return Response(error_message_dict,
                         status=status.HTTP_404_NOT_FOUND)
Exemplo n.º 13
0
    def get(self, request, pk, format=None):
        cycles = LoanCycles.objects.all()
        loan_group = get_object(Loans, pk)
        loan_cycles = cycles.filter(related_loan=loan_group)

        cycle_status = self.request.query_params.get('cycle_status', None)

        if cycle_status is not None:
            if cycle_status == 'Pending':
                loan_cycles = loan_cycles.filter(cycle_status="Pending")
            elif cycle_status == 'Paid':
                loan_cycles = loan_cycles.filter(cycle_status="Paid")

        serializer = LoanCycleListSerializer(loan_cycles, many=True)
        data_dict = {"data": serializer.data, "status": 200}
        return Response(data_dict, status=status.HTTP_200_OK)
Exemplo n.º 14
0
    def get(self, request, pk, format=None):
        institution = get_object(Institution, pk)
        
        #Hard coding this bitch
        institution_settings = InstitutionSettings.objects.get(institution_id=institution)

        registered_members      = GroupMember.objects.all().count()
        total_savings           = SavingsAccount.objects.all().aggregate(account_balance=Sum('account_balance'))
        total_membership_fee    = float(registered_members) * float(institution_settings.membership_fee)
        institution_statistics={
            "registered_members":registered_members,
            "total_savings":total_savings['account_balance'],
            "total_membership_fee": total_membership_fee,
        }

        data_dict = {"status":200, "data":institution_statistics}
        return Response(data_dict, status=status.HTTP_200_OK)
Exemplo n.º 15
0
    def update(self, request, pk, *args, **kwargs):
        instance = get_object(Loans, pk)
        if request.data[
                'is_loan_disbursed'] == 'Disburse' and instance.loan_status == True and instance.is_loan_disbursed == False:
            next_payment_date = calculate_next_payment_date(
                instance.loan_cycle_frequency, datetime.datetime.now())
            loan_disburse = {
                'is_loan_disbursed': True,
                'next_payment_date': next_payment_date
            }
            serializer = DisburseLoanSerializer(instance=instance,
                                                data=loan_disburse)
            serializer.is_valid(raise_exception=True)
            serializer.save()

            try:
                cycles = calculate_payment_cycles(
                    int(instance.expected_duration),
                    instance.loan_cycle_frequency,
                    float(instance.loan_balance_to_pay),
                    instance.next_payment_date)
                for cycle in cycles:
                    cycle['related_loan'] = pk
                    cycle['loan_balance'] = instance.loan_balance_to_pay
                    loan_cycle = LoanCycleSerializer(data=cycle)
                    loan_cycle.is_valid(raise_exception=True)
                    loan_cycle.save()
            except:
                print("Biganye")
            loan_status_dict = {
                "data": serializer.data,
                "loan_cycles": cycles,
                "status": 200,
                "message": "Loan disbursement successfull"
            }

        else:
            loan_status_dict = {
                "status":
                200,
                "error":
                "Loan hasnt yet been approved or loan was already disbursed"
            }
        return Response(loan_status_dict, status=status.HTTP_200_OK)
Exemplo n.º 16
0
    def post(self, request, pk, format=None):
        loan_cycle_payment = LoanPaymentsSerializer(data=request.data)
        #get loan cycle
        related_loan_cycle = get_object(LoanCycles, pk)
        #get total loan cycles
        loan_id = related_loan_cycle.related_loan.id
        total_cycles = LoanCycles.objects.filter(related_loan=loan_id).filter(
            cycle_status="Unpaid")

        if loan_cycle_payment.is_valid():
            if total_cycles.count() > 1:
                #check prevailing cycle status
                if related_loan_cycle.cycle_status == "Unpaid":
                    loan_cycle_payment.save(
                        related_loan_cycle=related_loan_cycle,
                        transaction_status=True)

                    balance = calculate_balance(
                        related_loan_cycle.amount_expected,
                        int(request.data['amount_paid']))
                    loan_balance = related_loan_cycle.loan_balance - int(
                        request.data['amount_paid'])
                    if balance > 0:
                        cycle_status = 'Unpaid'
                    else:
                        cycle_status = 'Paid'

                    cycle_update = {
                        'amount_paid': request.data['amount_paid'],
                        'balance': balance,
                        'loan_balance': loan_balance,
                        'cycle_status': cycle_status,
                        'amount_expected': balance
                    }

                    #update loan cycle with new defaults on payment
                    LoanCycles.objects.update_or_create(id=pk,
                                                        defaults=cycle_update)

                    data_dict = {
                        "status": 201,
                        "message": "Payment made successfully",
                        "data": loan_cycle_payment.data,
                        "cycle_detail": cycle_update
                    }
                    return Response(data_dict, status=status.HTTP_201_CREATED)
                else:
                    loan_cycle_payment.save(
                        related_loan_cycle=related_loan_cycle,
                        comment="Transaction Failed")
                    data_dict = {
                        "status": 400,
                        "message":
                        "Payment was not made to cycle because cycle is fully paid out",
                        "data": loan_cycle_payment.data
                    }
                    return Response(data_dict,
                                    status=status.HTTP_400_BAD_REQUEST)
            else:
                #code to implement the cycle and loan completion if the payment is complete
                pass
        return Response(loan_cycle_payment.errors,
                        status=status.HTTP_400_BAD_REQUEST)
Exemplo n.º 17
0
 def get(self, request, pk, format=None):
     loan = get_object(Loans, pk)
     serializer = LoanStatusSerializer(loan)
     data_with_link = dict(serializer.data)
     data_dict = {"data": data_with_link, "status": 200}
     return Response(data_dict, status=status.HTTP_200_OK)
Exemplo n.º 18
0
    def post(self, request, format=None):
        savings_data = request.data.copy()
        payment_method = savings_data.pop('payment_method', None)
        phone_number = savings_data.pop('phone_number', None)

        savings_payment_serializer = SavingsPaymentsSerializer(
            data=savings_data)
        if savings_payment_serializer.is_valid():
            if payment_method[0] == "CASH":
                savings_payment_serializer.save()
                #add amount to savings account
                savings_account = get_object(
                    SavingsAccount,
                    savings_payment_serializer.data['savings_account_related'])

                saving_amount_update = {
                    "account_balance":
                    float(savings_account.account_balance) +
                    float(savings_payment_serializer.data['amount_paid']),
                    "running_balance":
                    float(savings_account.running_balance) +
                    float(savings_payment_serializer.data['amount_paid']),
                }

                SavingsAccount.objects.update_or_create(
                    id=savings_account.pk, defaults=saving_amount_update)

                savings_account_updated = get_object(SavingsAccount,
                                                     savings_account.pk)

                #send twilio sms with payment details
                phone_number = "{}{}".format(
                    savings_account.group_member_related.phone_dialing_code,
                    savings_account.group_member_related.phone_number)
                message = "You have deposited {} on Savings account Number {}. Your Balance is {}".format(
                    savings_payment_serializer.data['amount_paid'],
                    savings_account_updated.account_number,
                    savings_account_updated.account_balance)
                try:
                    send_sms(phone_number, message)
                except:
                    print("Message Not sending")

                data_dict = {
                    "status": 201,
                    "data": savings_payment_serializer.data,
                    "savings_account": savings_account_updated.account_balance
                }
                return Response(data_dict, status=status.HTTP_201_CREATED)
            else:
                savings_payment_serializer.save()
                #add amount to savings account
                savings_account = get_object(
                    SavingsAccount,
                    savings_payment_serializer.data['savings_account_related'])

                saving_amount_update = {
                    "account_balance":
                    float(savings_account.account_balance) +
                    float(savings_payment_serializer.data['amount_paid']),
                    "running_balance":
                    float(savings_account.running_balance) +
                    float(savings_payment_serializer.data['amount_paid']),
                }

                SavingsAccount.objects.update_or_create(
                    id=savings_account.pk, defaults=saving_amount_update)

                savings_account_updated = get_object(SavingsAccount,
                                                     savings_account.pk)

                data = {
                    "service_code": "M002",
                    "merchant_phone_number": phone_number[0],
                    "client_phone_number": phone_number[0],
                    "amount": "2000",
                    "reason": "Savings Payment"
                }

                body = str.encode(json.dumps(data))

                url = '{}/api/v1/payments/service_payment/'.format(
                    settings.PAY_URL)
                # api_key = '7/1GTEPNjebtQ4Oq3kLFZyYoXhivqCxBKbfg0L0Q6yA80oGop2s/BzWdxmUzJv8yQERZ5NKvqDzx8j8AEh6xWQ==' # Replace this with the API key for the web service
                headers = {'Content-Type': 'application/json'}

                req = urllib.request.Request(url, body, headers)

                try:
                    response = urllib.request.urlopen(req)

                    result = response.read()
                    #decode result from binary string to dictionary
                    decoded_result = json.loads(result.decode())
                    print(decoded_result)
                    # scored_label = decoded_result['Results']['output1'][0]['Scored Labels']
                    # print(scored_label)
                except urllib.error.HTTPError as error:
                    print("The request failed with status code: " +
                          str(error.code))

                    # Print the headers - they include the requert ID and the timestamp, which are useful for debugging the failure
                    print(error.info())
                    print(json.loads(error.read().decode("utf8", 'ignore')))

                #send twilio sms with payment details
                phone_number = "{}{}".format(
                    savings_account.group_member_related.phone_dialing_code,
                    savings_account.group_member_related.phone_number)
                message = "You have deposited {} on Savings account Number {}. Your Balance is {}".format(
                    savings_payment_serializer.data['amount_paid'],
                    savings_account_updated.account_number,
                    savings_account_updated.account_balance)
                try:
                    send_sms(phone_number, message)
                except:
                    print("Message Not sending")

                data_dict = {
                    "status": 201,
                    "data": savings_payment_serializer.data,
                    "savings_account": savings_account_updated.account_balance
                }
                return Response(data_dict, status=status.HTTP_201_CREATED)
        return Response(savings_payment_serializer.errors,
                        status=status.HTTP_400_BAD_REQUEST)
Exemplo n.º 19
0
 def delete(self, request, pk, format=None):
     loan_group = get_object(Loans, pk)
     loan_group.delete()
     return Response(status=status.HTTP_204_NO_CONTENT)