[new][feature] Payment Entry
This commit is contained in:
parent
4177504860
commit
12e2a51519
@ -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",
|
||||
|
@ -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)
|
||||
|
@ -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]
|
||||
]
|
||||
}
|
||||
});
|
||||
|
0
erpnext/accounts/doctype/payment_entry/__init__.py
Normal file
0
erpnext/accounts/doctype/payment_entry/__init__.py
Normal file
523
erpnext/accounts/doctype/payment_entry/payment_entry.js
Normal file
523
erpnext/accounts/doctype/payment_entry/payment_entry.js
Normal file
@ -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);
|
||||
}
|
||||
})
|
1475
erpnext/accounts/doctype/payment_entry/payment_entry.json
Normal file
1475
erpnext/accounts/doctype/payment_entry/payment_entry.json
Normal file
File diff suppressed because it is too large
Load Diff
329
erpnext/accounts/doctype/payment_entry/payment_entry.py
Normal file
329
erpnext/accounts/doctype/payment_entry/payment_entry.py
Normal file
@ -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)
|
||||
|
12
erpnext/accounts/doctype/payment_entry/test_payment_entry.py
Normal file
12
erpnext/accounts/doctype/payment_entry/test_payment_entry.py
Normal file
@ -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
|
@ -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
|
||||
}
|
@ -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
|
@ -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
|
||||
}
|
@ -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
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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"}],
|
||||
|
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user