From 12e2a51519b2782e47ac97281024286a0d3e800a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Sun, 26 Jun 2016 01:37:21 +0530 Subject: [PATCH] [new][feature] Payment Entry --- .../accounts_settings/accounts_settings.json | 51 +- .../doctype/journal_entry/journal_entry.py | 3 +- .../mode_of_payment/mode_of_payment.js | 3 +- .../doctype/payment_entry/__init__.py | 0 .../doctype/payment_entry/payment_entry.js | 523 ++++++ .../doctype/payment_entry/payment_entry.json | 1475 +++++++++++++++++ .../doctype/payment_entry/payment_entry.py | 329 ++++ .../payment_entry/test_payment_entry.py | 12 + .../payment_entry_deduction/__init__.py | 0 .../payment_entry_deduction.json | 113 ++ .../payment_entry_deduction.py | 10 + .../payment_entry_reference/__init__.py | 0 .../payment_entry_reference.json | 237 +++ .../payment_entry_reference.py | 10 + erpnext/accounts/utils.py | 8 +- erpnext/controllers/accounts_controller.py | 6 +- erpnext/setup/doctype/company/company.js | 1 + erpnext/setup/doctype/company/company.json | 29 +- 18 files changed, 2800 insertions(+), 10 deletions(-) create mode 100644 erpnext/accounts/doctype/payment_entry/__init__.py create mode 100644 erpnext/accounts/doctype/payment_entry/payment_entry.js create mode 100644 erpnext/accounts/doctype/payment_entry/payment_entry.json create mode 100644 erpnext/accounts/doctype/payment_entry/payment_entry.py create mode 100644 erpnext/accounts/doctype/payment_entry/test_payment_entry.py create mode 100644 erpnext/accounts/doctype/payment_entry_deduction/__init__.py create mode 100644 erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json create mode 100644 erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py create mode 100644 erpnext/accounts/doctype/payment_entry_reference/__init__.py create mode 100644 erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json create mode 100644 erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index d46c2d56067..aca83dad791 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -87,6 +87,55 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_4", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "allow_payment_entry_via_journal_entry", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Allow Payment Entry via Journal Entry", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -150,7 +199,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2016-06-27 15:18:27.566087", + "modified": "2016-06-27 15:18:28.566087", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 40386e088aa..9ff64eb9c67 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -814,7 +814,7 @@ def get_exchange_rate(account, account_currency=None, company=None, company_currency = get_company_currency(company) if account_currency != company_currency: - if reference_type and reference_name and frappe.get_meta(reference_type).get_field("conversion_rate"): + if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name: exchange_rate = frappe.db.get_value(reference_type, reference_name, "conversion_rate") elif account_details and account_details.account_type == "Bank" and \ @@ -831,6 +831,7 @@ def get_exchange_rate(account, account_currency=None, company=None, # don't return None or 0 as it is multipled with a value and that value could be lost return exchange_rate or 1 +@frappe.whitelist() def get_average_exchange_rate(account): exchange_rate = 0 bank_balance_in_account_currency = get_balance_on(account) diff --git a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.js b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.js index 10807ff8700..9115c208688 100644 --- a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.js +++ b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.js @@ -2,11 +2,12 @@ // License: GNU General Public License v3. See license.txt cur_frm.set_query("default_account", "accounts", function(doc, cdt, cdn) { + var d = locals[cdt][cdn]; return{ filters: [ ['Account', 'account_type', 'in', 'Bank, Cash'], ['Account', 'is_group', '=', 0], - ['Account', 'company', '=', doc.company] + ['Account', 'company', '=', d.company] ] } }); diff --git a/erpnext/accounts/doctype/payment_entry/__init__.py b/erpnext/accounts/doctype/payment_entry/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js new file mode 100644 index 00000000000..826f2360f2e --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -0,0 +1,523 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Payment Entry', { + onload: function(frm) { + frm.set_value("paid_from_account_currency", null); + frm.set_value("paid_from_account_currency", null); + }, + + setup: function(frm) { + frm.get_field('references').grid.editable_fields = [ + {fieldname: 'reference_doctype', columns: 2}, + {fieldname: 'reference_name', columns: 3}, + {fieldname: 'outstanding_amount', columns: 3}, + {fieldname: 'allocated_amount', columns: 3} + ]; + + var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable"; + + frm.set_query("paid_from", function() { + var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ? + ["Bank", "Cash"] : party_account_type; + + return { + filters: { + "account_type": ["in", account_types], + "is_group": 0, + "company": frm.doc.company + } + } + }); + + frm.set_query("paid_to", function() { + var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ? + ["Bank", "Cash"] : party_account_type; + + return { + filters: { + "account_type": ["in", account_types], + "is_group": 0, + "company": frm.doc.company + } + } + }); + + frm.set_query("account", "deductions", function() { + return { + filters: { + "is_group": 0, + "company": frm.doc.company + } + } + }); + + frm.set_query("cost_center", "deductions", function() { + return { + filters: { + "is_group": 0, + "company": frm.doc.company + } + } + }); + + frm.set_query("reference_doctype", "references", function() { + if (frm.doc.party_type=="Customer") { + var doctypes = ["Sales Order", "Sales Invoice", "Journal Entry"]; + } else if (frm.doc.party_type=="Supplier") { + var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"]; + } else { + var doctypes = ["Journal Entry"]; + } + + return { + filters: { "name": ["in", doctypes] } + }; + }); + }, + + refresh: function(frm) { + frm.events.hide_unhide_fields(frm); + frm.events.set_dynamic_labels(frm); + }, + + hide_unhide_fields: function(frm) { + var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; + + frm.toggle_display(["source_exchange_rate", "base_paid_amount"], + (frm.doc.paid_from && frm.doc.paid_from_account_currency != company_currency)); + + frm.toggle_display(["target_exchange_rate", "base_received_amount"], + (frm.doc.paid_to && frm.doc.paid_to_account_currency != company_currency)); + + frm.toggle_display(["base_total_allocated_amount"], + ((frm.doc.payment_type=="Receive" && frm.doc.paid_from_account_currency != company_currency) || + (frm.doc.payment_type=="Pay" && frm.doc.paid_to_account_currency != company_currency))); + + frm.toggle_display(["received_amount"], + frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency) + }, + + set_dynamic_labels: function(frm) { + var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; + + var field_label_map = {}; + var grid_field_label_map = {}; + + var setup_field_label_map = function(fields_list, currency, parentfield) { + var doctype = parentfield ? frm.fields_dict[parentfield].grid.doctype : frm.doc.doctype; + $.each(fields_list, function(i, fname) { + var docfield = frappe.meta.docfield_map[doctype][fname]; + if(docfield) { + var label = __(docfield.label || "").replace(/\([^\)]*\)/g, ""); + if(parentfield) { + grid_field_label_map[doctype + "-" + fname] = + label.trim() + " (" + __(currency) + ")"; + } else { + field_label_map[fname] = label.trim() + " (" + currency + ")"; + } + } + }); + } + + setup_field_label_map(["base_paid_amount", "base_received_amount", "base_total_allocated_amount", + "difference_amount"], company_currency); + + setup_field_label_map(["paid_amount"], frm.doc.paid_from_account_currency); + setup_field_label_map(["received_amount"], frm.doc.paid_to_account_currency); + + var party_account_currency = frm.doc.payment_type=="Receive" ? + frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency; + + setup_field_label_map(["total_allocated_amount"], party_account_currency); + + $.each(field_label_map, function(fname, label) { + me.frm.fields_dict[fname].set_label(label); + }); + + setup_field_label_map(["total_amount"], company_currency, "references"); + setup_field_label_map(["outstanding_amount", "allocated_amount"], + party_account_currency, "references"); + + $.each(grid_field_label_map, function(fname, label) { + fname = fname.split("-"); + var df = frappe.meta.get_docfield(fname[0], fname[1], me.frm.doc.name); + if(df) df.label = label; + }); + + cur_frm.set_df_property("source_exchange_rate", "description", + ("1 " + frm.doc.paid_from_account_currency + " = [?] " + company_currency)); + + cur_frm.set_df_property("target_exchange_rate", "description", + ("1 " + frm.doc.paid_to_account_currency + " = [?] " + company_currency)); + }, + + "party": function(frm) { + if(frm.doc.payment_type && frm.doc.party_type && frm.doc.party) { + frm.set_party_account_based_on_party = true; + + return frappe.call({ + method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_party_details", + args: { + company: frm.doc.company, + party_type: frm.doc.party_type, + party: frm.doc.party, + date: frm.doc.posting_date + }, + callback: function(r, rt) { + if(r.message) { + if(frm.doc.payment_type == "Receive") { + frm.set_value("paid_from", r.message.party_account); + frm.set_value("paid_from_account_currency", r.message.party_account_currency); + frm.set_value("paid_from_account_balance", r.message.account_balance); + } else if (frm.doc.payment_type == "Pay"){ + frm.set_value("paid_to", r.message.party_account); + frm.set_value("paid_to_account_currency", r.message.party_account_currency); + frm.set_value("paid_to_account_balance", r.message.account_balance); + } + frm.set_value("party_balance", r.message.party_balance); + frm.events.get_outstanding_documents(frm); + frm.events.hide_unhide_fields(frm); + frm.events.set_dynamic_labels(frm); + frm.set_party_account_based_on_party = false; + } + } + }); + } + }, + + payment_type: function(frm) { + if(frm.doc.payment_type == "Internal Transfer") { + $.each(["party", "party_balance", "paid_from", "paid_to", + "references", "total_allocated_amount"], function(i, field) { + frm.set_value(field, ""); + }) + } else { + frm.events.party(frm); + } + }, + + "mode_of_payment": function(frm) { + return frappe.call({ + method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account", + args: { + "mode_of_payment": frm.doc.mode_of_payment, + "company": frm.doc.company + }, + callback: function(r, rt) { + if(r.message) { + var payment_account_field = frm.doc.payment_type == "Receive" ? "paid_to" : "paid_from"; + frm.set_value(payment_account_field, r.message['account']); + } + } + }); + }, + + paid_from: function(frm) { + if(frm.set_party_account_based_on_party) return; + + frm.events.set_account_currency_and_balance(frm, frm.doc.paid_from, + "paid_from_account_currency", "paid_from_account_balance", function() { + if(frm.doc.payment_type == "Receive") frm.events.get_outstanding_documents(frm); + } + ); + }, + + paid_to: function(frm) { + if(frm.set_party_account_based_on_party) return; + + frm.events.set_account_currency_and_balance(frm, frm.doc.paid_to, + "paid_to_account_currency", "paid_to_account_balance", function() { + if(frm.doc.payment_type == "Pay") frm.events.get_outstanding_documents(frm); + } + ); + }, + + set_account_currency_and_balance: function(frm, account, currency_field, + balance_field, callback_function) { + frappe.call({ + method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_account_currency_and_balance", + args: { + "account": account, + "date": frm.doc.posting_date + }, + callback: function(r, rt) { + if(r.message) { + frm.set_value(currency_field, r.message['account_currency']); + frm.set_value(balance_field, r.message['account_balance']); + + if(callback_function) callback_function() + + frm.events.hide_unhide_fields(frm); + frm.events.set_dynamic_labels(frm); + } + } + }); + }, + + paid_from_account_currency: function(frm) { + var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; + + if (frm.doc.paid_from_account_currency == company_currency) { + frm.set_value("source_exchange_rate", 1); + } else if (frm.doc.paid_from){ + if (in_list(["Internal Transfer", "Pay"], frm.doc.payment_type)) { + frappe.call({ + method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_average_exchange_rate", + args: { + account: frm.doc.paid_from + }, + callback: function(r, rt) { + frm.set_value("source_exchange_rate", r.message); + } + }) + } else { + frm.events.set_current_exchange_rate(frm, "source_exchange_rate", + frm.doc.paid_from_account_currency, company_currency); + } + } + }, + + paid_to_account_currency: function(frm) { + var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; + + frm.events.set_current_exchange_rate(frm, "target_exchange_rate", + frm.doc.paid_to_account_currency, company_currency); + }, + + set_current_exchange_rate: function(frm, exchange_rate_field, from_currency, to_currency) { + frappe.call({ + method: "erpnext.setup.utils.get_exchange_rate", + args: { + from_currency: from_currency, + to_currency: to_currency + }, + callback: function(r, rt) { + frm.set_value(exchange_rate_field, r.message); + } + }) + }, + + source_exchange_rate: function(frm) { + if (frm.doc.paid_amount) { + frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate)); + } + }, + + target_exchange_rate: function(frm) { + if (frm.doc.received_amount) { + frm.set_value("base_received_amount", + flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate)); + } + }, + + paid_amount: function(frm) { + frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate)); + + if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) { + frm.set_value("received_amount", frm.doc.paid_amount); + frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate); + frm.set_value("base_received_amount", frm.doc.base_paid_amount); + } + + frm.events.set_difference_amount(frm); + }, + + received_amount: function(frm) { + frm.set_value("base_received_amount", + flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate)); + frm.events.set_difference_amount(frm); + }, + + get_outstanding_documents: function(frm) { + frm.events.check_mandatory_to_fetch(frm); + var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; + + frm.clear_table("references"); + + return frappe.call({ + method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_outstanding_reference_documents', + args: { + args: { + "company": frm.doc.company, + "party_type": frm.doc.party_type, + "payment_type": frm.doc.payment_type, + "party": frm.doc.party, + "party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to + } + }, + callback: function(r, rt) { + if(r.message) { + $.each(r.message, function(i, d) { + var c = frm.add_child("references"); + c.reference_doctype = d.voucher_type; + c.reference_name = d.voucher_no; + c.total_amount = d.invoice_amount; + c.outstanding_amount = d.outstanding_amount; + + if(frm.doc.party_account_currency != company_currency) { + c.exchange_rate = d.exchange_rate; + } else { + c.exchange_rate = 1; + } + + if (in_list(['Sales Invoice', 'Purchase Invoice'], d.reference_doctype)){ + c.due_date = d.due_date + } + }); + } + frm.events.set_total_allocated_amount(frm); + frm.refresh_fields() + } + }); + }, + + set_total_allocated_amount: function(frm) { + var total_allocated_amount = base_total_allocated_amount = 0.0; + $.each(frm.doc.references || [], function(i, row) { + if (row.allocated_amount) { + if (flt(row.allocated_amount) <= row.outstanding_amount) { + total_allocated_amount += flt(row.allocated_amount); + base_total_allocated_amount += flt(flt(row.allocated_amount)*flt(row.exchange_rate), + precision("base_paid_amount")); + } else { + if(flt(row.allocated_amount) < 0) + frappe.throw(__("Row {0}: Allocated amount can not be negative", [row.idx])); + else if(flt(row.allocated_amount) > flt(row.outstanding_amount)) + frappe.throw(__("Row {0}: Allocated Amount cannot be greater than Outstanding Amount", + [__(row.idx)])); + + frappe.model.set_value(row.doctype, row.name, "allocated_amount", 0.0); + } + } + }); + frm.set_value("total_allocated_amount", total_allocated_amount); + frm.set_value("base_total_allocated_amount", base_total_allocated_amount); + + frm.events.set_difference_amount(frm); + }, + + set_difference_amount: function(frm) { + var unallocated_amount = 0; + var party_amount = frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount; + + if(frm.doc.total_allocated_amount < party_amount) + unallocated_amount = party_amount - frm.doc.total_allocated_amount; + + frm.set_value("unallocated_amount", unallocated_amount) + + var difference_amount = 0; + var base_unallocated_amount = flt(frm.doc.unallocated_amount) * + (frm.doc.payment_type=="Receive" ? frm.doc.source_exchange_rate : frm.doc.target_exchange_rate); + + var base_party_amount = flt(frm.doc.base_total_allocated_amount) + base_unallocated_amount; + + if(frm.doc.payment_type == "Receive") { + difference_amount = base_party_amount - flt(frm.doc.base_received_amount); + } else if (frm.doc.payment_type == "Pay") { + difference_amount = flt(frm.doc.base_paid_amount) - base_party_amount; + } else { + difference_amount = flt(frm.doc.base_paid_amount) - flt(frm.doc.base_received_amount); + } + + $.each(frm.doc.deductions || [], function(i, d) { + if(d.amount) difference_amount -= flt(d.amount); + }) + + frm.set_value("difference_amount", difference_amount); + + frm.toggle_display("write_off_difference_amount", + (frm.doc.difference_amount && frm.doc.total_allocated_amount > party_amount)); + }, + + check_mandatory_to_fetch: function(frm) { + $.each(["Company", "Party Type", "Party", "payment_type"], function(i, field) { + if(!frm.doc[frappe.model.scrub(field)]) frappe.throw(__("Please select {0} first", [field])); + }); + }, + + validate_reference_document: function(frm, row) { + var _validate = function(i, row) { + if (!row.reference_doctype) { + return; + } + + if(frm.doc.party_type=="Customer" + && !in_list(["Sales Order", "Sales Invoice", "Journal Entry"], row.reference_doctype)) { + frappe.model.set_value(row.doctype, row.name, "reference_doctype", null); + frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Sales Order, Sales Invoice or Journal Entry", [row.idx])); + return false; + } + + if(frm.doc.party_type=="Supplier" && !in_list(["Purchase Order", + "Purchase Invoice", "Journal Entry"], row.reference_doctype)) { + frappe.model.set_value(row.doctype, row.name, "against_voucher_type", null); + frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Purchase Order, Purchase Invoice or Journal Entry", [row.idx])); + return false; + } + + } + + if (row) { + _validate(0, row); + } else { + $.each(frm.doc.vouchers || [], _validate); + } + }, + + write_off_difference_amount: function(frm) { + if(frm.doc.difference_amount) { + frappe.call({ + method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_write_off_account_and_cost_center", + args: { + company: frm.doc.company + }, + callback: function(r, rt) { + if(r.message) { + var write_off_row = $.map(frm.doc["deductions"] || [], function(t) { + return t.account==r.message["write_off_account"] ? t : null; }); + + if (!write_off_row.length) { + var row = frm.add_child("deductions"); + row.account = r.message["write_off_account"]; + row.cost_center = r.message["cost_center"]; + } else { + var row = write_off_row[0]; + } + + row.amount = flt(row.amount) + flt(frm.doc.difference_amount); + refresh_field("deductions"); + + frm.events.set_difference_amount(frm); + } + } + }) + } + } +}); + + +frappe.ui.form.on('Payment Entry Reference', { + reference_doctype: function(frm, cdt, cdn) { + var row = locals[cdt][cdn]; + frm.events.validate_reference_document(frm, row); + }, + + allocated_amount: function(frm) { + frm.events.set_total_allocated_amount(frm); + }, + + references_remove: function(frm) { + frm.events.set_total_allocated_amount(frm); + } +}) + +frappe.ui.form.on('Payment Entry Deduction', { + amount: function(frm) { + frm.events.set_difference_amount(frm); + }, + + deductions_remove: function(frm) { + frm.events.set_difference_amount(frm); + } +}) \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json new file mode 100644 index 00000000000..5994aa352be --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -0,0 +1,1475 @@ +{ + "allow_copy": 0, + "allow_import": 1, + "allow_rename": 0, + "autoname": "naming_series:", + "beta": 0, + "creation": "2016-06-01 14:38:51.012597", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "fields": [ + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "fieldname": "naming_series", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Series", + "length": 0, + "no_copy": 0, + "options": "PE-", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "fieldname": "payment_type", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Type", + "length": 0, + "no_copy": 0, + "options": "Receive\nPay\nInternal Transfer", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_5", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "default": "Today", + "fieldname": "posting_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Posting Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "company", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Company", + "length": 0, + "no_copy": 0, + "options": "Company", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "mode_of_payment", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Mode of Payment", + "length": 0, + "no_copy": 0, + "options": "Mode of Payment", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)", + "fieldname": "party_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)", + "fieldname": "party_type", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Party Type", + "length": 0, + "no_copy": 0, + "options": "Customer\nSupplier", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_10", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type", + "fieldname": "party", + "fieldtype": "Dynamic Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Party", + "length": 0, + "no_copy": 0, + "options": "party_type", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "party", + "fieldname": "party_balance", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Party Balance", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "payment_accounts_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "depends_on": "eval:(in_list([\"Internal Transfer\", \"Pay\"], doc.payment_type) || doc.party)", + "fieldname": "paid_from", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Account Paid From", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "paid_from", + "fieldname": "paid_from_account_currency", + "fieldtype": "Link", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Account Currency", + "length": 0, + "no_copy": 0, + "options": "Currency", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "paid_from", + "fieldname": "paid_from_account_balance", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Account Balance", + "length": 0, + "no_copy": 0, + "options": "paid_from_account_currency", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_18", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:(in_list([\"Internal Transfer\", \"Receive\"], doc.payment_type) || doc.party)", + "fieldname": "paid_to", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Account Paid To", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "paid_to", + "fieldname": "paid_to_account_balance", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Account Balance", + "length": 0, + "no_copy": 0, + "options": "paid_to_account_currency", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "paid_to", + "fieldname": "paid_to_account_currency", + "fieldtype": "Link", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Account Currency", + "length": 0, + "no_copy": 0, + "options": "Currency", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": "", + "depends_on": "eval:(doc.paid_to && doc.paid_from)", + "fieldname": "payment_amounts_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Amounts", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "depends_on": "", + "fieldname": "paid_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Paid Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "source_exchange_rate", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Exchange Rate", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "base_paid_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Paid Amount (Company Currency)", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_21", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "depends_on": "", + "fieldname": "received_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Received Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "target_exchange_rate", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Exchange Rate", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "base_received_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Received Amount (Company Currency)", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "transaction_references", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Transaction References", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "depends_on": "eval:(doc.paid_from && doc.paid_to)", + "fieldname": "reference_no", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Cheque/Reference No", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_23", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "depends_on": "eval:(doc.paid_from && doc.paid_to)", + "fieldname": "reference_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Cheque/Reference Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": "references", + "depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)", + "fieldname": "section_break_14", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Reference Documents", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "references", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment References", + "length": 0, + "no_copy": 0, + "options": "Payment Entry Reference", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "section_break_34", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 1, + "collapsible": 0, + "depends_on": "", + "fieldname": "total_allocated_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Total Allocated Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "base_total_allocated_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Total Allocated Amount (Company Currency)", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "difference_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Difference Amount (Company Currency)", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "difference_amount", + "fieldname": "write_off_difference_amount", + "fieldtype": "Button", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Write Off Difference Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_36", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "unallocated_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Unallocated Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": "deductions", + "depends_on": "eval:(doc.paid_amount && doc.received_amount)", + "fieldname": "deductions_or_loss_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Deductions or Loss", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "deductions", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Deductions or Loss", + "length": 0, + "no_copy": 0, + "options": "Payment Entry Deduction", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": "write_off_amount", + "depends_on": "difference_amount", + "fieldname": "write_off_section", + "fieldtype": "Section Break", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Write Off", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "write_off_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Write Off Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "write_off_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Write Off Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_39", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "write_off_cost_center", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Write Off Cost Center", + "length": 0, + "no_copy": 0, + "options": "Cost Center", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": "", + "depends_on": "eval:(doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)", + "fieldname": "section_break_12", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "More Information", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "", + "fieldname": "project", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Project", + "length": 0, + "no_copy": 0, + "options": "Project", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "remarks", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Remarks", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_16", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "letter_head", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Letter Head", + "length": 0, + "no_copy": 0, + "options": "Letter Head", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "print_heading", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Print Heading", + "length": 0, + "no_copy": 0, + "options": "Print Heading", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "amended_from", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Amended From", + "length": 0, + "no_copy": 1, + "options": "Payment Entry", + "permlevel": 0, + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 1, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2016-06-26 01:00:56.344341", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Payment Entry", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 1, + "apply_user_permissions": 0, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "set_user_permissions": 0, + "share": 1, + "submit": 1, + "write": 1 + }, + { + "amend": 1, + "apply_user_permissions": 0, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 1, + "write": 1 + } + ], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py new file mode 100644 index 00000000000..30848d87aae --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -0,0 +1,329 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe, json +from frappe import _, scrub +from frappe.utils import flt +from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on +from erpnext.accounts.party import get_party_account +from erpnext.accounts.doctype.journal_entry.journal_entry import get_average_exchange_rate +from erpnext.setup.utils import get_exchange_rate +from erpnext.accounts.general_ledger import make_gl_entries + +from erpnext.controllers.accounts_controller import AccountsController + + +class PaymentEntry(AccountsController): + def validate(self): + self.set_missing_values() + self.validate_party_details() + self.validate_allocated_amounts() + self.set_exchange_rate() + self.set_amounts() + self.validate_mandatory() + self.set_write_off_amount() + + def on_submit(self): + self.make_gl_entries() + self.update_advance_paid() + + def on_cancel(self): + self.make_gl_entries() + self.update_advance_paid() + + def set_missing_values(self): + if self.payment_type == "Receive": + self.paid_from = self.paid_from_account_currency = self.paid_from_account_balance = None + elif self.payment_type == "Pay": + self.paid_to = self.paid_to_account_currency = self.paid_to_account_balance = None + elif self.payment_type == "Internal Transfer": + self.party = self.party_account = self.party_account_currency = self.party_balance = None + + if self.party: + if self.party_account: + if not self.party_account_currency: + self.party_account_currency = get_account_currency(self.party_account) + + if not self.party_balance: + self.party_balance = get_balance_on(party_type=self.party_type, + party=self.party, date=self.posting_date) + else: + self.party_account = get_party_account(self.party_type, self.party, self.company) + + if self.paid_from: + acc = get_account_currency_and_balance(self.paid_from, self.posting_date) + self.paid_from_account_currency = acc.account_currency + self.paid_from_account_balance = acc.account_balance + + if self.paid_to: + acc = get_account_currency_and_balance(self.paid_to, self.posting_date) + self.paid_to_account_currency = acc.account_currency + self.paid_to_account_balance = acc.account_balance + + def validate_party_details(self): + if self.party: + if not frappe.db.exists(self.party_type, self.party): + frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party)) + + if self.party_account: + account_type = frappe.db.get_value("Account", self.party_account, "account_type") + + if self.party_type == "Customer" and account_type != "Receivable": + frappe.throw(_("Account Type must be Receivable for {0}").format(self.party_account)) + + if self.party_type == "Supplier" and account_type != "Payable": + frappe.throw(_("Account Type must be Payable for {0}").format(self.party_account)) + + def validate_allocated_amounts(self): + if self.payment_type == "Internal Transfer": + self.references = [] + self.total_allocated_amount = 0 + return + + self.total_allocated_amount, self.base_total_allocated_amount = 0, 0 + for d in self.get("references"): + if d.allocated_amount: + self.total_allocated_amount += flt(d.allocated_amount) + self.base_total_allocated_amount += flt(flt(d.allocated_amount) * flt(d.exchange_rate), + self.precision("base_paid_amount")) + + party_amount_field = "received_amount" if self.payment_type == "Pay" else "paid_amount" + + if self.total_allocated_amount != self.get(party_amount_field): + frappe.throw(_("Total Allocated Amount must be equal to {0} ({1})") + .format(self.get(party_amount_field), self.meta.get_label(party_amount_field))) + + def set_exchange_rate(self): + if self.paid_from: + if self.paid_from_account_currency != self.company_currency: + self.source_exchange_rate = get_average_exchange_rate(self.paid_from) + else: + self.source_exchange_rate = 1 + + if self.paid_to: + self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency, + self.company_currency) + + def set_amounts(self): + self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0 + if self.paid_amount: + if self.paid_from: + self.base_paid_amount = flt(flt(self.paid_amount) * flt(self.source_exchange_rate), + self.precision("base_paid_amount")) + else: + self.base_paid_amount = self.base_total_allocated_amount + + if self.received_amount: + if self.paid_to: + self.base_received_amount = flt(flt(self.received_amount) * flt(self.target_exchange_rate), + self.precision("base_received_amount")) + else: + self.base_received_amount = self.base_total_allocated_amount + + self.difference_amount = self.base_paid_amount - self.base_received_amount + + def validate_mandatory(self): + mandatory_fields = ["paid_amount", "received_amount", "base_paid_amount", "base_received_amount", + "reference_no", "reference_date"] + if self.payment_type == "Receive": + mandatory_fields += ["party_type", "party", "party_account", "party_account_currency", + "paid_to", "paid_to_account_currency", "references", "total_allocated_amount"] + elif self.payment_type == "Pay": + mandatory_fields += ["party_type", "party", "party_account", "party_account_currency", + "paid_from", "paid_from_account_currency", "references", "total_allocated_amount"] + else: + mandatory_fields += ["paid_from", "paid_from_account_currency", + "paid_to", "paid_to_account_currency"] + + if self.paid_from: + mandatory_fields.append("source_exchange_rate") + if self.paid_to: + mandatory_fields.append("target_exchange_rate") + + for field in mandatory_fields: + if not self.get(field): + frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field))) + + def set_write_off_amount(self): + if self.payment_type in ("Receive", "Pay"): + bank_account_currency = self.paid_from_account_currency \ + if self.paid_from else self.paid_to_account_currency + + if self.party_account_currency == bank_account_currency and self.difference_amount: + self.write_off_amount = self.difference_amount + + def make_gl_entries(self): + gl_entries = [] + self.add_party_gl_entries(gl_entries) + self.add_bank_gl_entries(gl_entries) + self.add_write_off_gl_entries(gl_entries) + self.add_deductions_gl_entries(gl_entries) + + make_gl_entries(gl_entries, cancel = (self.docstatus==2)) + + + def add_party_gl_entries(self, gl_entries): + if self.party_account: + party_gl_dict = self.get_gl_dict({ + "account": self.party_account, + "party_type": self.party_type, + "party": self.party, + "against": self.paid_from or self.paid_to, + "account_currency": self.party_account_currency + }) + + for d in self.get("references"): + party_gl_dict.update({ + "against_voucher_type": d.reference_doctype, + "against_voucher": d.reference_name + }) + + allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate), + self.precision("paid_amount")) + + if self.payment_type == "Receive": + party_gl_dict.update({ + "credit_in_account_currency": d.allocated_amount, + "credit": allocated_amount_in_company_currency + }) + elif self.payment_type == "Pay": + party_gl_dict.update({ + "debit_in_account_currency": d.allocated_amount, + "debit": allocated_amount_in_company_currency + }) + + gl_entries.append(party_gl_dict) + + def add_bank_gl_entries(self, gl_entries): + if self.paid_from and self.paid_amount: + gl_entries.append( + self.get_gl_dict({ + "account": self.paid_from, + "account_currency": self.paid_from_account_currency, + "against": self.party_account, + "credit_in_account_currency": self.paid_amount, + "credit": self.base_paid_amount + }) + ) + if self.paid_to and self.received_amount: + gl_entries.append( + self.get_gl_dict({ + "account": self.paid_to, + "account_currency": self.paid_to_account_currency, + "against": self.party, + "debit_in_account_currency": self.received_amount, + "debit": self.base_received_amount + }) + ) + + def add_write_off_gl_entries(self, gl_entries): + if self.write_off_account and self.write_off_amount: + write_off_account_currency = get_account_currency(self.write_off_account) + if self.write_off_account_currency != self.company_currency: + frappe.throw(_("Write Off Account currency must be same as {0}") + .format(self.company_currency)) + + gl_entries.append( + self.get_gl_dict({ + "account": self.write_off_account, + "against": self.party, + "debit_in_account_currency": self.write_off_amount, + "debit": self.write_off_amount, + "cost_center": self.write_off_cost_center + }, write_off_account_currency) + ) + + def add_deductions_gl_entries(self, gl_entries): + pass + + def update_advance_paid(self): + if self.payment_type in ("Receive", "Pay") and self.party: + for d in self.get("references"): + if d.allocated_amount and d.reference_doctype in ("Sales Order", "Purchase Order"): + frappe.get_doc(d.reference_doctype, d.reference_name).set_total_advance_paid() + +@frappe.whitelist() +def get_outstanding_reference_documents(args): + args = json.loads(args) + + party_account_currency = get_account_currency(args.get("party_account")) + company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency") + + if ((args.get("party_type") == "Customer" and args.get("payment_type") == "Pay") + or (args.get("party_type") == "Supplier" and args.get("payment_type") == "Received")): + + frappe.throw(_("Please enter the Reference Documents manually")) + + # Get all outstanding sales /purchase invoices + outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), + args.get("party_account")) + + # Get all SO / PO which are not fully billed or aginst which full advance not paid + orders_to_be_billed = get_orders_to_be_billed(args.get("party_type"), args.get("party"), + party_account_currency, company_currency) + + return outstanding_invoices + orders_to_be_billed + +def get_orders_to_be_billed(party_type, party, party_account_currency, company_currency): + voucher_type = 'Sales Order' if party_type == "Customer" else 'Purchase Order' + + ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" + + orders = frappe.db.sql(""" + select + name as voucher_no, + {ref_field} as invoice_amount, + ({ref_field} - advance_paid) as outstanding_amount, + transaction_date as posting_date + from + `tab{voucher_type}` + where + {party_type} = %s + and docstatus = 1 + and ifnull(status, "") != "Closed" + and {ref_field} > advance_paid + and abs(100 - per_billed) > 0.01 + order by + transaction_date, name + """.format(**{ + "ref_field": ref_field, + "voucher_type": voucher_type, + "party_type": scrub(party_type) + }), party, as_dict = True) + + order_list = [] + for d in orders: + d["voucher_type"] = voucher_type + d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency) + order_list.append(d) + + return order_list + +@frappe.whitelist() +def get_party_details(company, party_type, party, date): + party_account = get_party_account(party_type, party, company) + + account_currency = get_account_currency(party_account) + account_balance = get_balance_on(party_account, date) + party_balance = get_balance_on(party_type=party_type, party=party) + + return { + "party_account": party_account, + "party_account_currency": account_currency, + "party_balance": party_balance, + "account_balance": account_balance + } + +@frappe.whitelist() +def get_account_currency_and_balance(account, date): + return frappe._dict({ + "account_currency": get_account_currency(account), + "account_balance": get_balance_on(account, date) + }) + +@frappe.whitelist() +def get_write_off_account_and_cost_center(company): + return frappe.db.get_value("Company", company, ["write_off_account", "cost_center"], as_dict=1) + \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py new file mode 100644 index 00000000000..837adf85d94 --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +# test_records = frappe.get_test_records('Payment Entry') + +class TestPaymentEntry(unittest.TestCase): + pass diff --git a/erpnext/accounts/doctype/payment_entry_deduction/__init__.py b/erpnext/accounts/doctype/payment_entry_deduction/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json new file mode 100644 index 00000000000..e800235f1c8 --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json @@ -0,0 +1,113 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2016-06-15 15:56:30.815503", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "cost_center", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Cost Center", + "length": 0, + "no_copy": 0, + "options": "Cost Center", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2016-06-23 12:45:26.516398", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Payment Entry Deduction", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py new file mode 100644 index 00000000000..d6686bbe422 --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, 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 PaymentEntryDeduction(Document): + pass diff --git a/erpnext/accounts/doctype/payment_entry_reference/__init__.py b/erpnext/accounts/doctype/payment_entry_reference/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json new file mode 100644 index 00000000000..a82270afae1 --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json @@ -0,0 +1,237 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2016-06-01 16:55:32.196722", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "reference_doctype", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Type", + "length": 0, + "no_copy": 0, + "options": "DocType", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "reference_name", + "fieldtype": "Dynamic Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Name", + "length": 0, + "no_copy": 0, + "options": "reference_doctype", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "due_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Due Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_4", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "total_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Total Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "outstanding_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Outstanding Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "allocated_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Allocated Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "exchange_rate", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Exchange Rate", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2016-06-22 16:15:10.404692", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Payment Entry Reference", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py new file mode 100644 index 00000000000..51f8c06165a --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, 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 PaymentEntryReference(Document): + pass diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 27389aa441a..2ae8bbad8a7 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -378,7 +378,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None): payment_dr_or_cr = "payment_gl_entry.debit_in_account_currency - payment_gl_entry.credit_in_account_currency" invoice_list = frappe.db.sql("""select - voucher_no, voucher_type, posting_date, + voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount, ( select @@ -405,7 +405,8 @@ def get_outstanding_invoices(party_type, party, account, condition=None): or against_voucher is null)) or (voucher_type != 'Journal Entry')) group by voucher_type, voucher_no - having (invoice_amount - payment_amount) > 0.005""".format( + having (invoice_amount - payment_amount) > 0.005 + order by posting_date, name""".format( dr_or_cr = dr_or_cr, payment_dr_or_cr = payment_dr_or_cr, condition = condition or "" @@ -423,7 +424,8 @@ def get_outstanding_invoices(party_type, party, account, condition=None): 'invoice_amount': flt(d.invoice_amount), 'payment_amount': flt(d.payment_amount), 'outstanding_amount': flt(d.invoice_amount - d.payment_amount, precision), - 'due_date': frappe.db.get_value(d.voucher_type, d.voucher_no, "due_date") + 'due_date': frappe.db.get_value(d.voucher_type, d.voucher_no, "due_date"), + 'exchange_rate': frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate") }) return outstanding_invoices diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index e3a66a4b11b..fb037217542 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -396,10 +396,10 @@ class AccountsController(TransactionBase): select account_currency, sum({dr_or_cr}) as amount from - `tabJournal Entry Account` + `tabGL Entry` where - reference_type = %s and reference_name = %s and party=%s - and docstatus = 1 and is_advance = "Yes" + against_voucher_type = %s and against_voucher = %s and party=%s + and docstatus = 1 """.format(dr_or_cr=dr_or_cr), (self.doctype, self.name, party), as_dict=1) if advance: diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js index 2a182863431..9f9b1cc344e 100644 --- a/erpnext/setup/doctype/company/company.js +++ b/erpnext/setup/doctype/company/company.js @@ -136,6 +136,7 @@ erpnext.company.setup_queries = function(frm) { ["default_expense_account", {"root_type": "Expense"}], ["default_income_account", {"root_type": "Income"}], ["round_off_account", {"root_type": "Expense"}], + ["write_off_account", {"root_type": "Expense"}], ["accumulated_depreciation_account", {"root_type": "Asset"}], ["depreciation_expense_account", {"root_type": "Expense"}], ["disposal_account", {"report_type": "Profit and Loss"}], diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index 9140534cee5..754504edaf0 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -495,6 +495,32 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "write_off_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Write Off Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -1325,6 +1351,7 @@ "hide_toolbar": 0, "icon": "icon-building", "idx": 1, + "image_view": 0, "in_create": 0, "in_dialog": 0, "is_submittable": 0, @@ -1332,7 +1359,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2016-05-16 15:24:47.178826", + "modified": "2016-06-26 00:44:30.299891", "modified_by": "Administrator", "module": "Setup", "name": "Company",