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)
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)
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
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
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
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)
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)
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)
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)
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)
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
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)
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)
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)
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)
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)
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)
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)
def delete(self, request, pk, format=None): loan_group = get_object(Loans, pk) loan_group.delete() return Response(status=status.HTTP_204_NO_CONTENT)