def test_calculate_principal_force_max_duration(self): actual = calculate_principal(20000.0, "_Test Loan Plan Eco", "2020-08-19", "2017-12-12") expected = { "principal": 300000.0, "expected_eta": getdate("2022-12-31"), "duration": 60, "recovery_amount": 5000.0, "initial_interest": 15000.0, } self.assertEqual(actual, expected)
def test_calculate_principal(self): actual = calculate_principal(20000.0, "_Test Loan Plan Basic", "2030-08-19", "2017-12-12") expected = { "principal": 400000.0, "expected_eta": getdate("2022-12-31"), "duration": 60, "recovery_amount": 6666.67, "initial_interest": 40000.0, } self.assertEqual(actual, expected)
def test_calculate_principal_end_date_before_loan_plan_max_duration(self): actual = calculate_principal(20000.0, "_Test Loan Plan Basic", "2020-08-19", "2017-12-12") expected = { "principal": 206666.67, "expected_eta": getdate("2020-07-31"), "duration": 31, "recovery_amount": 6666.67, "initial_interest": 21000.0, } self.assertEqual(actual, expected)
def test_calculate_principal_force_max_duration(self): actual = calculate_principal(20000.0, '_Test Loan Plan Eco', '2020-08-19', '2017-12-12') expected = { 'principal': 300000.0, 'expected_eta': getdate('2022-12-31'), 'duration': 60, 'recovery_amount': 5000.0, 'initial_interest': 15000.0, } self.assertEqual(actual, expected)
def test_calculate_principal(self): actual = calculate_principal(20000.0, '_Test Loan Plan Basic', '2030-08-19', '2017-12-12') expected = { 'principal': 400000.0, 'expected_eta': getdate('2022-12-31'), 'duration': 60, 'recovery_amount': 6666.67, 'initial_interest': 40000.0, } self.assertEqual(actual, expected)
def validate_allowable_amount(self, is_update=False): effective_date = frappe.get_value( 'Loan Plan', self.loan_plan, 'effective_from' ) if effective_date and \ getdate(effective_date) > getdate(self.posting_date): return None date_of_retirement, net_salary_amount = frappe.get_value( 'Microfinance Loanee', {'customer': self.customer}, ['date_of_retirement', 'net_salary_amount'] ) if not date_of_retirement or not net_salary_amount: return None allowed = calculate_principal( income=net_salary_amount, loan_plan=self.loan_plan, end_date=date_of_retirement, execution_date=self.posting_date, ) loan_principal = flt(self.loan_principal) recovery_amount = flt(self.recovery_amount) if loan_principal > allowed.get('principal'): frappe.throw( "Requested principal cannot exceed {}".format( _fmt_money(allowed.get('principal')) ) ) tentative_outstanding = reduce( lambda a, x: a + get_outstanding_principal(x), map(pick('name'), _existing_loans_by(self.customer)), loan_principal ) if is_update: before = self.get_doc_before_save() tentative_outstanding -= before.loan_principal if tentative_outstanding > allowed.get('principal'): frappe.throw( "Customer already has existing loans. " "Total principal would exceed allowed {}".format( _fmt_money(allowed.get('principal')), ) ) if recovery_amount < tentative_outstanding / allowed.get('duration'): frappe.throw( "Recovery Amount cannot be less than {}".format( _fmt_money(loan_principal / allowed.get('duration')) ) )
def test_calculate_principal_end_date_before_loan_plan_max_duration(self): actual = calculate_principal( 20000.0, '_Test Loan Plan Basic', '2020-08-19', '2017-12-12', ) expected = { 'principal': 206666.67, 'expected_eta': getdate('2020-07-31'), 'duration': 31, 'recovery_amount': 6666.67, 'initial_interest': 21000.0, } self.assertEqual(actual, expected)
def validate_allowable_amount(self, is_update=False): loan_type = self.loan_type or frappe.db.get_value( "Loan Plan", self.loan_plan, "loan_type") if loan_type == "EMI": return effective_date = frappe.get_value("Loan Plan", self.loan_plan, "effective_from") if effective_date and getdate(effective_date) > getdate( self.posting_date): return None date_of_retirement, net_salary_amount = frappe.get_value( "Microfinance Loanee", {"customer": self.customer}, ["date_of_retirement", "net_salary_amount"], ) if not date_of_retirement or not net_salary_amount: return None allowed = calculate_principal( income=net_salary_amount, loan_plan=self.loan_plan, end_date=date_of_retirement, execution_date=self.posting_date, ) loan_principal = flt(self.loan_principal) recovery_amount = flt(self.recovery_amount) if loan_principal > allowed.get("principal"): frappe.throw("Requested principal cannot exceed {}".format( _fmt_money(allowed.get("principal")))) tentative_outstanding = reduce( lambda a, x: a + get_outstanding_principal(x), map(pick("name"), _existing_loans_by(self.customer)), loan_principal, ) if is_update: before = self.get_doc_before_save() tentative_outstanding -= before.loan_principal if tentative_outstanding > allowed.get("principal"): frappe.throw("Customer already has existing loans. " "Total principal would exceed allowed {}".format( _fmt_money(allowed.get("principal")))) if recovery_amount < tentative_outstanding / allowed.get("duration"): frappe.throw("Recovery Amount cannot be less than {}".format( _fmt_money(loan_principal / allowed.get("duration"))))