Merge pull request #21305 from deepeshgarg007/partial_loan_repayment_fixes
fix: Loan Repayment code clean up and other fixes
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index b3c803b..223c4e3 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -776,22 +776,16 @@
for payment in self.get('loans'):
amounts = calculate_amounts(payment.loan, self.posting_date, "Regular Payment")
+ total_amount = amounts['interest_amount'] + amounts['payable_principal_amount']
+ if payment.total_payment > total_amount:
+ frappe.throw(_("""Row {0}: Paid amount {1} is greater than pending accrued amount {2}
+ against loan {3}""").format(payment.idx, frappe.bold(payment.total_payment),
+ frappe.bold(total_amount), frappe.bold(payment.loan)))
- if payment.interest_amount > amounts['interest_amount']:
- frappe.throw(_("""Row {0}: Paid Interest amount {1} is greater than pending interest amount {2}
- against loan {3}""").format(payment.idx, frappe.bold(payment.interest_amount),
- frappe.bold(amounts['interest_amount']), frappe.bold(payment.loan)))
-
- if payment.principal_amount > amounts['payable_principal_amount']:
- frappe.throw(_("""Row {0}: Paid Principal amount {1} is greater than pending principal amount {2}
- against loan {3}""").format(payment.idx, frappe.bold(payment.principal_amount),
- frappe.bold(amounts['payable_principal_amount']), frappe.bold(payment.loan)))
-
- payment.total_payment = payment.interest_amount + payment.principal_amount
self.total_interest_amount += payment.interest_amount
self.total_principal_amount += payment.principal_amount
- self.total_loan_repayment = self.total_interest_amount + self.total_principal_amount
+ self.total_loan_repayment += payment.total_payment
def get_loan_details(self):
diff --git a/erpnext/loan_management/doctype/loan/test_loan.py b/erpnext/loan_management/doctype/loan/test_loan.py
index 108672b..2d1ad33 100644
--- a/erpnext/loan_management/doctype/loan/test_loan.py
+++ b/erpnext/loan_management/doctype/loan/test_loan.py
@@ -149,13 +149,19 @@
repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(last_date, 10), "Regular Payment", 111118.68)
repayment_entry.save()
+ repayment_entry.submit()
penalty_amount = (accrued_interest_amount * 5 * 25) / (100 * days_in_year(get_datetime(first_date).year))
-
- self.assertEquals(flt(repayment_entry.interest_payable, 2), flt(accrued_interest_amount, 2))
self.assertEquals(flt(repayment_entry.penalty_amount, 2), flt(penalty_amount, 2))
- repayment_entry.submit()
+ amounts = frappe.db.get_value('Loan Interest Accrual', {'loan': loan.name}, ['paid_interest_amount',
+ 'paid_principal_amount'])
+
+ loan.load_from_db()
+
+ self.assertEquals(amounts[0], repayment_entry.interest_payable)
+ self.assertEquals(flt(loan.total_principal_paid, 2), flt(repayment_entry.amount_paid -
+ penalty_amount - amounts[0], 2))
def test_loan_closure_repayment(self):
pledges = []
@@ -189,15 +195,19 @@
process_loan_interest_accrual_for_demand_loans(posting_date = last_date)
repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(last_date, 5),
- "Loan Closure", 13315.0681)
- repayment_entry.save()
+ "Loan Closure", flt(loan.loan_amount + accrued_interest_amount))
+ repayment_entry.submit()
- repayment_entry.amount_paid = repayment_entry.payable_amount
+ amounts = frappe.db.get_value('Loan Interest Accrual', {'loan': loan.name}, ['paid_interest_amount',
+ 'paid_principal_amount'])
- self.assertEquals(flt(repayment_entry.interest_payable, 3), flt(accrued_interest_amount, 3))
+ unaccrued_interest_amount = (loan.loan_amount * loan.rate_of_interest * 6) \
+ / (days_in_year(get_datetime(first_date).year) * 100)
+
+ self.assertEquals(flt(amounts[0] + unaccrued_interest_amount, 3),
+ flt(accrued_interest_amount, 3))
self.assertEquals(flt(repayment_entry.penalty_amount, 5), 0)
- repayment_entry.submit()
loan.load_from_db()
self.assertEquals(loan.status, "Loan Closure Requested")
@@ -227,57 +237,15 @@
process_loan_interest_accrual_for_term_loans(posting_date=nowdate())
repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(get_last_day(nowdate()), 5),
- "Regular Payment", 89768.7534247)
+ "Regular Payment", 89768.75)
- repayment_entry.save()
repayment_entry.submit()
- repayment_entry.load_from_db()
+ amounts = frappe.db.get_value('Loan Interest Accrual', {'loan': loan.name}, ['paid_interest_amount',
+ 'paid_principal_amount'])
- self.assertEquals(repayment_entry.interest_payable, 11250.00)
- self.assertEquals(repayment_entry.payable_principal_amount, 78303.00)
-
- def test_partial_loan_repayment(self):
- pledges = []
- pledges.append({
- "loan_security": "Test Security 1",
- "qty": 4000.00,
- "haircut": 50
- })
-
- loan_security_pledge = create_loan_security_pledge(self.applicant2, pledges)
-
- loan = create_demand_loan(self.applicant2, "Demand Loan", loan_security_pledge.name,
- posting_date=get_first_day(nowdate()))
-
- loan.submit()
-
- self.assertEquals(loan.loan_amount, 1000000)
-
- first_date = '2019-10-01'
- last_date = '2019-10-30'
-
- no_of_days = date_diff(last_date, first_date) + 1
-
- accrued_interest_amount = (loan.loan_amount * loan.rate_of_interest * no_of_days) \
- / (days_in_year(get_datetime().year) * 100)
-
- make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
-
- process_loan_interest_accrual_for_demand_loans(posting_date = add_days(first_date, 15))
- process_loan_interest_accrual_for_demand_loans(posting_date = add_days(first_date, 30))
-
- repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(last_date, 1), "Regular Payment", 6500)
- repayment_entry.save()
- repayment_entry.submit()
-
- penalty_amount = (accrued_interest_amount * 4 * 25) / (100 * days_in_year(get_datetime(first_date).year))
-
- lia1 = frappe.get_value("Loan Interest Accrual", {"loan": loan.name, "is_paid": 1}, 'name')
- lia2 = frappe.get_value("Loan Interest Accrual", {"loan": loan.name, "is_paid": 0}, 'name')
-
- self.assertTrue(lia1)
- self.assertTrue(lia2)
+ self.assertEquals(amounts[0], 11250.00)
+ self.assertEquals(amounts[1], 78303.00)
def test_security_shortfall(self):
pledges = []
@@ -294,7 +262,7 @@
make_loan_disbursement_entry(loan.name, loan.loan_amount)
- frappe.db.sql(""" UPDATE `tabLoan Security Price` SET loan_security_price = 100
+ frappe.db.sql("""UPDATE `tabLoan Security Price` SET loan_security_price = 100
where loan_security='Test Security 2'""")
create_process_loan_security_shortfall()
diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.json b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.json
index a261120..5fc3e8f 100644
--- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.json
+++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.json
@@ -15,12 +15,13 @@
"company",
"posting_date",
"is_term_loan",
- "is_paid",
"section_break_7",
"pending_principal_amount",
"payable_principal_amount",
+ "paid_principal_amount",
"column_break_14",
"interest_amount",
+ "paid_interest_amount",
"section_break_15",
"process_loan_interest_accrual",
"repayment_schedule_name",
@@ -103,13 +104,6 @@
},
{
"default": "0",
- "fieldname": "is_paid",
- "fieldtype": "Check",
- "label": "Is Paid",
- "read_only": 1
- },
- {
- "default": "0",
"fetch_from": "loan.is_term_loan",
"fieldname": "is_term_loan",
"fieldtype": "Check",
@@ -143,12 +137,24 @@
"hidden": 1,
"label": "Repayment Schedule Name",
"read_only": 1
+ },
+ {
+ "fieldname": "paid_principal_amount",
+ "fieldtype": "Currency",
+ "label": "Paid Principal Amount",
+ "options": "Company:company:default_currency"
+ },
+ {
+ "fieldname": "paid_interest_amount",
+ "fieldtype": "Currency",
+ "label": "Paid Interest Amount",
+ "options": "Company:company:default_currency"
}
],
"in_create": 1,
"is_submittable": 1,
"links": [],
- "modified": "2020-04-10 18:31:02.369857",
+ "modified": "2020-04-16 11:24:23.258404",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Interest Accrual",
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.json b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.json
index 4b930c5..789c129 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.json
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.json
@@ -30,9 +30,8 @@
"reference_number",
"column_break_21",
"reference_date",
- "paid_accrual_entries",
- "partial_paid_entry",
"principal_amount_paid",
+ "repayment_details",
"amended_from"
],
"fields": [
@@ -156,13 +155,6 @@
"read_only": 1
},
{
- "fieldname": "paid_accrual_entries",
- "fieldtype": "Text",
- "hidden": 1,
- "label": "Paid Accrual Entries",
- "read_only": 1
- },
- {
"default": "0",
"fetch_from": "against_loan.is_term_loan",
"fieldname": "is_term_loan",
@@ -198,13 +190,6 @@
"fieldtype": "Column Break"
},
{
- "fieldname": "partial_paid_entry",
- "fieldtype": "Text",
- "hidden": 1,
- "label": "Partial Paid Entry",
- "read_only": 1
- },
- {
"default": "0.0",
"fieldname": "principal_amount_paid",
"fieldtype": "Currency",
@@ -225,11 +210,18 @@
"fieldtype": "Date",
"label": "Due Date",
"read_only": 1
+ },
+ {
+ "fieldname": "repayment_details",
+ "fieldtype": "Table",
+ "hidden": 1,
+ "label": "Repayment Details",
+ "options": "Loan Repayment Detail"
}
],
"is_submittable": 1,
"links": [],
- "modified": "2020-02-26 06:18:54.934538",
+ "modified": "2020-04-16 18:14:45.166754",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Repayment",
@@ -264,7 +256,6 @@
"write": 1
}
],
- "quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
index 2d2ca4c..87e8a15 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
@@ -19,11 +19,11 @@
def validate(self):
amounts = calculate_amounts(self.against_loan, self.posting_date, self.payment_type)
self.set_missing_values(amounts)
-
- def before_submit(self):
- self.mark_as_paid()
+ self.validate_amount()
+ self.allocate_amounts(amounts['pending_accrual_entries'])
def on_submit(self):
+ self.update_paid_amount()
self.make_gl_entries()
def on_cancel(self):
@@ -38,32 +38,25 @@
self.cost_center = erpnext.get_default_cost_center(self.company)
if not self.interest_payable:
- self.interest_payable = amounts['interest_amount']
+ self.interest_payable = flt(amounts['interest_amount'], 2)
if not self.penalty_amount:
- self.penalty_amount = amounts['penalty_amount']
+ self.penalty_amount = flt(amounts['penalty_amount'], 2)
if not self.pending_principal_amount:
- self.pending_principal_amount = amounts['pending_principal_amount']
+ self.pending_principal_amount = flt(amounts['pending_principal_amount'], 2)
if not self.payable_principal_amount and self.is_term_loan:
- self.payable_principal_amount = amounts['payable_principal_amount']
+ self.payable_principal_amount = flt(amounts['payable_principal_amount'], 2)
if not self.payable_amount:
- self.payable_amount = amounts['payable_amount']
-
- if amounts.get('paid_accrual_entries'):
- self.paid_accrual_entries = frappe.as_json(amounts.get('paid_accrual_entries'))
+ self.payable_amount = flt(amounts['payable_amount'], 2)
if amounts.get('due_date'):
self.due_date = amounts.get('due_date')
- def mark_as_paid(self):
- paid_entries = []
- paid_amount = self.amount_paid
- interest_paid = paid_amount
-
- if not paid_amount:
+ def validate_amount(self):
+ if not self.amount_paid:
frappe.throw(_("Amount paid cannot be zero"))
if self.amount_paid < self.penalty_amount:
@@ -74,37 +67,15 @@
msg = _("Amount of {0} is required for Loan closure").format(self.payable_amount)
frappe.throw(msg)
+ def update_paid_amount(self):
loan = frappe.get_doc("Loan", self.against_loan)
- if self.paid_accrual_entries:
- paid_accrual_entries = json.loads(self.paid_accrual_entries)
-
- if paid_amount - self.penalty_amount > 0 and self.paid_accrual_entries:
-
- interest_paid = paid_amount - self.penalty_amount
-
- for lia, interest_amount in iteritems(paid_accrual_entries):
- if interest_amount <= interest_paid:
- paid_entries.append(lia)
- interest_paid -= interest_amount
- elif interest_paid:
- self.partial_paid_entry = frappe.as_json({"name": lia, "interest_amount": interest_amount})
- frappe.db.set_value("Loan Interest Accrual", lia, "interest_amount",
- interest_amount - interest_paid)
- interest_paid = 0
-
- if paid_entries:
- self.paid_accrual_entries = frappe.as_json(paid_entries)
- else:
- self.paid_accrual_entries = ""
-
- if interest_paid:
- self.principal_amount_paid = interest_paid
-
- if paid_entries:
- frappe.db.sql("""UPDATE `tabLoan Interest Accrual`
- SET is_paid = 1 where name in (%s)""" #nosec
- % ", ".join(['%s']*len(paid_entries)), tuple(paid_entries))
+ for payment in self.repayment_details:
+ frappe.db.sql(""" UPDATE `tabLoan Interest Accrual`
+ SET paid_principal_amount = `paid_principal_amount` + %s,
+ paid_interest_amount = `paid_interest_amount` + %s
+ WHERE name = %s""",
+ (flt(payment.paid_principal_amount), flt(payment.paid_interest_amount), payment.loan_interest_accrual))
if flt(loan.total_principal_paid + self.principal_amount_paid, 2) >= flt(loan.total_payment, 2):
frappe.db.set_value("Loan", self.against_loan, "status", "Loan Closure Requested")
@@ -116,21 +87,14 @@
update_shortfall_status(self.against_loan, self.principal_amount_paid)
def mark_as_unpaid(self):
-
loan = frappe.get_doc("Loan", self.against_loan)
- if self.paid_accrual_entries:
- paid_accrual_entries = json.loads(self.paid_accrual_entries)
-
- if self.paid_accrual_entries:
- frappe.db.sql("""UPDATE `tabLoan Interest Accrual`
- SET is_paid = 0 where name in (%s)""" #nosec
- % ", ".join(['%s']*len(paid_accrual_entries)), tuple(paid_accrual_entries))
-
- if self.partial_paid_entry:
- partial_paid_entry = json.loads(self.partial_paid_entry)
- frappe.db.set_value("Loan Interest Accrual", partial_paid_entry["name"], "interest_amount",
- partial_paid_entry["interest_amount"])
+ for payment in self.repayment_details:
+ frappe.db.sql(""" UPDATE `tabLoan Interest Accrual`
+ SET paid_principal_amount = `paid_principal_amount` - %s,
+ paid_interest_amount = `paid_interest_amount` - %s
+ WHERE name = %s""",
+ (payment.paid_principal_amount, payment.paid_interest_amount, payment.loan_interest_accrual))
frappe.db.sql(""" UPDATE `tabLoan` SET total_amount_paid = %s, total_principal_paid = %s
WHERE name = %s """, (loan.total_amount_paid - self.amount_paid,
@@ -139,6 +103,38 @@
if loan.status == "Loan Closure Requested":
frappe.db.set_value("Loan", self.against_loan, "status", "Disbursed")
+ def allocate_amounts(self, paid_entries):
+ self.set('repayment_details', [])
+ self.principal_amount_paid = 0
+
+ if self.amount_paid - self.penalty_amount > 0 and paid_entries:
+ interest_paid = self.amount_paid - self.penalty_amount
+ for lia, amounts in iteritems(paid_entries):
+ if amounts['interest_amount'] + amounts['payable_principal_amount'] <= interest_paid:
+ interest_amount = amounts['interest_amount']
+ paid_principal = amounts['payable_principal_amount']
+ self.principal_amount_paid += paid_principal
+ interest_paid -= (interest_amount + paid_principal)
+ elif interest_paid:
+ if interest_paid >= amounts['interest_amount']:
+ interest_amount = amounts['interest_amount']
+ paid_principal = interest_paid - interest_amount
+ self.principal_amount_paid += paid_principal
+ interest_paid = 0
+ else:
+ interest_amount = interest_paid
+ interest_paid = 0
+ paid_principal=0
+
+ self.append('repayment_details', {
+ 'loan_interest_accrual': lia,
+ 'paid_interest_amount': interest_amount,
+ 'paid_principal_amount': paid_principal
+ })
+
+ if interest_paid:
+ self.principal_amount_paid += interest_paid
+
def make_gl_entries(self, cancel=0, adv_adj=0):
gle_map = []
loan_details = frappe.get_doc("Loan", self.against_loan)
@@ -223,7 +219,7 @@
"posting_date": posting_date,
"applicant": applicant,
"penalty_amount": penalty_amount,
- "interst_payable": interest_payable,
+ "interest_payable": interest_payable,
"payable_principal_amount": payable_principal_amount,
"amount_paid": amount_paid,
"loan_type": loan_type
@@ -232,15 +228,22 @@
return lr
def get_accrued_interest_entries(against_loan):
- accrued_interest_entries = frappe.get_all("Loan Interest Accrual",
- fields=["name", "interest_amount", "posting_date", "payable_principal_amount"],
- filters = {
- "loan": against_loan,
- "is_paid": 0,
- "docstatus": 1
- }, order_by="posting_date")
- return accrued_interest_entries
+ unpaid_accrued_entries = frappe.db.sql(
+ """
+ SELECT name, posting_date, interest_amount - paid_interest_amount as interest_amount,
+ payable_principal_amount - paid_principal_amount as payable_principal_amount
+ FROM
+ `tabLoan Interest Accrual`
+ WHERE
+ loan = %s
+ AND (interest_amount - paid_interest_amount > 0 OR
+ payable_principal_amount - paid_principal_amount > 0)
+ AND
+ docstatus = 1
+ """, (against_loan), as_dict=1)
+
+ return unpaid_accrued_entries
# This function returns the amounts that are payable at the time of loan repayment based on posting date
# So it pulls all the unpaid Loan Interest Accrual Entries and calculates the penalty if applicable
@@ -273,8 +276,10 @@
total_pending_interest += entry.interest_amount
payable_principal_amount += entry.payable_principal_amount
- pending_accrual_entries.setdefault(entry.name,
- flt(entry.interest_amount) + flt(entry.payable_principal_amount))
+ pending_accrual_entries.setdefault(entry.name, {
+ 'interest_amount': flt(entry.interest_amount),
+ 'payable_principal_amount': flt(entry.payable_principal_amount)
+ })
final_due_date = due_date
@@ -291,7 +296,7 @@
amounts["interest_amount"] = total_pending_interest
amounts["penalty_amount"] = penalty_amount
amounts["payable_amount"] = payable_principal_amount + total_pending_interest + penalty_amount
- amounts["paid_accrual_entries"] = pending_accrual_entries
+ amounts["pending_accrual_entries"] = pending_accrual_entries
if final_due_date:
amounts["due_date"] = final_due_date
diff --git a/erpnext/loan_management/doctype/loan_repayment_detail/__init__.py b/erpnext/loan_management/doctype/loan_repayment_detail/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/loan_management/doctype/loan_repayment_detail/__init__.py
diff --git a/erpnext/loan_management/doctype/loan_repayment_detail/loan_repayment_detail.json b/erpnext/loan_management/doctype/loan_repayment_detail/loan_repayment_detail.json
new file mode 100644
index 0000000..cff1dbb
--- /dev/null
+++ b/erpnext/loan_management/doctype/loan_repayment_detail/loan_repayment_detail.json
@@ -0,0 +1,43 @@
+{
+ "actions": [],
+ "creation": "2020-04-15 18:31:54.026923",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "loan_interest_accrual",
+ "paid_principal_amount",
+ "paid_interest_amount"
+ ],
+ "fields": [
+ {
+ "fieldname": "loan_interest_accrual",
+ "fieldtype": "Link",
+ "label": "Loan Interest Accrual",
+ "options": "Loan Interest Accrual"
+ },
+ {
+ "fieldname": "paid_principal_amount",
+ "fieldtype": "Currency",
+ "label": "Paid Principal Amount",
+ "options": "Company:company:default_currency"
+ },
+ {
+ "fieldname": "paid_interest_amount",
+ "fieldtype": "Currency",
+ "label": "Paid Interest Amount",
+ "options": "Company:company:default_currency"
+ }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-15 21:50:03.837019",
+ "modified_by": "Administrator",
+ "module": "Loan Management",
+ "name": "Loan Repayment Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/loan_management/doctype/loan_repayment_detail/loan_repayment_detail.py b/erpnext/loan_management/doctype/loan_repayment_detail/loan_repayment_detail.py
new file mode 100644
index 0000000..a83b9b5
--- /dev/null
+++ b/erpnext/loan_management/doctype/loan_repayment_detail/loan_repayment_detail.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class LoanRepaymentDetail(Document):
+ pass
diff --git a/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json b/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json
index f7e2116..2f4fe24 100644
--- a/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json
+++ b/erpnext/loan_management/doctype/salary_slip_loan/salary_slip_loan.json
@@ -28,7 +28,6 @@
{
"fieldname": "loan_account",
"fieldtype": "Link",
- "in_list_view": 1,
"label": "Loan Account",
"options": "Account",
"read_only": 1
@@ -50,21 +49,23 @@
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Principal Amount",
- "options": "Company:company:default_currency"
+ "options": "Company:company:default_currency",
+ "read_only": 1
},
{
"fieldname": "interest_amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Interest Amount",
- "options": "Company:company:default_currency"
+ "options": "Company:company:default_currency",
+ "read_only": 1
},
{
"fieldname": "total_payment",
"fieldtype": "Currency",
+ "in_list_view": 1,
"label": "Total Payment",
- "options": "Company:company:default_currency",
- "read_only": 1
+ "options": "Company:company:default_currency"
},
{
"fieldname": "loan_repayment_entry",
@@ -84,7 +85,7 @@
],
"istable": 1,
"links": [],
- "modified": "2020-04-09 20:01:53.546364",
+ "modified": "2020-04-16 13:17:04.798335",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Salary Slip Loan",
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index f175687..7011cf9 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -287,7 +287,7 @@
if (in_list(['serial_no', 'batch_no'], field)) {
args[field] = value;
}
-
+
// add to cur_frm
const item = this.frm.add_child('items', args);
frappe.flags.hide_serial_batch_dialog = true;