def post(self, request, loan_id=None): user = request.user loan = Loan.objects.filter( pk=loan_id).prefetch_related('loanpayment_set') if not loan.exists(): return Response( {'detail': MESSAGES.get('NOT_FOUND').format('Loan')}, status=status.HTTP_404_NOT_FOUND) loan = loan.first() if not loan.user == user: return Response({'detail': MESSAGES.get('NOT_LOAN_OWNER')}, status=status.HTTP_400_BAD_REQUEST) if loan.status == 'paid': return Response({'detail': MESSAGES.get('LOAN_ALREADY_PAID')}, status=status.HTTP_400_BAD_REQUEST) payment = loan.loanpayment_set.filter(status='pending') if not payment.exists(): return Response({'detail': MESSAGES.get('LOAN_ALREADY_PAID')}, status=status.HTTP_400_BAD_REQUEST) payment = payment.first() payment.payment_date = datetime.datetime.now() payment.status = 'paid' payment.save() loan_profile = LoanProfile.objects.filter(user=user) loan_profile = loan_profile.first() \ if loan_profile.exists() \ else LoanProfile(user=user, score=0) today = datetime.date.today() if payment.deadline < today: loan_profile.score -= 3 else: loan_profile.score += 1 loan_profile.save() total_payment = 0 for pm in loan.loanpayment_set.all(): total_payment += pm.amount serializer = self.serializer_class(payment) response_data = serializer.data if total_payment >= (loan.amount + loan.amount * loan.interest_rate / 100): loan.status = 'paid' loan.save() else: LoanPayment.objects.create(loan=loan, amount=payment.amount, status='pending', payment_date=None, deadline=add_months( payment.deadline, 1)) response_data['loan_status'] = loan.status return Response(response_data)
def get(self, request, account_number=None): if not account_number: return Response({'detail': MESSAGES.get('URL_PARAM_MISSING')}, status=status.HTTP_400_BAD_REQUEST) transactions = self.get_queryset().filter(account=account_number) serializer = self.serializer_class(transactions, many=True) return self.get_paginated_response( self.paginate_queryset(serializer.data))
def get(self, request, loan_id=None): if not loan_id: return Response({'detail': MESSAGES.get('URL_PARAM_MISSING')}, status=status.HTTP_400_BAD_REQUEST) payments = self.get_queryset().filter( loan=loan_id).order_by('-created_at') serializer = self.serializer_class(payments, many=True) return self.get_paginated_response( self.paginate_queryset(serializer.data))
def get(self, request): user = request.user account = Account.objects.filter(user=user) if not account.exists(): return Response({'detail': MESSAGES.get('ACCOUNT_DOES_NOT_EXIST')}, status=status.HTTP_400_BAD_REQUEST) serializer = self.serializer_class(account.first()) return Response(serializer.data)
def post(self, request): user = request.user account = Account.objects.filter(user=user) if account.exists(): return Response({'detail': MESSAGES.get('ACCOUNT_EXISTS')}, status=status.HTTP_400_BAD_REQUEST) account_number = generate_account_number() account = Account.objects.create(number=account_number, user=user) serializer = self.serializer_class(account) return Response(serializer.data, status=status.HTTP_201_CREATED)
def is_eligible_lender(amount, length, score, num_of_loans): if amount > 50000 or amount < 500: return { 'eligible': False, 'reason': MESSAGES.get('WRONG_LOAN_AMOUNT') } if length > 96 or length < 6: return { 'eligible': False, 'reason': MESSAGES.get('WRONG_LOAN_LENGTH') } if num_of_loans <= 5: return check_eligibility(amount, length, 'newbee') elif 5 < num_of_loans <= 10: _type = 'bronze' if 60 <= score else 'newbee' return check_eligibility(amount, length, _type) elif 10 < num_of_loans <= 25: _type = 'silver' if 120 <= score else 'bronze' return check_eligibility(amount, length, _type) else: _type = 'gold' if 180 <= score else 'silver' return check_eligibility(amount, length, _type)
def get(self, request, user_id=None): user = request.user if user_id: user = User.objects.filter(pk=user_id).first() if not user: return Response( {'detail': MESSAGES.get('NOT_FOUND').format('user')}, status=status.HTTP_404_NOT_FOUND) loan_profile = LoanProfile.objects.filter(user=user) num_of_loans = len(Loan.objects.filter(user=user)) serializer = self.serializer_class(user, context={'request': request}) response_data = serializer.data response_data['lend_score'] = loan_profile.first().score \ if loan_profile.exists() else None response_data['num_of_loans'] = num_of_loans return Response(response_data)
def check_eligibility(amount, length, _type): if _type == 'newbee': if 500 <= amount <= 3000 and 6 <= length <= 24: interest_rate = 17 if length <= 12: interest_rate += 18 / length else: interest_rate -= 18 / length return { 'eligible': True, 'interest_rate': interest_rate } return { 'eligible': False, 'reason': MESSAGES.get('NON_ELIGIBLE_REQUEST') } elif _type == 'bronze': if 500 <= amount <= 10000 and 6 <= length <= 48: interest_rate = 14 if length <= 24: interest_rate += 22 / length else: interest_rate -= 22 / length return { 'eligible': True, 'interest_rate': interest_rate } return { 'eligible': False, 'reason': MESSAGES.get('NON_ELIGIBLE_REQUEST') } elif _type == 'silver': if 500 <= amount <= 30000 and 6 <= length < 72: interest_rate = 11 if length <= 36: interest_rate += 34 / length else: interest_rate -= 34 / length return { 'eligible': True, 'interest_rate': interest_rate } return { 'eligible': False, 'reason': MESSAGES.get('NON_ELIGIBLE_REQUEST') } elif _type == 'gold': if 500 <= amount <= 50000 and 6 <= length < 96: interest_rate = 8 if length <= 48: interest_rate += 44 / length else: interest_rate -= 44 / length return { 'eligible': True, 'interest_rate': interest_rate } return { 'eligible': False, 'reason': MESSAGES.get('NON_ELIGIBLE_REQUEST') } else: return { 'eligible': False, 'reason': MESSAGES.get('WRONG_SCORE_TYPE') }
def post(self, request): user = request.user requested_amount = request.data.get('amount') requested_length = request.data.get('length') errors = {} if not requested_amount: errors['amount'] = [ MESSAGES.get('FIELD_REQUIRED').format('This field') ] if not requested_length: errors['length'] = [ MESSAGES.get('FIELD_REQUIRED').format('This field') ] loan_profile = LoanProfile.objects.filter(user=user) if loan_profile.exists(): loan_profile = loan_profile.first() loans = self.get_queryset().prefetch_related( 'loanpayment_set').filter(user=user) for loan in loans: loan_finished = True total_amount = loan.amount + (loan.amount * loan.interest_rate / 100) amount = 0 for payment in loan.loanpayment_set.filter(status='paid'): amount += payment.amount if total_amount > amount: loan_finished = False if not loan_finished: return Response({'detail': MESSAGES.get('UNPAID_LOAN')}, status=status.HTTP_400_BAD_REQUEST) num_of_loans = len(loans) else: loan_profile = LoanProfile.objects.create(user=user, score=0) num_of_loans = 0 lend_score = loan_profile.score eligibility = is_eligible_lender(requested_amount, requested_length, lend_score, num_of_loans) if not eligibility['eligible']: return Response({'detail': eligibility['reason']}, status=status.HTTP_400_BAD_REQUEST) today = datetime.date.today() deadline = today.replace(year=today.year + math.ceil(requested_length / 12)) loan_request = Loan.objects.create( user=user, amount=requested_amount, interest_rate=eligibility['interest_rate'], status='ongoing', deadline=deadline) account = Account.objects.get(user=user) account.balance += requested_amount account.updated_at = datetime.datetime.now() account.save() Transaction.objects.create(id=generate_transaction_id(), type='loan', amount=requested_amount, description='LOAN FOR {} {}'.format( user.first_name, user.last_name), account=account) payment_deadline = add_months(today, 1) payment_amount = requested_amount payment_amount += payment_amount * eligibility['interest_rate'] / 100 payment_amount /= requested_length LoanPayment.objects.create(loan=loan_request, amount=payment_amount, status='pending', payment_date=None, deadline=payment_deadline) return Response({ 'id': loan_request.id, 'monthly_payment_amount': payment_amount, 'loan_length': requested_length, 'loan_amount': requested_amount, 'interest_rate': eligibility['interest_rate'], 'next_payment_date': payment_deadline, 'loan_deadline': deadline })