Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Refund entry against loans #29460

Merged
merged 3 commits into from
Feb 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion erpnext/loan_management/doctype/loan/loan.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ frappe.ui.form.on('Loan', {
});
});

$.each(["payment_account", "loan_account"], function (i, field) {
$.each(["payment_account", "loan_account", "disbursement_account"], function (i, field) {
frm.set_query(field, function () {
return {
"filters": {
Expand Down Expand Up @@ -88,6 +88,10 @@ frappe.ui.form.on('Loan', {
frm.add_custom_button(__('Loan Write Off'), function() {
frm.trigger("make_loan_write_off_entry");
},__('Create'));

frm.add_custom_button(__('Loan Refund'), function() {
frm.trigger("make_loan_refund");
},__('Create'));
}
}
frm.trigger("toggle_fields");
Expand Down Expand Up @@ -155,6 +159,21 @@ frappe.ui.form.on('Loan', {
})
},

make_loan_refund: function(frm) {
frappe.call({
args: {
"loan": frm.doc.name
},
method: "erpnext.loan_management.doctype.loan.loan.make_refund_jv",
callback: function (r) {
if (r.message) {
let doc = frappe.model.sync(r.message)[0];
frappe.set_route("Form", doc.doctype, doc.name);
}
}
})
},

request_loan_closure: function(frm) {
frappe.confirm(__("Do you really want to close this loan"),
function() {
Expand Down
15 changes: 13 additions & 2 deletions erpnext/loan_management/doctype/loan/loan.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"actions": [],
"allow_import": 1,
"autoname": "ACC-LOAN-.YYYY.-.#####",
"creation": "2019-08-29 17:29:18.176786",
"creation": "2022-01-25 10:30:02.294967",
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 1,
Expand Down Expand Up @@ -34,6 +34,7 @@
"is_term_loan",
"account_info",
"mode_of_payment",
"disbursement_account",
"payment_account",
"column_break_9",
"loan_account",
Expand Down Expand Up @@ -356,12 +357,21 @@
"fieldtype": "Date",
"label": "Closure Date",
"read_only": 1
},
{
"fetch_from": "loan_type.disbursement_account",
"fieldname": "disbursement_account",
"fieldtype": "Link",
"label": "Disbursement Account",
"options": "Account",
"read_only": 1,
"reqd": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-10-12 18:10:32.360818",
"modified": "2022-01-25 16:29:16.325501",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan",
Expand Down Expand Up @@ -391,5 +401,6 @@
"search_fields": "posting_date",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
48 changes: 41 additions & 7 deletions erpnext/loan_management/doctype/loan/loan.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from frappe.utils import add_months, flt, get_last_day, getdate, now_datetime, nowdate

import erpnext
from erpnext.accounts.doctype.journal_entry.journal_entry import get_payment_entry
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.loan_management.doctype.loan_repayment.loan_repayment import calculate_amounts
from erpnext.loan_management.doctype.loan_security_unpledge.loan_security_unpledge import (
Expand Down Expand Up @@ -233,17 +234,15 @@ def request_loan_closure(loan, posting_date=None):
loan_type = frappe.get_value('Loan', loan, 'loan_type')
write_off_limit = frappe.get_value('Loan Type', loan_type, 'write_off_amount')

# checking greater than 0 as there may be some minor precision error
if not pending_amount:
frappe.db.set_value('Loan', loan, 'status', 'Loan Closure Requested')
elif pending_amount < write_off_limit:
if pending_amount and abs(pending_amount) < write_off_limit:
# Auto create loan write off and update status as loan closure requested
write_off = make_loan_write_off(loan)
write_off.submit()
frappe.db.set_value('Loan', loan, 'status', 'Loan Closure Requested')
else:
elif pending_amount > 0:
frappe.throw(_("Cannot close loan as there is an outstanding of {0}").format(pending_amount))

frappe.db.set_value('Loan', loan, 'status', 'Loan Closure Requested')

@frappe.whitelist()
def get_loan_application(loan_application):
loan = frappe.get_doc("Loan Application", loan_application)
Expand Down Expand Up @@ -400,4 +399,39 @@ def add_single_month(date):
if getdate(date) == get_last_day(date):
return get_last_day(add_months(date, 1))
else:
return add_months(date, 1)
return add_months(date, 1)

@frappe.whitelist()
def make_refund_jv(loan, amount=0, reference_number=None, reference_date=None, submit=0):
loan_details = frappe.db.get_value('Loan', loan, ['applicant_type', 'applicant',
'loan_account', 'payment_account', 'posting_date', 'company', 'name',
'total_payment', 'total_principal_paid'], as_dict=1)

loan_details.doctype = 'Loan'
loan_details[loan_details.applicant_type.lower()] = loan_details.applicant

if not amount:
amount = flt(loan_details.total_principal_paid - loan_details.total_payment)

if amount < 0:
frappe.throw(_('No excess amount pending for refund'))

refund_jv = get_payment_entry(loan_details, {
"party_type": loan_details.applicant_type,
"party_account": loan_details.loan_account,
"amount_field_party": 'debit_in_account_currency',
"amount_field_bank": 'credit_in_account_currency',
"amount": amount,
"bank_account": loan_details.payment_account
})

if reference_number:
refund_jv.cheque_no = reference_number

if reference_date:
refund_jv.cheque_date = reference_date

if submit:
refund_jv.submit()

return refund_jv
24 changes: 19 additions & 5 deletions erpnext/loan_management/doctype/loan/test_loan.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,17 @@ def setUp(self):
create_loan_type("Personal Loan", 500000, 8.4,
is_term_loan=1,
mode_of_payment='Cash',
disbursement_account='Disbursement Account - _TC',
payment_account='Payment Account - _TC',
loan_account='Loan Account - _TC',
interest_income_account='Interest Income Account - _TC',
penalty_income_account='Penalty Income Account - _TC')

create_loan_type("Stock Loan", 2000000, 13.5, 25, 1, 5, 'Cash', 'Payment Account - _TC', 'Loan Account - _TC',
'Interest Income Account - _TC', 'Penalty Income Account - _TC')
create_loan_type("Stock Loan", 2000000, 13.5, 25, 1, 5, 'Cash', 'Disbursement Account - _TC',
'Payment Account - _TC', 'Loan Account - _TC', 'Interest Income Account - _TC', 'Penalty Income Account - _TC')

create_loan_type("Demand Loan", 2000000, 13.5, 25, 0, 5, 'Cash', 'Payment Account - _TC', 'Loan Account - _TC',
'Interest Income Account - _TC', 'Penalty Income Account - _TC')
create_loan_type("Demand Loan", 2000000, 13.5, 25, 0, 5, 'Cash', 'Disbursement Account - _TC',
'Payment Account - _TC', 'Loan Account - _TC', 'Interest Income Account - _TC', 'Penalty Income Account - _TC')

create_loan_security_type()
create_loan_security()
Expand Down Expand Up @@ -790,6 +791,18 @@ def create_loan_accounts():
"account_type": "Bank",
}).insert(ignore_permissions=True)

if not frappe.db.exists("Account", "Disbursement Account - _TC"):
frappe.get_doc({
"doctype": "Account",
"company": "_Test Company",
"account_name": "Disbursement Account",
"root_type": "Asset",
"report_type": "Balance Sheet",
"currency": "INR",
"parent_account": "Bank Accounts - _TC",
"account_type": "Bank",
}).insert(ignore_permissions=True)

if not frappe.db.exists("Account", "Interest Income Account - _TC"):
frappe.get_doc({
"doctype": "Account",
Expand All @@ -815,7 +828,7 @@ def create_loan_accounts():
}).insert(ignore_permissions=True)

def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest, penalty_interest_rate=None, is_term_loan=None, grace_period_in_days=None,
mode_of_payment=None, payment_account=None, loan_account=None, interest_income_account=None, penalty_income_account=None,
mode_of_payment=None, disbursement_account=None, payment_account=None, loan_account=None, interest_income_account=None, penalty_income_account=None,
repayment_method=None, repayment_periods=None):

if not frappe.db.exists("Loan Type", loan_name):
Expand All @@ -829,6 +842,7 @@ def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest, penalty_i
"penalty_interest_rate": penalty_interest_rate,
"grace_period_in_days": grace_period_in_days,
"mode_of_payment": mode_of_payment,
"disbursement_account": disbursement_account,
"payment_account": payment_account,
"loan_account": loan_account,
"interest_income_account": interest_income_account,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
class TestLoanApplication(unittest.TestCase):
def setUp(self):
create_loan_accounts()
create_loan_type("Home Loan", 500000, 9.2, 0, 1, 0, 'Cash', 'Payment Account - _TC', 'Loan Account - _TC',
create_loan_type("Home Loan", 500000, 9.2, 0, 1, 0, 'Cash', 'Disbursement Account - _TC', 'Payment Account - _TC', 'Loan Account - _TC',
'Interest Income Account - _TC', 'Penalty Income Account - _TC', 'Repay Over Number of Periods', 18)
self.applicant = make_employee("kate_loan@loan.com", "_Test Company")
make_salary_structure("Test Salary Structure Loan", "Monthly", employee=self.applicant, currency='INR')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def make_gl_entries(self, cancel=0, adv_adj=0):
gle_map.append(
self.get_gl_dict({
"account": loan_details.loan_account,
"against": loan_details.payment_account,
"against": loan_details.disbursement_account,
"debit": self.disbursed_amount,
"debit_in_account_currency": self.disbursed_amount,
"against_voucher_type": "Loan",
Expand All @@ -137,7 +137,7 @@ def make_gl_entries(self, cancel=0, adv_adj=0):

gle_map.append(
self.get_gl_dict({
"account": loan_details.payment_account,
"account": loan_details.disbursement_account,
"against": loan_details.loan_account,
"credit": self.disbursed_amount,
"credit_in_account_currency": self.disbursed_amount,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class TestLoanDisbursement(unittest.TestCase):
def setUp(self):
create_loan_accounts()

create_loan_type("Demand Loan", 2000000, 13.5, 25, 0, 5, 'Cash', 'Payment Account - _TC', 'Loan Account - _TC',
'Interest Income Account - _TC', 'Penalty Income Account - _TC')
create_loan_type("Demand Loan", 2000000, 13.5, 25, 0, 5, 'Cash', 'Disbursement Account - _TC',
'Payment Account - _TC', 'Loan Account - _TC', 'Interest Income Account - _TC', 'Penalty Income Account - _TC')

create_loan_security_type()
create_loan_security()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ class TestLoanInterestAccrual(unittest.TestCase):
def setUp(self):
create_loan_accounts()

create_loan_type("Demand Loan", 2000000, 13.5, 25, 0, 5, 'Cash', 'Payment Account - _TC', 'Loan Account - _TC',
'Interest Income Account - _TC', 'Penalty Income Account - _TC')
create_loan_type("Demand Loan", 2000000, 13.5, 25, 0, 5, 'Cash', 'Disbursement Account - _TC',
'Payment Account - _TC', 'Loan Account - _TC', 'Interest Income Account - _TC', 'Penalty Income Account - _TC')

create_loan_security_type()
create_loan_security()
Expand Down
2 changes: 1 addition & 1 deletion erpnext/loan_management/doctype/loan_type/loan_type.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ frappe.ui.form.on('Loan Type', {
});
});

$.each(["payment_account", "loan_account"], function (i, field) {
$.each(["payment_account", "loan_account", "disbursement_account"], function (i, field) {
frm.set_query(field, function () {
return {
"filters": {
Expand Down
18 changes: 14 additions & 4 deletions erpnext/loan_management/doctype/loan_type/loan_type.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
"description",
"account_details_section",
"mode_of_payment",
"disbursement_account",
"payment_account",
"loan_account",
"column_break_12",
"loan_account",
"interest_income_account",
"penalty_income_account",
"amended_from"
Expand Down Expand Up @@ -79,7 +80,7 @@
{
"fieldname": "payment_account",
"fieldtype": "Link",
"label": "Payment Account",
"label": "Repayment Account",
"options": "Account",
"reqd": 1
},
Expand Down Expand Up @@ -149,15 +150,23 @@
"fieldtype": "Currency",
"label": "Auto Write Off Amount ",
"options": "Company:company:default_currency"
},
{
"fieldname": "disbursement_account",
"fieldtype": "Link",
"label": "Disbursement Account",
"options": "Account",
"reqd": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-04-19 18:10:57.368490",
"modified": "2022-01-25 16:23:57.009349",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Type",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
Expand All @@ -181,5 +190,6 @@
}
],
"sort_field": "modified",
"sort_order": "DESC"
"sort_order": "DESC",
"states": []
}
1 change: 1 addition & 0 deletions erpnext/patches.txt
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,4 @@ erpnext.patches.v12_0.add_company_link_to_einvoice_settings
erpnext.patches.v14_0.migrate_cost_center_allocations
erpnext.patches.v13_0.convert_to_website_item_in_item_card_group_template
erpnext.patches.v13_0.shopping_cart_to_ecommerce
erpnext.patches.v13_0.update_disbursement_account
22 changes: 22 additions & 0 deletions erpnext/patches/v13_0/update_disbursement_account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import frappe


def execute():

frappe.reload_doc("loan_management", "doctype", "loan_type")
frappe.reload_doc("loan_management", "doctype", "loan")

loan_type = frappe.qb.DocType("Loan Type")
loan = frappe.qb.DocType("Loan")

frappe.qb.update(
loan_type
).set(
loan_type.disbursement_account, loan_type.payment_account
).run()

frappe.qb.update(
loan
).set(
loan.disbursement_account, loan.payment_account
).run()
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ def test_loan(self):
create_loan_type("Car Loan", 500000, 8.4,
is_term_loan=1,
mode_of_payment='Cash',
disbursement_account='Disbursement Account - _TC',
payment_account='Payment Account - _TC',
loan_account='Loan Account - _TC',
interest_income_account='Interest Income Account - _TC',
Expand Down
1 change: 1 addition & 0 deletions erpnext/payroll/doctype/salary_slip/test_salary_slip.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ def test_loan_repayment_salary_slip(self):
create_loan_type("Car Loan", 500000, 8.4,
is_term_loan=1,
mode_of_payment='Cash',
disbursement_account='Disbursement Account - _TC',
payment_account='Payment Account - _TC',
loan_account='Loan Account - _TC',
interest_income_account='Interest Income Account - _TC',
Expand Down