Merge branch 'develop' into payment_reconciliation_enhancements_for_dr_or_cr_and_gain_or_loss
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index b7f383f..b6c48c8 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -228,6 +228,10 @@
frappe.model.validate_missing(jvd, "account");
var party_account_field = jvd.reference_type==="Sales Invoice" ? "debit_to": "credit_to";
out.filters.push([jvd.reference_type, party_account_field, "=", jvd.account]);
+
+ if (in_list(['Debit Note', 'Credit Note'], doc.voucher_type)) {
+ out.filters.push([jvd.reference_type, "is_return", "=", 1]);
+ }
}
if(in_list(["Sales Order", "Purchase Order"], jvd.reference_type)) {
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index d082b60..3132c93 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -331,7 +331,8 @@
for reference_name, total in iteritems(self.reference_totals):
reference_type = self.reference_types[reference_name]
- if reference_type in ("Sales Invoice", "Purchase Invoice"):
+ if (reference_type in ("Sales Invoice", "Purchase Invoice") and
+ self.voucher_type not in ['Debit Note', 'Credit Note']):
invoice = frappe.db.get_value(reference_type, reference_name,
["docstatus", "outstanding_amount"], as_dict=1)
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 92803a6..ea76126 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -535,6 +535,20 @@
"amount": self.total_allocated_amount * (tax_details['tax']['rate'] / 100)
}
+ def set_gain_or_loss(self, account_details=None):
+ if not self.difference_amount:
+ self.set_difference_amount()
+
+ row = {
+ 'amount': self.difference_amount
+ }
+
+ if account_details:
+ row.update(account_details)
+
+ self.append('deductions', row)
+ self.set_unallocated_amount()
+
@frappe.whitelist()
def get_outstanding_reference_documents(args):
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
index 4c24a9f..df31cde 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
@@ -16,6 +16,20 @@
})[0].outstanding_amount;
frappe.model.set_value(cdt, cdn, "allocated_amount", Math.min(invoice_amount, row.amount));
+
+ frm.call({
+ doc: frm.doc,
+ method: 'get_difference_amount',
+ args: {
+ child_row: row
+ },
+ callback: function(r, rt) {
+ if(r.message) {
+ frappe.model.set_value(cdt, cdn,
+ "difference_amount", r.message);
+ }
+ }
+ });
}
}
});
@@ -104,6 +118,91 @@
reconcile: function() {
var me = this;
+ var show_dialog = me.frm.doc.payments.filter(d => d.difference_amount && !d.difference_account);
+
+ if (show_dialog && show_dialog.length) {
+
+ this.data = [];
+ const dialog = new frappe.ui.Dialog({
+ title: __("Select Difference Account"),
+ fields: [
+ {
+ fieldname: "payments", fieldtype: "Table", label: __("Payments"),
+ data: this.data, in_place_edit: true,
+ get_data: () => {
+ return this.data;
+ },
+ fields: [{
+ fieldtype:'Data',
+ fieldname:"docname",
+ in_list_view: 1,
+ hidden: 1
+ }, {
+ fieldtype:'Data',
+ fieldname:"reference_name",
+ label: __("Voucher No"),
+ in_list_view: 1,
+ read_only: 1
+ }, {
+ fieldtype:'Link',
+ options: 'Account',
+ in_list_view: 1,
+ label: __("Difference Account"),
+ fieldname: 'difference_account',
+ reqd: 1,
+ get_query: function() {
+ return {
+ filters: {
+ company: me.frm.doc.company,
+ is_group: 0
+ }
+ }
+ }
+ }, {
+ fieldtype:'Currency',
+ in_list_view: 1,
+ label: __("Difference Amount"),
+ fieldname: 'difference_amount',
+ read_only: 1
+ }]
+ },
+ ],
+ primary_action: function() {
+ const args = dialog.get_values()["payments"];
+
+ args.forEach(d => {
+ frappe.model.set_value("Payment Reconciliation Payment", d.docname,
+ "difference_account", d.difference_account);
+ })
+
+ me.reconcile_payment_entries();
+ dialog.hide();
+ },
+ primary_action_label: __('Reconcile Entries')
+ });
+
+ this.frm.doc.payments.forEach(d => {
+ if (d.difference_amount && !d.difference_account) {
+ dialog.fields_dict.payments.df.data.push({
+ 'docname': d.name,
+ 'reference_name': d.reference_name,
+ 'difference_amount': d.difference_amount,
+ 'difference_account': d.difference_account,
+ });
+ }
+ });
+
+ this.data = dialog.fields_dict.payments.df.data;
+ dialog.fields_dict.payments.grid.refresh();
+ dialog.show();
+ } else {
+ this.reconcile_payment_entries();
+ }
+ },
+
+ reconcile_payment_entries: function() {
+ var me = this;
+
return this.frm.call({
doc: me.frm.doc,
method: 'reconcile',
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index a625494..b74eed5 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -3,10 +3,11 @@
from __future__ import unicode_literals
import frappe, erpnext
-from frappe.utils import flt
+from frappe.utils import flt, today
from frappe import msgprint, _
from frappe.model.document import Document
-from erpnext.accounts.utils import get_outstanding_invoices
+from erpnext.accounts.utils import (get_outstanding_invoices,
+ update_reference_in_payment_entry, reconcile_against_document)
from erpnext.controllers.accounts_controller import get_advance_payment_entries
class PaymentReconciliation(Document):
@@ -20,7 +21,10 @@
payment_entries = self.get_payment_entries()
journal_entries = self.get_jv_entries()
- self.add_payment_entries(payment_entries + journal_entries)
+ if self.party_type in ["Customer", "Supplier"]:
+ dr_or_cr_notes = self.get_dr_or_cr_notes()
+
+ self.add_payment_entries(payment_entries + journal_entries + dr_or_cr_notes)
def get_payment_entries(self):
order_doctype = "Sales Order" if self.party_type=="Customer" else "Purchase Order"
@@ -71,6 +75,34 @@
return list(journal_entries)
+ def get_dr_or_cr_notes(self):
+ dr_or_cr = ("credit_in_account_currency"
+ if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
+
+ reconciled_dr_or_cr = ("debit_in_account_currency"
+ if dr_or_cr == "credit_in_account_currency" else "credit_in_account_currency")
+
+ voucher_type = ('Sales Invoice'
+ if self.party_type == 'Customer' else "Purchase Invoice")
+
+ return frappe.db.sql(""" SELECT `tab{doc}`.name as reference_name, %(voucher_type)s as reference_type,
+ (sum(`tabGL Entry`.{dr_or_cr}) - sum(`tabGL Entry`.{reconciled_dr_or_cr})) as amount
+ FROM `tab{doc}`, `tabGL Entry`
+ WHERE
+ (`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
+ and `tab{doc}`.is_return = 1 and `tabGL Entry`.against_voucher_type = %(voucher_type)s
+ and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s
+ and `tabGL Entry`.party_type = %(party_type)s and `tabGL Entry`.account = %(account)s
+ GROUP BY `tabSales Invoice`.name
+ Having
+ amount > 0
+ """.format(doc=voucher_type, dr_or_cr=dr_or_cr, reconciled_dr_or_cr=reconciled_dr_or_cr), {
+ 'party': self.party,
+ 'party_type': self.party_type,
+ 'voucher_type': voucher_type,
+ 'account': self.receivable_payable_account
+ }, as_dict=1)
+
def add_payment_entries(self, entries):
self.set('payments', [])
for e in entries:
@@ -114,36 +146,67 @@
if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
lst = []
+ dr_or_cr_notes = []
for e in self.get('payments'):
+ reconciled_entry = []
if e.invoice_number and e.allocated_amount:
- lst.append(frappe._dict({
- 'voucher_type': e.reference_type,
- 'voucher_no' : e.reference_name,
- 'voucher_detail_no' : e.reference_row,
- 'against_voucher_type' : e.invoice_type,
- 'against_voucher' : e.invoice_number,
- 'account' : self.receivable_payable_account,
- 'party_type': self.party_type,
- 'party': self.party,
- 'is_advance' : e.is_advance,
- 'dr_or_cr' : dr_or_cr,
- 'unadjusted_amount' : flt(e.amount),
- 'allocated_amount' : flt(e.allocated_amount)
- }))
+ if e.reference_type in ['Sales Invoice', 'Purchase Invoice']:
+ reconciled_entry = dr_or_cr_notes
+ else:
+ reconciled_entry = lst
+
+ reconciled_entry.append(self.get_payment_details(e, dr_or_cr))
if lst:
- from erpnext.accounts.utils import reconcile_against_document
reconcile_against_document(lst)
- msgprint(_("Successfully Reconciled"))
- self.get_unreconciled_entries()
+ if dr_or_cr_notes:
+ reconcile_dr_cr_note(dr_or_cr_notes)
+
+ msgprint(_("Successfully Reconciled"))
+ self.get_unreconciled_entries()
+
+ def get_payment_details(self, row, dr_or_cr):
+ return frappe._dict({
+ 'voucher_type': row.reference_type,
+ 'voucher_no' : row.reference_name,
+ 'voucher_detail_no' : row.reference_row,
+ 'against_voucher_type' : row.invoice_type,
+ 'against_voucher' : row.invoice_number,
+ 'account' : self.receivable_payable_account,
+ 'party_type': self.party_type,
+ 'party': self.party,
+ 'is_advance' : row.is_advance,
+ 'dr_or_cr' : dr_or_cr,
+ 'unadjusted_amount' : flt(row.amount),
+ 'allocated_amount' : flt(row.allocated_amount),
+ 'difference_amount': row.difference_amount,
+ 'difference_account': row.difference_account
+ })
+
+ def get_difference_amount(self, child_row):
+ if child_row.get("reference_type") != 'Payment Entry': return
+
+ child_row = frappe._dict(child_row)
+
+ if child_row.invoice_number and " | " in child_row.invoice_number:
+ child_row.invoice_type, child_row.invoice_number = child_row.invoice_number.split(" | ")
+
+ dr_or_cr = ("credit_in_account_currency"
+ if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
+
+ row = self.get_payment_details(child_row, dr_or_cr)
+
+ doc = frappe.get_doc(row.voucher_type, row.voucher_no)
+ update_reference_in_payment_entry(row, doc, do_not_save=True)
+
+ return doc.difference_amount
def check_mandatory_to_fetch(self):
for fieldname in ["company", "party_type", "party", "receivable_payable_account"]:
if not self.get(fieldname):
frappe.throw(_("Please select {0} first").format(self.meta.get_label(fieldname)))
-
def validate_invoice(self):
if not self.get("invoices"):
frappe.throw(_("No records found in the Invoice table"))
@@ -188,3 +251,41 @@
cond += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_amount))
return cond
+
+def reconcile_dr_cr_note(dr_cr_notes):
+ for d in dr_cr_notes:
+ voucher_type = ('Credit Note'
+ if d.voucher_type == 'Sales Invoice' else 'Debit Note')
+
+ dr_or_cr = ('credit_in_account_currency'
+ if d.reference_type == 'Sales Invoice' else 'debit_in_account_currency')
+
+ reconcile_dr_or_cr = ('debit_in_account_currency'
+ if dr_or_cr == 'credit_in_account_currency' else 'credit_in_account_currency')
+
+ jv = frappe.get_doc({
+ "doctype": "Journal Entry",
+ "voucher_type": voucher_type,
+ "posting_date": today(),
+ "accounts": [
+ {
+ 'account': d.account,
+ 'party': d.party,
+ 'party_type': d.party_type,
+ reconcile_dr_or_cr: (abs(d.allocated_amount)
+ if abs(d.unadjusted_amount) > abs(d.allocated_amount) else abs(d.unadjusted_amount)),
+ 'reference_type': d.against_voucher_type,
+ 'reference_name': d.against_voucher
+ },
+ {
+ 'account': d.account,
+ 'party': d.party,
+ 'party_type': d.party_type,
+ dr_or_cr: abs(d.allocated_amount),
+ 'reference_type': d.voucher_type,
+ 'reference_name': d.voucher_no
+ }
+ ]
+ })
+
+ jv.submit()
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
index 814257c..018bfd0 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
@@ -1,389 +1,127 @@
{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2014-07-09 16:13:35.452759",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
+ "creation": "2014-07-09 16:13:35.452759",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "field_order": [
+ "reference_type",
+ "reference_name",
+ "posting_date",
+ "is_advance",
+ "reference_row",
+ "col_break1",
+ "invoice_number",
+ "amount",
+ "allocated_amount",
+ "section_break_10",
+ "difference_account",
+ "difference_amount",
+ "sec_break1",
+ "remark"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reference_type",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Reference Type",
- "length": 0,
- "no_copy": 0,
- "options": "DocType",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "reference_type",
+ "fieldtype": "Link",
+ "label": "Reference Type",
+ "options": "DocType",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 3,
- "fieldname": "reference_name",
- "fieldtype": "Dynamic Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Reference Name",
- "length": 0,
- "no_copy": 0,
- "options": "reference_type",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "columns": 2,
+ "fieldname": "reference_name",
+ "fieldtype": "Dynamic Link",
+ "in_list_view": 1,
+ "label": "Reference Name",
+ "options": "reference_type",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "posting_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Posting Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "label": "Posting Date",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_advance",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Advance",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "is_advance",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Is Advance",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reference_row",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Reference Row",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "reference_row",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Reference Row",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "col_break1",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "col_break1",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 3,
- "fieldname": "invoice_number",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Invoice Number",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "columns": 2,
+ "fieldname": "invoice_number",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Invoice Number",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 2,
- "fieldname": "amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Amount",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "columns": 2,
+ "fieldname": "amount",
+ "fieldtype": "Currency",
+ "in_list_view": 1,
+ "label": "Amount",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 2,
- "fieldname": "allocated_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Allocated amount",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "columns": 2,
+ "fieldname": "allocated_amount",
+ "fieldtype": "Currency",
+ "in_list_view": 1,
+ "label": "Allocated amount",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sec_break1",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "sec_break1",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "remark",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Remark",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "remark",
+ "fieldtype": "Small Text",
+ "in_list_view": 1,
+ "label": "Remark",
+ "read_only": 1
+ },
+ {
+ "columns": 2,
+ "fieldname": "difference_account",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Difference Account",
+ "options": "Account"
+ },
+ {
+ "fieldname": "difference_amount",
+ "fieldtype": "Currency",
+ "label": "Difference Amount",
+ "print_hide": 1,
+ "read_only": 1
+ },
+ {
+ "fieldname": "section_break_10",
+ "fieldtype": "Section Break"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "menu_index": 0,
- "modified": "2019-01-07 16:52:07.567027",
- "modified_by": "Administrator",
- "module": "Accounts",
- "name": "Payment Reconciliation Payment",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "istable": 1,
+ "modified": "2019-06-24 00:08:11.150796",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payment Reconciliation Payment",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC"
}
\ No newline at end of file
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 7a230a7..7a1f6c5 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -435,7 +435,7 @@
jv_obj.flags.ignore_validate_update_after_submit = True
jv_obj.save(ignore_permissions=True)
-def update_reference_in_payment_entry(d, payment_entry):
+def update_reference_in_payment_entry(d, payment_entry, do_not_save=False):
reference_details = {
"reference_doctype": d.against_voucher_type,
"reference_name": d.against_voucher,
@@ -466,7 +466,17 @@
payment_entry.setup_party_account_field()
payment_entry.set_missing_values()
payment_entry.set_amounts()
- payment_entry.save(ignore_permissions=True)
+
+ if d.difference_amount and d.difference_account:
+ payment_entry.set_gain_or_loss(account_details={
+ 'account': d.difference_account,
+ 'cost_center': payment_entry.cost_center or frappe.get_cached_value('Company',
+ payment_entry.company, "cost_center"),
+ 'amount': d.difference_amount
+ })
+
+ if not do_not_save:
+ payment_entry.save(ignore_permissions=True)
def unlink_ref_doc_from_payment_entries(ref_doc):
remove_ref_doc_link_from_jv(ref_doc.doctype, ref_doc.name)