Merge branch 'develop' into email-digest
diff --git a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json
index a5ac3f3..4abba5f 100644
--- a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json
+++ b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry.json
@@ -1,5 +1,4 @@
{
- "actions": [],
"creation": "2019-05-09 15:47:39.760406",
"doctype": "DocType",
"engine": "InnoDB",
@@ -54,6 +53,7 @@
{
"fieldname": "transaction_type",
"fieldtype": "Link",
+ "in_standard_filter": 1,
"label": "Transaction Type",
"options": "DocType"
},
@@ -109,9 +109,9 @@
}
],
"in_create": 1,
+ "index_web_pages_for_search": 1,
"is_submittable": 1,
- "links": [],
- "modified": "2020-02-27 14:40:10.502605",
+ "modified": "2020-09-04 12:16:36.569066",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Ledger Entry",
diff --git a/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry_list.js b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry_list.js
new file mode 100644
index 0000000..889325b
--- /dev/null
+++ b/erpnext/hr/doctype/leave_ledger_entry/leave_ledger_entry_list.js
@@ -0,0 +1,13 @@
+frappe.listview_settings['Leave Ledger Entry'] = {
+ onload: function(listview) {
+ if(listview.page.fields_dict.transaction_type) {
+ listview.page.fields_dict.transaction_type.get_query = function() {
+ return {
+ "filters": {
+ "name": ["in", ["Leave Allocation", "Leave Application", "Leave Encashment"]],
+ }
+ };
+ };
+ }
+ }
+};
diff --git a/erpnext/loan_management/doctype/loan/test_loan.py b/erpnext/loan_management/doctype/loan/test_loan.py
index 5faf80e..f225409 100644
--- a/erpnext/loan_management/doctype/loan/test_loan.py
+++ b/erpnext/loan_management/doctype/loan/test_loan.py
@@ -199,10 +199,9 @@
"Loan Closure", flt(loan.loan_amount + accrued_interest_amount))
repayment_entry.submit()
- amounts = frappe.db.get_value('Loan Interest Accrual', {'loan': loan.name}, ['paid_interest_amount',
- 'paid_principal_amount'])
+ amount = frappe.db.get_value('Loan Interest Accrual', {'loan': loan.name}, ['sum(paid_interest_amount)'])
- self.assertEquals(flt(amounts[0], 2),flt(accrued_interest_amount, 2))
+ self.assertEquals(flt(amount, 2),flt(accrued_interest_amount, 2))
self.assertEquals(flt(repayment_entry.penalty_amount, 5), 0)
loan.load_from_db()
diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
index 1d3fa71..2d959bf 100644
--- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
+++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
@@ -213,7 +213,8 @@
WHERE loan = %s""", (loan.name))
if last_posting_date[0][0]:
- return last_posting_date[0][0]
+ # interest for last interest accrual date is already booked, so add 1 day
+ return add_days(last_posting_date[0][0], 1)
else:
return loan.disbursement_date
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
index 7d83e32..47fb885 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
@@ -13,6 +13,7 @@
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.accounts.general_ledger import make_gl_entries
from erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall import update_shortfall_status
+from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
class LoanRepayment(AccountsController):
@@ -22,6 +23,9 @@
self.validate_amount()
self.allocate_amounts(amounts['pending_accrual_entries'])
+ def before_submit(self):
+ self.book_unaccrued_interest()
+
def on_submit(self):
self.update_paid_amount()
self.make_gl_entries()
@@ -72,6 +76,26 @@
msg = _("Amount of {0} is required for Loan closure").format(self.payable_amount)
frappe.throw(msg)
+ def book_unaccrued_interest(self):
+ if self.payment_type == 'Loan Closure':
+ total_interest_paid = 0
+ for payment in self.repayment_details:
+ total_interest_paid += payment.paid_interest_amount
+
+ if total_interest_paid < self.interest_payable:
+ if not self.is_term_loan:
+ process = process_loan_interest_accrual_for_demand_loans(posting_date=self.posting_date,
+ loan=self.against_loan)
+
+ lia = frappe.db.get_value('Loan Interest Accrual', {'process_loan_interest_accrual':
+ process}, ['name', 'interest_amount', 'payable_principal_amount'], as_dict=1)
+
+ self.append('repayment_details', {
+ 'loan_interest_accrual': lia.name,
+ 'paid_interest_amount': lia.interest_amount,
+ 'paid_principal_amount': lia.payable_principal_amount
+ })
+
def update_paid_amount(self):
precision = cint(frappe.db.get_default("currency_precision")) or 2
@@ -148,8 +172,6 @@
if self.payment_type == 'Loan Closure' and total_interest_paid < self.interest_payable:
unaccrued_interest = self.interest_payable - total_interest_paid
interest_paid -= unaccrued_interest
- if self.repayment_details:
- self.repayment_details[-1].paid_interest_amount += unaccrued_interest
if interest_paid:
self.principal_amount_paid += interest_paid
diff --git a/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.py b/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.py
index cd3cf7e..0fa9686 100644
--- a/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.py
+++ b/erpnext/loan_management/doctype/process_loan_interest_accrual/process_loan_interest_accrual.py
@@ -36,6 +36,8 @@
loan_process.submit()
+ return loan_process.name
+
def process_loan_interest_accrual_for_term_loans(posting_date=None, loan_type=None, loan=None):
if not term_loan_accrual_pending(posting_date or nowdate()):
@@ -49,6 +51,8 @@
loan_process.submit()
+ return loan_process.name
+
def term_loan_accrual_pending(date):
pending_accrual = frappe.db.get_value('Repayment Schedule', {
'payment_date': ('<=', date),
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 4ed30ad..ede2212 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -632,7 +632,7 @@
execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart')
execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart_field')
erpnext.patches.v12_0.remove_bank_remittance_custom_fields
-erpnext.patches.v12_0.generate_leave_ledger_entries
+erpnext.patches.v12_0.generate_leave_ledger_entries #27-08-2020
execute:frappe.delete_doc_if_exists("Report", "Loan Repayment")
erpnext.patches.v12_0.move_credit_limit_to_customer_credit_limit
erpnext.patches.v12_0.add_variant_of_in_item_attribute_table
diff --git a/erpnext/patches/v12_0/generate_leave_ledger_entries.py b/erpnext/patches/v12_0/generate_leave_ledger_entries.py
index c5bec19..342c129 100644
--- a/erpnext/patches/v12_0/generate_leave_ledger_entries.py
+++ b/erpnext/patches/v12_0/generate_leave_ledger_entries.py
@@ -36,8 +36,7 @@
for allocation in allocation_list:
if not frappe.db.exists("Leave Ledger Entry", {'transaction_type': 'Leave Allocation', 'transaction_name': allocation.name}):
- allocation.update(dict(doctype="Leave Allocation"))
- allocation_obj = frappe.get_doc(allocation)
+ allocation_obj = frappe.get_doc("Leave Allocation", allocation)
allocation_obj.create_leave_ledger_entry()
def generate_application_leave_ledger_entries():
@@ -46,8 +45,7 @@
for application in leave_applications:
if not frappe.db.exists("Leave Ledger Entry", {'transaction_type': 'Leave Application', 'transaction_name': application.name}):
- application.update(dict(doctype="Leave Application"))
- frappe.get_doc(application).create_leave_ledger_entry()
+ frappe.get_doc("Leave Application", application.name).create_leave_ledger_entry()
def generate_encashment_leave_ledger_entries():
''' fix ledger entries for missing leave encashment transaction '''
@@ -55,8 +53,7 @@
for encashment in leave_encashments:
if not frappe.db.exists("Leave Ledger Entry", {'transaction_type': 'Leave Encashment', 'transaction_name': encashment.name}):
- encashment.update(dict(doctype="Leave Encashment"))
- frappe.get_doc(encashment).create_leave_ledger_entry()
+ frappe.get_doc("Leave Enchashment", encashment).create_leave_ledger_entry()
def generate_expiry_allocation_ledger_entries():
''' fix ledger entries for missing leave allocation transaction '''
@@ -65,24 +62,16 @@
for allocation in allocation_list:
if not frappe.db.exists("Leave Ledger Entry", {'transaction_type': 'Leave Allocation', 'transaction_name': allocation.name, 'is_expired': 1}):
- allocation.update(dict(doctype="Leave Allocation"))
- allocation_obj = frappe.get_doc(allocation)
+ allocation_obj = frappe.get_doc("Leave Allocation", allocation)
if allocation_obj.to_date <= getdate(today()):
expire_allocation(allocation_obj)
def get_allocation_records():
- return frappe.get_all("Leave Allocation", filters={
- "docstatus": 1
- }, fields=['name', 'employee', 'leave_type', 'new_leaves_allocated',
- 'unused_leaves', 'from_date', 'to_date', 'carry_forward'
- ], order_by='to_date ASC')
+ return frappe.get_all("Leave Allocation", filters={"docstatus": 1},
+ fields=['name'], order_by='to_date ASC')
def get_leaves_application_records():
- return frappe.get_all("Leave Application", filters={
- "docstatus": 1
- }, fields=['name', 'employee', 'leave_type', 'total_leave_days', 'from_date', 'to_date'])
+ return frappe.get_all("Leave Application", filters={"docstatus": 1}, fields=['name'])
def get_leave_encashment_records():
- return frappe.get_all("Leave Encashment", filters={
- "docstatus": 1
- }, fields=['name', 'employee', 'leave_type', 'encashable_days', 'encashment_date'])
+ return frappe.get_all("Leave Encashment", filters={"docstatus": 1}, fields=['name'])