From bf78ed6947ca32346384527d19a5fa6913b05cb4 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 16 Apr 2020 22:53:47 +0530 Subject: [PATCH] fix: Loan Repayment code clean up and other fixes --- erpnext/hr/doctype/salary_slip/salary_slip.py | 18 +-- .../loan_management/doctype/loan/test_loan.py | 80 +++------- .../loan_interest_accrual.json | 24 +-- .../loan_repayment/loan_repayment.json | 27 ++-- .../doctype/loan_repayment/loan_repayment.py | 147 +++++++++--------- .../doctype/loan_repayment_detail/__init__.py | 0 .../loan_repayment_detail.json | 43 +++++ .../loan_repayment_detail.py | 10 ++ .../salary_slip_loan/salary_slip_loan.json | 13 +- .../page/point_of_sale/point_of_sale.js | 2 +- 10 files changed, 191 insertions(+), 173 deletions(-) create mode 100644 erpnext/loan_management/doctype/loan_repayment_detail/__init__.py create mode 100644 erpnext/loan_management/doctype/loan_repayment_detail/loan_repayment_detail.json create mode 100644 erpnext/loan_management/doctype/loan_repayment_detail/loan_repayment_detail.py diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py index b3c803b564..223c4e3e3b 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/salary_slip.py @@ -776,22 +776,16 @@ class SalarySlip(TransactionBase): 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 108672b25a..2d1ad33ed0 100644 --- a/erpnext/loan_management/doctype/loan/test_loan.py +++ b/erpnext/loan_management/doctype/loan/test_loan.py @@ -149,13 +149,19 @@ class TestLoan(unittest.TestCase): 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 @@ class TestLoan(unittest.TestCase): 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 @@ class TestLoan(unittest.TestCase): 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 @@ class TestLoan(unittest.TestCase): 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 a26112011c..5fc3e8f4b6 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", @@ -101,13 +102,6 @@ "label": "Company", "options": "Company" }, - { - "default": "0", - "fieldname": "is_paid", - "fieldtype": "Check", - "label": "Is Paid", - "read_only": 1 - }, { "default": "0", "fetch_from": "loan.is_term_loan", @@ -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 4b930c50ae..789c129946 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": [ @@ -155,13 +154,6 @@ "options": "Company:company:default_currency", "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", @@ -197,13 +189,6 @@ "fieldname": "column_break_21", "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", @@ -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 2d2ca4c2f4..87e8a15ab4 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 @@ class LoanRepayment(AccountsController): 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 @@ class LoanRepayment(AccountsController): 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 @@ class LoanRepayment(AccountsController): 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 @@ class LoanRepayment(AccountsController): 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 @@ class LoanRepayment(AccountsController): 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 @@ def create_repayment_entry(loan, applicant, company, posting_date, loan_type, "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 @@ def create_repayment_entry(loan, applicant, company, posting_date, loan_type, 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 @@ def get_amounts(amounts, against_loan, posting_date, payment_type): 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 @@ def get_amounts(amounts, against_loan, posting_date, payment_type): 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 0000000000..e69de29bb2 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 0000000000..cff1dbb1d2 --- /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 0000000000..a83b9b5941 --- /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 f7e211656e..2f4fe24945 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 f175687f26..7011cf9804 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 @@ erpnext.pos.PointOfSale = class PointOfSale { 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;