[refactor] added dynamic link in journal entry, #3847
diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
index 7dd021e..f1c8820 100644
--- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
+++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py
@@ -19,7 +19,8 @@
dl = frappe.db.sql("""select t1.name, t1.cheque_no, t1.cheque_date, t2.debit,
- t2.credit, t1.posting_date, t2.against_account, t1.clearance_date
+ t2.credit, t1.posting_date, t2.against_account, t1.clearance_date,
+ t2.reference_type, t2.reference_name
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where
diff --git a/erpnext/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.json b/erpnext/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.json
index b2c6e66..78691a3 100644
--- a/erpnext/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.json
+++ b/erpnext/accounts/doctype/bank_reconciliation_detail/bank_reconciliation_detail.json
@@ -1,11 +1,19 @@
{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
"creation": "2013-02-22 01:27:37",
+ "custom": 0,
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
+ "allow_on_submit": 0,
"fieldname": "voucher_id",
"fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 0,
"label": "Voucher ID",
"no_copy": 0,
@@ -13,46 +21,84 @@
"oldfieldtype": "Link",
"options": "Journal Entry",
"permlevel": 0,
- "search_index": 0
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "clearance_date",
"fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 1,
"label": "Clearance Date",
"no_copy": 0,
"oldfieldname": "clearance_date",
"oldfieldtype": "Date",
"permlevel": 0,
- "search_index": 0
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "against_account",
"fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 1,
"label": "Against Account",
"no_copy": 0,
"oldfieldname": "against_account",
"oldfieldtype": "Data",
"permlevel": 0,
+ "print_hide": 0,
"read_only": 1,
- "search_index": 0
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "cheque_number",
"fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 1,
"label": "Cheque Number",
"no_copy": 0,
"oldfieldname": "cheque_number",
"oldfieldtype": "Data",
"permlevel": 0,
+ "print_hide": 0,
"read_only": 1,
- "search_index": 0
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "debit",
"fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 1,
"label": "Debit",
"no_copy": 0,
@@ -60,12 +106,21 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0,
+ "print_hide": 0,
"read_only": 1,
- "search_index": 0
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "credit",
"fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 1,
"label": "Credit",
"no_copy": 0,
@@ -73,40 +128,113 @@
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0,
+ "print_hide": 0,
"read_only": 1,
- "search_index": 0
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
+ "fieldname": "reference_type",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Reference Type",
+ "no_copy": 0,
+ "options": "DocType",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "fieldname": "reference_name",
+ "fieldtype": "Dynamic Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Reference Name",
+ "no_copy": 0,
+ "options": "reference_type",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
"fieldname": "posting_date",
"fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 0,
"label": "Posting Date",
"no_copy": 0,
"oldfieldname": "posting_date",
"oldfieldtype": "Date",
"permlevel": 0,
+ "print_hide": 0,
"read_only": 1,
- "search_index": 0
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "cheque_date",
"fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 1,
"label": "Cheque Date",
"no_copy": 0,
"oldfieldname": "cheque_date",
"oldfieldtype": "Date",
"permlevel": 0,
+ "print_hide": 0,
"read_only": 1,
- "search_index": 0
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
}
],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
"idx": 1,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
"istable": 1,
- "modified": "2015-04-21 01:29:29.570890",
+ "modified": "2015-08-10 16:59:43.974705",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Reconciliation Detail",
"owner": "Administrator",
- "permissions": []
+ "permissions": [],
+ "read_only": 0,
+ "read_only_onload": 0
}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index ec17e34..38f3e0c 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -50,32 +50,43 @@
$.each([["against_voucher", "Purchase Invoice", "supplier"],
["against_invoice", "Sales Invoice", "customer"]], function(i, opts) {
- me.frm.set_query(opts[0], "accounts", function(doc, cdt, cdn) {
- var jvd = frappe.get_doc(cdt, cdn);
- frappe.model.validate_missing(jvd, "party_type");
- frappe.model.validate_missing(jvd, "party");
- return {
- filters: [
- [opts[1], opts[2], "=", jvd.party],
- [opts[1], "docstatus", "=", 1],
- [opts[1], "outstanding_amount", "!=", 0]
- ]
- };
- });
});
- this.frm.set_query("against_jv", "accounts", function(doc, cdt, cdn) {
+ me.frm.set_query("reference_name", "accounts", function(doc, cdt, cdn) {
var jvd = frappe.get_doc(cdt, cdn);
- frappe.model.validate_missing(jvd, "account");
+ // expense claim
+ if(jvd.reference_type==="Expense Claim") {
+ return {};
+ }
+
+ // journal entry
+ if(jvd.reference_type==="Journal Entry") {
+ frappe.model.validate_missing(jvd, "account");
+
+ return {
+ query: "erpnext.accounts.doctype.journal_entry.journal_entry.get_against_jv",
+ filters: {
+ account: jvd.account,
+ party: jvd.party
+ }
+ };
+ }
+
+ // against party
+
+ frappe.model.validate_missing(jvd, "party_type");
+ frappe.model.validate_missing(jvd, "party");
return {
- query: "erpnext.accounts.doctype.journal_entry.journal_entry.get_against_jv",
- filters: {
- account: jvd.account,
- party: jvd.party
- }
+ filters: [
+ [jvd.reference_type, jvd.reference_type.indexOf("Sales")==1 ? "customer" : "supplier", "=", jvd.party],
+ [jvd.reference_type, "docstatus", "=", 1],
+ [jvd.reference_type, "outstanding_amount", "!=", 0]
+ ]
};
});
+
+
},
setup_balance_formatter: function() {
@@ -93,24 +104,16 @@
})
},
- against_voucher: function(doc, cdt, cdn) {
+ reference_name: function(doc, cdt, cdn) {
var d = frappe.get_doc(cdt, cdn);
- if (d.against_voucher && !flt(d.debit)) {
- this.get_outstanding('Purchase Invoice', d.against_voucher, d);
+ if (d.reference_type==="Purchase Invoice" && !flt(d.debit)) {
+ this.get_outstanding('Purchase Invoice', d.reference_name, d);
}
- },
-
- against_invoice: function(doc, cdt, cdn) {
- var d = frappe.get_doc(cdt, cdn);
- if (d.against_invoice && !flt(d.credit)) {
- this.get_outstanding('Sales Invoice', d.against_invoice, d);
+ if (d.reference_type==="Sales Invoice" && !flt(d.credit)) {
+ this.get_outstanding('Sales Invoice', d.reference_name, d);
}
- },
-
- against_jv: function(doc, cdt, cdn) {
- var d = frappe.get_doc(cdt, cdn);
- if (d.against_jv && !flt(d.credit) && !flt(d.debit)) {
- this.get_outstanding('Journal Entry', d.against_jv, d);
+ if (d.reference_type==="Journal Entry" && !flt(d.credit) && !flt(d.debit)) {
+ this.get_outstanding('Journal Entry', d.reference_name, d);
}
},
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 80d2435..b48e46c 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -28,13 +28,10 @@
self.validate_entries_for_advance()
self.validate_debit_and_credit()
self.validate_against_jv()
- self.validate_against_sales_invoice()
- self.validate_against_purchase_invoice()
+ self.validate_reference_doc()
self.set_against_account()
self.create_remarks()
self.set_print_format_fields()
- self.validate_against_sales_order()
- self.validate_against_purchase_order()
self.check_due_date()
self.validate_expense_claim()
self.validate_credit_debit_note()
@@ -54,10 +51,8 @@
advance_paid = frappe._dict()
for d in self.get("accounts"):
if d.is_advance:
- if d.against_sales_order:
- advance_paid.setdefault("Sales Order", []).append(d.against_sales_order)
- elif d.against_purchase_order:
- advance_paid.setdefault("Purchase Order", []).append(d.against_purchase_order)
+ if d.reference_type in ("Sales Order", "Purchase Order"):
+ advance_paid.setdefault(d.reference_type, []).append(d.reference_name)
for voucher_type, order_list in advance_paid.items():
for voucher_no in list(set(order_list)):
@@ -65,7 +60,7 @@
def on_cancel(self):
from erpnext.accounts.utils import remove_against_link_from_jv
- remove_against_link_from_jv(self.doctype, self.name, "against_jv")
+ remove_against_link_from_jv(self.doctype, self.name)
self.make_gl_entries(1)
self.update_advance_paid()
@@ -93,10 +88,8 @@
for d in self.get("accounts"):
if d.party_type and d.party and d.get("credit" if d.party_type=="Customer" else "debit") > 0:
due_date = None
- if d.against_invoice:
- due_date = frappe.db.get_value("Sales Invoice", d.against_invoice, "due_date")
- elif d.against_voucher:
- due_date = frappe.db.get_value("Purchase Invoice", d.against_voucher, "due_date")
+ if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
+ due_date = frappe.db.get_value(d.reference_type, d.reference_name, "due_date")
if due_date and getdate(self.cheque_date) > getdate(due_date):
diff = date_diff(self.cheque_date, due_date)
@@ -115,17 +108,17 @@
def validate_entries_for_advance(self):
for d in self.get('accounts'):
- if not (d.against_voucher and d.against_invoice and d.against_jv):
+ if d.reference_type not in ("Sales Invoice", "Purchase Invoice", "Journal Entry"):
if (d.party_type == 'Customer' and flt(d.credit) > 0) or \
(d.party_type == 'Supplier' and flt(d.debit) > 0):
- if not d.is_advance:
+ if d.is_advance=="No":
msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.").format(d.idx, d.account))
- elif (d.against_sales_order or d.against_purchase_order) and d.is_advance != "Yes":
+ elif d.reference_type in ("Sales Order", "Purchase Order") and d.is_advance != "Yes":
frappe.throw(_("Row {0}: Payment against Sales/Purchase Order should always be marked as advance").format(d.idx))
def validate_against_jv(self):
for d in self.get('accounts'):
- if d.against_jv:
+ if d.reference_type=="Journal Voucher":
account_root_type = frappe.db.get_value("Account", d.account, "root_type")
if account_root_type == "Asset" and flt(d.debit) > 0:
frappe.throw(_("For {0}, only credit accounts can be linked against another debit entry")
@@ -134,17 +127,17 @@
frappe.throw(_("For {0}, only debit accounts can be linked against another credit entry")
.format(d.account))
- if d.against_jv == self.name:
+ if d.reference_name == self.name:
frappe.throw(_("You can not enter current voucher in 'Against Journal Entry' column"))
against_entries = frappe.db.sql("""select * from `tabJournal Entry Account`
where account = %s and docstatus = 1 and parent = %s
- and ifnull(against_jv, '') = '' and ifnull(against_invoice, '') = ''
- and ifnull(against_voucher, '') = ''""", (d.account, d.against_jv), as_dict=True)
+ and ifnull(reference_type, '') = '' and ifnull(reference_name, '') = ''
+ """, (d.account, d.reference_name), as_dict=True)
if not against_entries:
frappe.throw(_("Journal Entry {0} does not have account {1} or already matched against other voucher")
- .format(d.against_jv, d.account))
+ .format(d.reference_name, d.account))
else:
dr_or_cr = "debit" if d.credit > 0 else "credit"
valid = False
@@ -153,89 +146,99 @@
valid = True
if not valid:
frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
- .format(d.against_jv, dr_or_cr))
+ .format(d.reference_name, dr_or_cr))
- def validate_against_sales_invoice(self):
- self.validate_account_in_against_voucher("against_invoice", "Sales Invoice")
-
- def validate_against_purchase_invoice(self):
- self.validate_account_in_against_voucher("against_voucher", "Purchase Invoice")
-
- def validate_against_sales_order(self):
- payment_against_voucher = self.validate_account_in_against_voucher("against_sales_order", "Sales Order")
- self.validate_against_order_fields("Sales Order", payment_against_voucher)
-
- def validate_against_purchase_order(self):
- payment_against_voucher = self.validate_account_in_against_voucher("against_purchase_order", "Purchase Order")
- self.validate_against_order_fields("Purchase Order", payment_against_voucher)
-
- def validate_account_in_against_voucher(self, against_field, doctype):
- payment_against_voucher = frappe._dict()
- field_dict = {'Sales Invoice': ["Customer", "Debit To"],
+ def validate_reference_doc(self):
+ """Validates reference document"""
+ field_dict = {
+ 'Sales Invoice': ["Customer", "Debit To"],
'Purchase Invoice': ["Supplier", "Credit To"],
'Sales Order': ["Customer"],
'Purchase Order': ["Supplier"]
- }
+ }
+
+ self.reference_totals = {}
+ self.reference_types = {}
for d in self.get("accounts"):
- if d.get(against_field):
- dr_or_cr = "credit" if against_field in ["against_invoice", "against_sales_order"] \
+ if not d.reference_type:
+ d.reference_name = None
+ if not d.reference_type:
+ d.reference_name = None
+ if d.reference_type and d.reference_name and (d.reference_type in field_dict.keys()):
+ dr_or_cr = "credit" if d.reference_type in ("Sales Order", "Sales Invoice") \
else "debit"
- if against_field == "against_sales_order" and flt(d.debit) > 0:
- frappe.throw(_("Row {0}: Debit entry can not be linked with a {1}").format(d.idx, doctype))
- if against_field == "against_purchase_order" and flt(d.credit) > 0:
- frappe.throw(_("Row {0}: Credit entry can not be linked with a {1}").format(d.idx, doctype))
+ # check debit or credit type Sales / Purchase Order
+ if d.reference_type=="Sales Order" and flt(d.debit) > 0:
+ frappe.throw(_("Row {0}: Debit entry can not be linked with a {1}").format(d.idx, d.reference_type))
- against_voucher = frappe.db.get_value(doctype, d.get(against_field),
- [scrub(dt) for dt in field_dict.get(doctype)])
+ if d.reference_type == "Purchase Order" and flt(d.credit) > 0:
+ frappe.throw(_("Row {0}: Credit entry can not be linked with a {1}").format(d.idx, d.reference_type))
- if against_field in ["against_invoice", "against_voucher"]:
- if (against_voucher[0] !=d.party or against_voucher[1] != d.account):
+ # set totals
+ if not d.reference_name in self.reference_totals:
+ self.reference_totals[d.reference_name] = 0.0
+ self.reference_totals[d.reference_name] += flt(d.get(dr_or_cr))
+ self.reference_types[d.reference_name] = d.reference_type
+
+ against_voucher = frappe.db.get_value(d.reference_type, d.reference_name,
+ [scrub(dt) for dt in field_dict.get(d.reference_type)])
+
+ # check if party and account match
+ if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
+ if (against_voucher[0] != d.party or against_voucher[1] != d.account):
frappe.throw(_("Row {0}: Party / Account does not match with {1} / {2} in {3} {4}")
- .format(d.idx, field_dict.get(doctype)[0], field_dict.get(doctype)[1],
- doctype, d.get(against_field)))
- else:
- payment_against_voucher.setdefault(d.get(against_field), []).append(flt(d.get(dr_or_cr)))
+ .format(d.idx, field_dict.get(d.reference_type)[0], field_dict.get(d.reference_type)[1],
+ d.reference_type, d.reference_name))
- if against_field in ["against_sales_order", "against_purchase_order"]:
+ # check if party matches for Sales / Purchase Order
+ if d.reference_type in ("Sales Order", "Purchase Order"):
+ # set totals
if against_voucher != d.party:
frappe.throw(_("Row {0}: {1} {2} does not match with {3}") \
- .format(d.idx, d.party_type, d.party, doctype))
- elif d.is_advance == "Yes":
- payment_against_voucher.setdefault(d.get(against_field), []).append(flt(d.get(dr_or_cr)))
+ .format(d.idx, d.party_type, d.party, d.reference_type))
- return payment_against_voucher
+ self.validate_orders()
+ self.validate_invoices()
- def validate_against_invoice_fields(self, doctype, payment_against_voucher):
- for voucher_no, payment_list in payment_against_voucher.items():
- voucher_properties = frappe.db.get_value(doctype, voucher_no,
- ["docstatus", "outstanding_amount"])
+ def validate_orders(self):
+ """Validate totals, stopped and docstatus for orders"""
+ for reference_name, total in self.reference_totals.iteritems():
+ reference_type = self.reference_types[reference_name]
- if voucher_properties[0] != 1:
- frappe.throw(_("{0} {1} is not submitted").format(doctype, voucher_no))
+ if reference_type in ("Sales Order", "Purchase Order"):
+ voucher_properties = frappe.db.get_value(reference_type, reference_name,
+ ["docstatus", "per_billed", "status", "advance_paid", "base_grand_total"])
- if flt(voucher_properties[1]) < flt(sum(payment_list)):
- frappe.throw(_("Payment against {0} {1} cannot be greater \
- than Outstanding Amount {2}").format(doctype, voucher_no, voucher_properties[1]))
+ if voucher_properties[0] != 1:
+ frappe.throw(_("{0} {1} is not submitted").format(reference_type, reference_name))
- def validate_against_order_fields(self, doctype, payment_against_voucher):
- for voucher_no, payment_list in payment_against_voucher.items():
- voucher_properties = frappe.db.get_value(doctype, voucher_no,
- ["docstatus", "per_billed", "status", "advance_paid", "base_grand_total"])
+ if flt(voucher_properties[1]) >= 100:
+ frappe.throw(_("{0} {1} is fully billed").format(reference_type, reference_name))
- if voucher_properties[0] != 1:
- frappe.throw(_("{0} {1} is not submitted").format(doctype, voucher_no))
+ if cstr(voucher_properties[2]) == "Stopped":
+ frappe.throw(_("{0} {1} is stopped").format(reference_type, reference_name))
- if flt(voucher_properties[1]) >= 100:
- frappe.throw(_("{0} {1} is fully billed").format(doctype, voucher_no))
+ if flt(voucher_properties[4]) < (flt(voucher_properties[3]) + total):
+ frappe.throw(_("Advance paid against {0} {1} cannot be greater \
+ than Grand Total {2}").format(reference_type, reference_name, voucher_properties[4]))
- if cstr(voucher_properties[2]) == "Stopped":
- frappe.throw(_("{0} {1} is stopped").format(doctype, voucher_no))
+ def validate_invoices(self):
+ """Validate totals and docstatus for invoices"""
+ for reference_name, total in self.reference_totals.iteritems():
+ reference_type = self.reference_types[reference_name]
- if flt(voucher_properties[4]) < flt(voucher_properties[3]) + flt(sum(payment_list)):
- frappe.throw(_("Advance paid against {0} {1} cannot be greater \
- than Grand Total {2}").format(doctype, voucher_no, voucher_properties[3]))
+ if reference_type in ("Sales Invoice", "Purchase Invoice"):
+ voucher_properties = frappe.db.get_value(reference_type, reference_name,
+ ["docstatus", "outstanding_amount"])
+
+ if voucher_properties[0] != 1:
+ frappe.throw(_("{0} {1} is not submitted").format(reference_type, reference_name))
+
+ if flt(voucher_properties[1]) < total:
+ frappe.throw(_("Payment against {0} {1} cannot be greater \
+ than Outstanding Amount {2}").format(reference_type, reference_name, voucher_properties[1]))
def set_against_account(self):
accounts_debited, accounts_credited = [], []
@@ -275,25 +278,25 @@
company_currency = get_company_currency(self.company)
for d in self.get('accounts'):
- if d.against_invoice and d.credit:
+ if d.reference_type=="Sales Invoice" and d.credit:
r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = company_currency), \
- d.against_invoice))
+ d.reference_name))
- if d.against_sales_order and d.credit:
+ if d.reference_type=="Sales Order" and d.credit:
r.append(_("{0} against Sales Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \
- d.against_sales_order))
+ d.reference_name))
- if d.against_voucher and d.debit:
+ if d.reference_type == "Purchase Invoice" and d.debit:
bill_no = frappe.db.sql("""select bill_no, bill_date
- from `tabPurchase Invoice` where name=%s""", d.against_voucher)
+ from `tabPurchase Invoice` where name=%s""", d.reference_name)
if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \
not in ['na', 'not applicable', 'none']:
r.append(_('{0} against Bill {1} dated {2}').format(fmt_money(flt(d.debit), currency=company_currency), bill_no[0][0],
bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d'))))
- if d.against_purchase_order and d.debit:
+ if d.reference_type == "Purchase Order" and d.debit:
r.append(_("{0} against Purchase Order {1}").format(fmt_money(flt(d.credit), currency = company_currency), \
- d.against_purchase_order))
+ d.reference_name))
if self.user_remark:
r.append(_("Note: {0}").format(self.user_remark))
@@ -332,13 +335,8 @@
"against": d.against_account,
"debit": flt(d.debit, self.precision("debit", "accounts")),
"credit": flt(d.credit, self.precision("credit", "accounts")),
- "against_voucher_type": (("Purchase Invoice" if d.against_voucher else None)
- or ("Sales Invoice" if d.against_invoice else None)
- or ("Journal Entry" if d.against_jv else None)
- or ("Sales Order" if d.against_sales_order else None)
- or ("Purchase Order" if d.against_purchase_order else None)),
- "against_voucher": d.against_voucher or d.against_invoice or d.against_jv
- or d.against_sales_order or d.against_purchase_order,
+ "against_voucher_type": d.reference_type,
+ "against_voucher": d.reference_name,
"remarks": self.remark,
"cost_center": d.cost_center
})
@@ -385,11 +383,13 @@
if self.write_off_based_on == 'Accounts Receivable':
jd1.party_type = "Customer"
jd1.credit = flt(d.outstanding_amount, self.precision("credit", "accounts"))
- jd1.against_invoice = cstr(d.name)
+ jd1.reference_type = "Sales Invoice"
+ jd1.reference_name = cstr(d.name)
elif self.write_off_based_on == 'Accounts Payable':
jd1.party_type = "Supplier"
jd1.debit = flt(d.outstanding_amount, self.precision("debit", "accounts"))
- jd1.against_voucher = cstr(d.name)
+ jd1.reference_type = "Purchase Invoice"
+ jd1.reference_name = cstr(d.name)
jd2 = self.append('accounts', {})
if self.write_off_based_on == 'Accounts Receivable':
@@ -415,19 +415,20 @@
def update_expense_claim(self):
for d in self.accounts:
- if d.against_expense_claim:
+ if d.reference_type=="Expense Claim":
amt = frappe.db.sql("""select sum(debit) as amt from `tabJournal Entry Account`
- where against_expense_claim = %s and docstatus = 1""", d.against_expense_claim ,as_dict=1)[0].amt
- frappe.db.set_value("Expense Claim", d.against_expense_claim , "total_amount_reimbursed", amt)
+ where reference_type = "Expense Claim" and
+ reference_name = %s and docstatus = 1""", d.reference_name ,as_dict=1)[0].amt
+ frappe.db.set_value("Expense Claim", d.reference_name , "total_amount_reimbursed", amt)
def validate_expense_claim(self):
for d in self.accounts:
- if d.against_expense_claim:
+ if d.reference_type=="Expense Claim":
sanctioned_amount, reimbursed_amount = frappe.db.get_value("Expense Claim",
- d.against_expense_claim, ("total_sanctioned_amount", "total_amount_reimbursed"))
+ d.reference_name, ("total_sanctioned_amount", "total_amount_reimbursed"))
pending_amount = flt(sanctioned_amount) - flt(reimbursed_amount)
if d.debit > pending_amount:
- frappe.throw(_("Row No {0}: Amount cannot be greater than Pending Amount against Expense Claim {1}. Pending Amount is {2}".format(d.idx, d.against_expense_claim, pending_amount)))
+ frappe.throw(_("Row No {0}: Amount cannot be greater than Pending Amount against Expense Claim {1}. Pending Amount is {2}".format(d.idx, d.reference_name, pending_amount)))
def validate_credit_debit_note(self):
if self.stock_entry:
@@ -467,6 +468,7 @@
@frappe.whitelist()
def get_payment_entry_from_sales_invoice(sales_invoice):
+ """Returns new Journal Entry document as dict for given Sales Invoice"""
from erpnext.accounts.utils import get_balance_on
si = frappe.get_doc("Sales Invoice", sales_invoice)
jv = get_payment_entry(si)
@@ -479,7 +481,8 @@
jv.get("accounts")[0].balance = get_balance_on(si.debit_to)
jv.get("accounts")[0].party_balance = get_balance_on(party=si.customer, party_type="Customer")
jv.get("accounts")[0].credit = si.outstanding_amount
- jv.get("accounts")[0].against_invoice = si.name
+ jv.get("accounts")[0].reference_type = si.doctype
+ jv.get("accounts")[0].reference_name = si.name
# debit bank
jv.get("accounts")[1].debit = si.outstanding_amount
@@ -488,6 +491,7 @@
@frappe.whitelist()
def get_payment_entry_from_purchase_invoice(purchase_invoice):
+ """Returns new Journal Entry document as dict for given Purchase Invoice"""
pi = frappe.get_doc("Purchase Invoice", purchase_invoice)
jv = get_payment_entry(pi)
jv.remark = 'Payment against Purchase Invoice {0}. {1}'.format(pi.name, pi.remarks)
@@ -499,13 +503,78 @@
jv.get("accounts")[0].balance = get_balance_on(pi.credit_to)
jv.get("accounts")[0].party_balance = get_balance_on(party=pi.supplier, party_type="Supplier")
jv.get("accounts")[0].debit = pi.outstanding_amount
- jv.get("accounts")[0].against_voucher = pi.name
+ jv.get("accounts")[0].reference_type = pi.doctype
+ jv.get("accounts")[0].reference_name = pi.name
# credit bank
jv.get("accounts")[1].credit = pi.outstanding_amount
return jv.as_dict()
+@frappe.whitelist()
+def get_payment_entry_from_sales_order(sales_order):
+ """Returns new Journal Entry document as dict for given Sales Order"""
+ from erpnext.accounts.utils import get_balance_on
+ from erpnext.accounts.party import get_party_account
+ so = frappe.get_doc("Sales Order", sales_order)
+
+ if flt(so.per_billed, 2) != 0.0:
+ frappe.throw(_("Can only make payment against unbilled Sales Order"))
+
+ jv = get_payment_entry(so)
+ jv.remark = 'Advance payment received against Sales Order {0}.'.format(so.name)
+ party_account = get_party_account(so.company, so.customer, "Customer")
+
+ amount = flt(so.base_grand_total) - flt(so.advance_paid)
+
+ # credit customer
+ jv.get("accounts")[0].account = party_account
+ jv.get("accounts")[0].party_type = "Customer"
+ jv.get("accounts")[0].party = so.customer
+ jv.get("accounts")[0].balance = get_balance_on(party_account)
+ jv.get("accounts")[0].party_balance = get_balance_on(party=so.customer, party_type="Customer")
+ jv.get("accounts")[0].credit = amount
+ jv.get("accounts")[0].reference_type = so.doctype
+ jv.get("accounts")[0].reference_name = so.name
+ jv.get("accounts")[0].is_advance = "Yes"
+
+ # debit bank
+ jv.get("accounts")[1].debit = amount
+
+ return jv.as_dict()
+
+@frappe.whitelist()
+def get_payment_entry_from_purchase_order(purchase_order):
+ """Returns new Journal Entry document as dict for given Sales Order"""
+ from erpnext.accounts.utils import get_balance_on
+ from erpnext.accounts.party import get_party_account
+ po = frappe.get_doc("Purchase Order", purchase_order)
+
+ if flt(po.per_billed, 2) != 0.0:
+ frappe.throw(_("Can only make payment against unbilled Sales Order"))
+
+ jv = get_payment_entry(po)
+ jv.remark = 'Advance payment made against Purchase Order {0}.'.format(po.name)
+ party_account = get_party_account(po.company, po.supplier, "Supplier")
+
+ amount = flt(po.base_grand_total) - flt(po.advance_paid)
+
+ # credit customer
+ jv.get("accounts")[0].account = party_account
+ jv.get("accounts")[0].party_type = "Supplier"
+ jv.get("accounts")[0].party = po.supplier
+ jv.get("accounts")[0].balance = get_balance_on(party_account)
+ jv.get("accounts")[0].party_balance = get_balance_on(party=po.supplier, party_type="Supplier")
+ jv.get("accounts")[0].debit = amount
+ jv.get("accounts")[0].reference_type = po.doctype
+ jv.get("accounts")[0].reference_name = po.name
+ jv.get("accounts")[0].is_advance = "Yes"
+
+ # debit bank
+ jv.get("accounts")[1].credit = amount
+
+ return jv.as_dict()
+
def get_payment_entry(doc):
bank_account = get_default_bank_cash_account(doc.company, "Bank Entry")
@@ -536,8 +605,7 @@
return frappe.db.sql("""select jv.name, jv.posting_date, jv.user_remark
from `tabJournal Entry` jv, `tabJournal Entry Account` jv_detail
where jv_detail.parent = jv.name and jv_detail.account = %s and ifnull(jv_detail.party, '') = %s
- and (ifnull(jv_detail.against_invoice, '') = '' and ifnull(jv_detail.against_voucher, '') = ''
- and ifnull(jv_detail.against_jv, '') = '' )
+ and (ifnull(jv_detail.reference_type, '') = ''
and jv.docstatus = 1 and jv.{0} like %s order by jv.name desc limit %s, %s""".format(searchfield),
(filters.get("account"), cstr(filters.get("party")), "%{0}%".format(txt), start, page_len))
@@ -546,12 +614,11 @@
args = eval(args)
if args.get("doctype") == "Journal Entry":
condition = " and party=%(party)s" if args.get("party") else ""
-
+
against_jv_amount = frappe.db.sql("""
select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {0}
- and ifnull(against_invoice, '')='' and ifnull(against_voucher, '')=''
- and ifnull(against_jv, '')=''""".format(condition), args)
+ and ifnull(reference_type, '')=''""".format(condition), args)
against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0
return {
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
index 2aa60f0..c70f10d 100644
--- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
@@ -29,10 +29,6 @@
def jv_against_voucher_testcase(self, base_jv, test_voucher):
dr_or_cr = "credit" if test_voucher.doctype in ["Sales Order", "Journal Entry"] else "debit"
- field_dict = {'Journal Entry': "against_jv",
- 'Sales Order': "against_sales_order",
- 'Purchase Order': "against_purchase_order"
- }
test_voucher.insert()
test_voucher.submit()
@@ -42,21 +38,20 @@
where account = %s and docstatus = 1 and parent = %s""",
("_Test Receivable - _TC", test_voucher.name)))
- self.assertTrue(not frappe.db.sql("""select name from `tabJournal Entry Account`
- where %s=%s""" % (field_dict.get(test_voucher.doctype), '%s'), (test_voucher.name)))
+ self.assertFalse(frappe.db.sql("""select name from `tabJournal Entry Account`
+ where reference_type = %s and reference_name = %s""", (test_voucher.doctype, test_voucher.name)))
base_jv.get("accounts")[0].is_advance = "Yes" if (test_voucher.doctype in ["Sales Order", "Purchase Order"]) else "No"
- base_jv.get("accounts")[0].set(field_dict.get(test_voucher.doctype), test_voucher.name)
+ base_jv.get("accounts")[0].set("reference_type", test_voucher.doctype)
+ base_jv.get("accounts")[0].set("reference_name", test_voucher.name)
base_jv.insert()
base_jv.submit()
submitted_voucher = frappe.get_doc(test_voucher.doctype, test_voucher.name)
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
- where %s=%s""" % (field_dict.get(test_voucher.doctype), '%s'), (submitted_voucher.name)))
-
- self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
- where %s=%s and %s=400""" % (field_dict.get(submitted_voucher.doctype), '%s', dr_or_cr), (submitted_voucher.name)))
+ where reference_type = %s and reference_name = %s and {0}=400""".format(dr_or_cr),
+ (submitted_voucher.doctype, submitted_voucher.name)))
if base_jv.get("accounts")[0].is_advance == "Yes":
self.advance_paid_testcase(base_jv, submitted_voucher, dr_or_cr)
@@ -102,23 +97,23 @@
def test_monthly_budget_crossed_ignore(self):
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
-
+
self.set_total_expense_zero("2013-02-28")
-
- jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+
+ jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 40000, "_Test Cost Center - _TC", submit=True)
-
+
self.assertTrue(frappe.db.get_value("GL Entry",
{"voucher_type": "Journal Entry", "voucher_no": jv.name}))
def test_monthly_budget_crossed_stop(self):
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Stop")
-
+
self.set_total_expense_zero("2013-02-28")
-
- jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+
+ jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 40000, "_Test Cost Center - _TC")
-
+
self.assertRaises(BudgetError, jv.submit)
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
@@ -127,37 +122,37 @@
self.test_monthly_budget_crossed_ignore()
frappe.db.set_value("Company", "_Test Company", "yearly_bgt_flag", "Stop")
-
+
self.set_total_expense_zero("2013-02-28")
- jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+ jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 150000, "_Test Cost Center - _TC")
-
+
self.assertRaises(BudgetError, jv.submit)
frappe.db.set_value("Company", "_Test Company", "yearly_bgt_flag", "Ignore")
def test_monthly_budget_on_cancellation(self):
self.set_total_expense_zero("2013-02-28")
-
- jv1 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+
+ jv1 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 20000, "_Test Cost Center - _TC", submit=True)
-
+
self.assertTrue(frappe.db.get_value("GL Entry",
{"voucher_type": "Journal Entry", "voucher_no": jv1.name}))
-
- jv2 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+
+ jv2 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", 20000, "_Test Cost Center - _TC", submit=True)
-
+
self.assertTrue(frappe.db.get_value("GL Entry",
{"voucher_type": "Journal Entry", "voucher_no": jv2.name}))
-
+
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Stop")
self.assertRaises(BudgetError, jv1.cancel)
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
-
+
def get_actual_expense(self, monthly_end_date):
return get_actual_expense({
"account": "_Test Account Cost for Goods Sold - _TC",
@@ -166,19 +161,19 @@
"company": "_Test Company",
"fiscal_year": get_fiscal_year(monthly_end_date)[0]
})
-
+
def set_total_expense_zero(self, posting_date):
existing_expense = self.get_actual_expense(posting_date)
- make_journal_entry("_Test Account Cost for Goods Sold - _TC",
+ make_journal_entry("_Test Account Cost for Goods Sold - _TC",
"_Test Account Bank Account - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True)
-
+
def make_journal_entry(account1, account2, amount, cost_center=None, submit=False):
jv = frappe.new_doc("Journal Entry")
jv.posting_date = "2013-02-14"
jv.company = "_Test Company"
jv.fiscal_year = "_Test Fiscal Year 2013"
jv.user_remark = "test"
-
+
jv.set("accounts", [
{
"account": account1,
@@ -193,11 +188,11 @@
}
])
jv.insert()
-
+
if submit:
jv.submit()
-
+
return jv
-
+
test_records = frappe.get_test_records('Journal Entry')
diff --git a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
index b336d49..d091714 100644
--- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
+++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
@@ -1,27 +1,44 @@
{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
"autoname": "hash",
"creation": "2013-02-22 01:27:39",
+ "custom": 0,
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
+ "allow_on_submit": 0,
"fieldname": "account",
"fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Account",
+ "no_copy": 0,
"oldfieldname": "account",
"oldfieldtype": "Link",
"options": "Account",
"permlevel": 0,
+ "print_hide": 0,
"print_width": "250px",
+ "read_only": 0,
+ "report_hide": 0,
"reqd": 1,
"search_index": 1,
+ "set_only_once": 0,
+ "unique": 0,
"width": "250px"
},
{
+ "allow_on_submit": 0,
"fieldname": "balance",
"fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 1,
"label": "Account Balance",
"no_copy": 1,
@@ -30,186 +47,336 @@
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 1,
- "read_only": 1
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"default": ":Company",
"description": "If Income or Expense",
"fieldname": "cost_center",
"fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
"in_filter": 1,
"in_list_view": 1,
"label": "Cost Center",
+ "no_copy": 0,
"oldfieldname": "cost_center",
"oldfieldtype": "Link",
"options": "Cost Center",
"permlevel": 0,
"print_hide": 1,
"print_width": "180px",
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
"width": "180px"
},
{
+ "allow_on_submit": 0,
"fieldname": "col_break1",
"fieldtype": "Column Break",
- "permlevel": 0
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "party_type",
"fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
"label": "Party Type",
+ "no_copy": 0,
"options": "DocType",
- "permlevel": 0
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "party",
"fieldtype": "Dynamic Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
"label": "Party",
+ "no_copy": 0,
"options": "party_type",
- "permlevel": 0
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "party_balance",
"fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
"label": "Party Balance",
+ "no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
- "read_only": 1
+ "print_hide": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "sec_break1",
"fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
"label": "Amount",
- "permlevel": 0
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "debit",
"fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 1,
"label": "Debit",
+ "no_copy": 0,
"oldfieldname": "debit",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
- "permlevel": 0
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "col_break2",
"fieldtype": "Column Break",
- "permlevel": 0
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "credit",
"fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
"in_list_view": 1,
"label": "Credit",
+ "no_copy": 0,
"oldfieldname": "credit",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
- "permlevel": 0
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "reference",
"fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
"label": "Reference",
- "permlevel": 0
- },
- {
- "fieldname": "against_invoice",
- "fieldtype": "Link",
- "in_filter": 1,
- "label": "Against Sales Invoice",
- "no_copy": 1,
- "oldfieldname": "against_invoice",
- "oldfieldtype": "Link",
- "options": "Sales Invoice",
+ "no_copy": 0,
"permlevel": 0,
"print_hide": 0,
- "search_index": 1
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
- "fieldname": "against_voucher",
- "fieldtype": "Link",
- "in_filter": 1,
- "in_list_view": 1,
- "label": "Against Purchase Invoice",
- "no_copy": 1,
- "oldfieldname": "against_voucher",
- "oldfieldtype": "Link",
- "options": "Purchase Invoice",
+ "allow_on_submit": 0,
+ "fieldname": "reference_type",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Reference Type",
+ "no_copy": 0,
+ "options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
- "search_index": 1
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
- "fieldname": "against_jv",
- "fieldtype": "Link",
- "in_filter": 1,
- "label": "Against Journal Entry",
- "no_copy": 1,
- "oldfieldname": "against_jv",
- "oldfieldtype": "Link",
- "options": "Journal Entry",
+ "allow_on_submit": 0,
+ "fieldname": "reference_name",
+ "fieldtype": "Dynamic Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Reference Name",
+ "no_copy": 0,
+ "options": "reference_type",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
- "search_index": 1
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "col_break3",
"fieldtype": "Column Break",
- "permlevel": 0
- },
- {
- "fieldname": "against_sales_order",
- "fieldtype": "Link",
- "label": "Against Sales Order",
- "options": "Sales Order",
- "permlevel": 0
- },
- {
- "fieldname": "against_purchase_order",
- "fieldtype": "Link",
- "label": "Against Purchase Order",
- "options": "Purchase Order",
- "permlevel": 0
- },
- {
- "fieldname": "against_expense_claim",
- "fieldtype": "Link",
- "label": "Against Expense Claim",
- "options": "Expense Claim",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "no_copy": 0,
"permlevel": 0,
- "precision": ""
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "is_advance",
"fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
"label": "Is Advance",
"no_copy": 1,
"oldfieldname": "is_advance",
"oldfieldtype": "Select",
"options": "No\nYes",
"permlevel": 0,
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
},
{
+ "allow_on_submit": 0,
"fieldname": "against_account",
"fieldtype": "Text",
"hidden": 1,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
"label": "Against Account",
"no_copy": 1,
"oldfieldname": "against_account",
"oldfieldtype": "Text",
"permlevel": 0,
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
}
],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
"idx": 1,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
"istable": 1,
- "modified": "2015-02-19 01:07:00.388689",
+ "modified": "2015-08-11 10:44:11.432623",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry Account",
"owner": "Administrator",
- "permissions": []
+ "permissions": [],
+ "read_only": 0,
+ "read_only_onload": 0
}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index bcca0f2..933570f 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -34,8 +34,8 @@
t1.name = t2.parent and t1.docstatus = 1 and t2.docstatus = 1
and t2.party_type = %(party_type)s and t2.party = %(party)s
and t2.account = %(account)s and {dr_or_cr} > 0
- and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')=''
- and ifnull(t2.against_jv, '')='' {cond}
+ and ifnull(t2.reference_type, '')=''
+ {cond}
and (CASE
WHEN t1.voucher_type in ('Debit Note', 'Credit Note')
THEN 1=1
@@ -190,7 +190,7 @@
if flt(p.allocated_amount) > flt(p.amount):
frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to JV amount {2}")
.format(p.idx, p.allocated_amount, p.amount))
-
+
invoice_outstanding = unreconciled_invoices.get(p.invoice_type, {}).get(p.invoice_number)
if flt(p.allocated_amount) - invoice_outstanding > 0.009:
frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to invoice outstanding amount {2}")
diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.py b/erpnext/accounts/doctype/payment_tool/payment_tool.py
index 6a002af..4edbebd 100644
--- a/erpnext/accounts/doctype/payment_tool/payment_tool.py
+++ b/erpnext/accounts/doctype/payment_tool/payment_tool.py
@@ -12,13 +12,6 @@
def make_journal_entry(self):
from erpnext.accounts.utils import get_balance_on
total_payment_amount = 0.00
- invoice_voucher_type = {
- 'Sales Invoice': 'against_invoice',
- 'Purchase Invoice': 'against_voucher',
- 'Journal Entry': 'against_jv',
- 'Sales Order': 'against_sales_order',
- 'Purchase Order': 'against_purchase_order',
- }
jv = frappe.new_doc('Journal Entry')
jv.voucher_type = 'Journal Entry'
@@ -41,7 +34,8 @@
d1.party = self.party
d1.balance = get_balance_on(self.party_account)
d1.set("debit" if self.received_or_paid=="Paid" else "credit", flt(v.payment_amount))
- d1.set(invoice_voucher_type.get(v.against_voucher_type), v.against_voucher_no)
+ d1.set("reference_type", v.against_voucher_type)
+ d1.set("reference_name", v.against_voucher_no)
d1.set('is_advance', 'Yes' if v.against_voucher_type in ['Sales Order', 'Purchase Order'] else 'No')
total_payment_amount = flt(total_payment_amount) + flt(d1.debit) - flt(d1.credit)
diff --git a/erpnext/accounts/doctype/payment_tool/test_payment_tool.py b/erpnext/accounts/doctype/payment_tool/test_payment_tool.py
index a4ff333..321986c 100644
--- a/erpnext/accounts/doctype/payment_tool/test_payment_tool.py
+++ b/erpnext/accounts/doctype/payment_tool/test_payment_tool.py
@@ -23,10 +23,11 @@
# Create SO with partial outstanding
so1 = make_sales_order(customer="_Test Customer 3", qty=10, rate=100)
-
+
self.create_against_jv(jv_test_records[0], {
"party": "_Test Customer 3",
- "against_sales_order": so1.name,
+ "reference_type": "Sales Order",
+ "reference_name": so1.name,
"is_advance": "Yes"
})
@@ -36,7 +37,8 @@
self.create_against_jv(jv_test_records[0], {
"party": "_Test Customer 3",
- "against_sales_order": so2.name,
+ "reference_type": "Sales Order",
+ "reference_name": so2.name,
"credit": 1000,
"is_advance": "Yes"
})
@@ -52,7 +54,8 @@
self.create_against_jv(jv_test_records[0], {
"party": "_Test Customer 3",
- "against_invoice": si1.name
+ "reference_type": si1.doctype,
+ "reference_name": si1.name
})
#Create SI with no outstanding
si2 = self.create_voucher(si_test_records[0], {
@@ -62,7 +65,8 @@
self.create_against_jv(jv_test_records[0], {
"party": "_Test Customer 3",
- "against_invoice": si2.name,
+ "reference_type": si2.doctype,
+ "reference_name": si2.name,
"credit": 561.80
})
@@ -125,7 +129,7 @@
def make_voucher_for_party(self, args, expected_outstanding):
#Make Journal Entry for Party
payment_tool_doc = frappe.new_doc("Payment Tool")
-
+
for k, v in args.items():
payment_tool_doc.set(k, v)
@@ -153,29 +157,12 @@
new_jv = paytool.make_journal_entry()
- #Create a list of expected values as [party account, payment against, against_jv, against_invoice,
- #against_voucher, against_sales_order, against_purchase_order]
- expected_values = [
- [paytool.party_account, paytool.party, 100.00, expected_outstanding.get("Journal Entry")[0], None, None, None, None],
- [paytool.party_account, paytool.party, 100.00, None, expected_outstanding.get("Sales Invoice")[0], None, None, None],
- [paytool.party_account, paytool.party, 100.00, None, None, expected_outstanding.get("Purchase Invoice")[0], None, None],
- [paytool.party_account, paytool.party, 100.00, None, None, None, expected_outstanding.get("Sales Order")[0], None],
- [paytool.party_account, paytool.party, 100.00, None, None, None, None, expected_outstanding.get("Purchase Order")[0]]
- ]
-
for jv_entry in new_jv.get("accounts"):
if paytool.party_account == jv_entry.get("account") and paytool.party == jv_entry.get("party"):
- row = [
- jv_entry.get("account"),
- jv_entry.get("party"),
- jv_entry.get("debit" if paytool.party_type=="Supplier" else "credit"),
- jv_entry.get("against_jv"),
- jv_entry.get("against_invoice"),
- jv_entry.get("against_voucher"),
- jv_entry.get("against_sales_order"),
- jv_entry.get("against_purchase_order"),
- ]
- self.assertTrue(row in expected_values)
+ self.assertEquals(100.00,
+ jv_entry.get("debit" if paytool.party_type=="Supplier" else "credit"))
+ self.assertEquals(jv_entry.reference_name,
+ expected_outstanding[jv_entry.reference_type][0])
self.assertEquals(new_jv.get("cheque_no"), paytool.reference_no)
self.assertEquals(new_jv.get("cheque_date"), paytool.reference_date)
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 8e91250..6257865 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -21,16 +21,15 @@
// Show / Hide button
this.show_general_ledger();
-
+
if(!doc.is_return) {
if(doc.docstatus==1) {
if(doc.outstanding_amount > 0) {
- this.frm.add_custom_button(__('Make Payment Entry'), this.make_bank_entry);
+ this.frm.add_custom_button(__('Payment'), this.make_bank_entry).addClass("btn-primary");
}
-
- cur_frm.add_custom_button(__('Make Debit Note'), this.make_debit_note);
+ cur_frm.add_custom_button(__('Debit Note'), this.make_debit_note);
}
-
+
if(doc.docstatus===0) {
cur_frm.add_custom_button(__('From Purchase Order'), function() {
frappe.model.map_current_doc({
@@ -102,7 +101,7 @@
if(row.purchase_receipt) frappe.model.clear_doc("Purchase Receipt", row.purchase_receipt)
})
},
-
+
make_debit_note: function() {
frappe.model.open_mapped_doc({
method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_debit_note",
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 00ea6ae..132cb10 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -41,8 +41,8 @@
self.po_required()
self.pr_required()
self.validate_supplier_invoice()
- self.validate_advance_jv("advances", "purchase_order")
-
+ self.validate_advance_jv("Purchase Order")
+
self.check_active_purchase_items()
self.check_conversion_rate()
self.validate_credit_to_acc()
@@ -233,7 +233,7 @@
self.update_against_document_in_jv()
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
-
+
self.update_project()
def make_gl_entries(self):
@@ -365,7 +365,7 @@
def on_cancel(self):
if not self.is_return:
from erpnext.accounts.utils import remove_against_link_from_jv
- remove_against_link_from_jv(self.doctype, self.name, "against_voucher")
+ remove_against_link_from_jv(self.doctype, self.name)
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
@@ -413,4 +413,4 @@
@frappe.whitelist()
def make_debit_note(source_name, target_doc=None):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
- return make_return_doc("Purchase Invoice", source_name, target_doc)
\ No newline at end of file
+ return make_return_doc("Purchase Invoice", source_name, target_doc)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 017ab3a..caf741e 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -40,14 +40,17 @@
this._super();
cur_frm.dashboard.reset();
-
+
this.frm.toggle_reqd("due_date", !this.frm.doc.is_return);
-
+
this.show_general_ledger();
-
+
if(doc.update_stock) this.show_stock_ledger();
-
+
if(doc.docstatus==1 && !doc.is_return) {
+ cur_frm.add_custom_button(doc.update_stock ? __('Sales Return') : __('Credit Note'),
+ this.make_sales_return);
+
if(cint(doc.update_stock)!=1) {
// show Make Delivery Note button only if Sales Invoice is not created from Delivery Note
var from_delivery_note = false;
@@ -57,16 +60,13 @@
});
if(!from_delivery_note) {
- cur_frm.add_custom_button(__('Make Delivery'), cur_frm.cscript['Make Delivery Note'])
+ cur_frm.add_custom_button(__('Delivery'), cur_frm.cscript['Make Delivery Note']).addClass("btn-primary");
}
}
if(doc.outstanding_amount!=0 && !cint(doc.is_return)) {
- cur_frm.add_custom_button(__('Make Payment Entry'), cur_frm.cscript.make_bank_entry);
+ cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry).addClass("btn-primary");
}
-
- cur_frm.add_custom_button(doc.update_stock ? __('Make Sales Return') : __('Make Credit Note'),
- this.make_sales_return);
}
// Show buttons only when pos view is active
@@ -201,7 +201,7 @@
items_on_form_rendered: function() {
erpnext.setup_serial_no();
},
-
+
make_sales_return: function() {
frappe.model.open_mapped_doc({
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.make_sales_return",
@@ -390,4 +390,4 @@
['Account', 'account_type', '=', 'Receivable']
]
}
-});
\ No newline at end of file
+});
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 6d76b53..4285eb8 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -46,7 +46,7 @@
self.validate_debit_to_acc()
self.validate_fixed_asset_account()
self.clear_unallocated_advances("Sales Invoice Advance", "advances")
- self.validate_advance_jv("advances", "sales_order")
+ self.validate_advance_jv("Sales Order")
self.add_remarks()
self.validate_write_off_account()
@@ -105,7 +105,7 @@
self.check_stop_sales_order("sales_order")
from erpnext.accounts.utils import remove_against_link_from_jv
- remove_against_link_from_jv(self.doctype, self.name, "against_invoice")
+ remove_against_link_from_jv(self.doctype, self.name)
if not self.is_return:
self.update_status_updater_args()
@@ -420,7 +420,7 @@
for d in self.get_item_list():
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1 and d.warehouse and flt(d['qty']):
self.update_reserved_qty(d)
-
+
incoming_rate = 0
if cint(self.is_return) and self.return_against and self.docstatus==1:
incoming_rate = self.get_incoming_rate_for_sales_return(d.item_code,
@@ -447,7 +447,7 @@
if update_outstanding == "No":
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
- update_outstanding_amt(self.debit_to, "Customer", self.customer,
+ update_outstanding_amt(self.debit_to, "Customer", self.customer,
self.doctype, self.return_against if cint(self.is_return) else self.name)
if repost_future_gle and cint(self.update_stock) \
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 67f4a8e..c7a992c 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -391,7 +391,8 @@
import test_records as jv_test_records
jv = frappe.get_doc(frappe.copy_doc(jv_test_records[0]))
- jv.get("accounts")[0].against_invoice = w.name
+ jv.get("accounts")[0].reference_type = w.doctype
+ jv.get("accounts")[0].reference_name = w.name
jv.insert()
jv.submit()
@@ -656,17 +657,17 @@
si.load_from_db()
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
- where against_invoice=%s""", si.name))
+ where reference_name=%s""", si.name))
self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account`
- where against_invoice=%s and credit=300""", si.name))
+ where reference_name=%s and credit=300""", si.name))
self.assertEqual(si.outstanding_amount, 261.8)
si.cancel()
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Entry Account`
- where against_invoice=%s""", si.name))
+ where reference_name=%s""", si.name))
def test_recurring_invoice(self):
from erpnext.controllers.tests.test_recurring_document import test_recurring_document
@@ -728,68 +729,67 @@
# hack! because stock ledger entires are already inserted and are not rolled back!
self.assertRaises(SerialNoDuplicateError, si.cancel)
-
+
def test_invoice_due_date_against_customers_credit_days(self):
# set customer's credit days
frappe.db.set_value("Customer", "_Test Customer", "credit_days_based_on", "Fixed Days")
frappe.db.set_value("Customer", "_Test Customer", "credit_days", 10)
-
+
si = create_sales_invoice()
self.assertEqual(si.due_date, add_days(nowdate(), 10))
-
+
# set customer's credit days is last day of the next month
frappe.db.set_value("Customer", "_Test Customer", "credit_days_based_on", "Last Day of the Next Month")
-
- si1 = create_sales_invoice(posting_date="2015-07-05")
+
+ si1 = create_sales_invoice(posting_date="2015-07-05")
self.assertEqual(si1.due_date, "2015-08-31")
-
+
def test_return_sales_invoice(self):
set_perpetual_inventory()
-
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
-
+
actual_qty_0 = get_qty_after_transaction()
-
+
si = create_sales_invoice(qty=5, rate=500, update_stock=1)
actual_qty_1 = get_qty_after_transaction()
self.assertEquals(actual_qty_0 - 5, actual_qty_1)
-
+
# outgoing_rate
- outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Sales Invoice",
+ outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si.name}, "stock_value_difference") / 5
-
+
# return entry
si1 = create_sales_invoice(is_return=1, return_against=si.name, qty=-2, rate=500, update_stock=1)
actual_qty_2 = get_qty_after_transaction()
-
+
self.assertEquals(actual_qty_1 + 2, actual_qty_2)
-
- incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
- {"voucher_type": "Sales Invoice", "voucher_no": si1.name},
+
+ incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
+ {"voucher_type": "Sales Invoice", "voucher_no": si1.name},
["incoming_rate", "stock_value_difference"])
-
+
self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3)))
-
-
+
+
# Check gl entry
- gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
+ gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si1.name, "account": "_Test Warehouse - _TC"}, "debit")
-
+
self.assertEquals(gle_warehouse_amount, stock_value_difference)
-
- party_credited = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
+
+ party_credited = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si1.name, "account": "Debtors - _TC", "party": "_Test Customer"}, "credit")
-
+
self.assertEqual(party_credited, 1000)
-
+
# Check outstanding amount
self.assertFalse(si1.outstanding_amount)
self.assertEqual(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"), 1500)
-
+
set_perpetual_inventory(0)
-
+
def test_discount_on_net_total(self):
si = frappe.copy_doc(test_records[2])
si.apply_discount_on = "Net Total"
@@ -798,7 +798,7 @@
expected_values = {
"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
- "base_price_list_rate", "base_rate", "base_amount",
+ "base_price_list_rate", "base_rate", "base_amount",
"net_rate", "base_net_rate", "net_amount", "base_net_amount"],
"_Test Item Home Desktop 100": [50, 0, 50, 500, 50, 50, 500, 25, 25, 250, 250],
"_Test Item Home Desktop 200": [150, 0, 150, 750, 150, 150, 750, 75, 75, 375, 375],
@@ -821,7 +821,7 @@
# check tax calculation
expected_values = {
- "keys": ["tax_amount", "tax_amount_after_discount_amount",
+ "keys": ["tax_amount", "tax_amount_after_discount_amount",
"base_tax_amount_after_discount_amount"],
"_Test Account Shipping Charges - _TC": [100, 100, 100],
"_Test Account Customs Duty - _TC": [62.5, 62.5, 62.5],
@@ -836,12 +836,12 @@
for d in si.get("taxes"):
for i, k in enumerate(expected_values["keys"]):
self.assertEquals(d.get(k), expected_values[d.account_head][i])
-
-
+
+
self.assertEquals(si.total_taxes_and_charges, 234.44)
self.assertEquals(si.base_grand_total, 859.44)
self.assertEquals(si.grand_total, 859.44)
-
+
def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice")
diff --git a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
index 699d684..604bc56 100644
--- a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
+++ b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
@@ -15,21 +15,19 @@
entries = get_entries(filters)
invoice_posting_date_map = get_invoice_posting_date_map(filters)
against_date = ""
- outstanding_amount = 0.0
data = []
for d in entries:
- if d.against_voucher:
- against_date = d.against_voucher and invoice_posting_date_map[d.against_voucher] or ""
+ against_date = invoice_posting_date_map[d.reference_name] or ""
+ if d.reference_type=="Purchase Invoice":
payment_amount = flt(d.debit) or -1 * flt(d.credit)
else:
- against_date = d.against_invoice and invoice_posting_date_map[d.against_invoice] or ""
payment_amount = flt(d.credit) or -1 * flt(d.debit)
- row = [d.name, d.party_type, d.party, d.posting_date, d.against_voucher or d.against_invoice,
+ row = [d.name, d.party_type, d.party, d.posting_date, d.reference_name,
against_date, d.debit, d.credit, d.cheque_no, d.cheque_date, d.remark]
- if d.against_voucher or d.against_invoice:
+ if d.reference_name:
row += get_ageing_data(30, 60, 90, d.posting_date, against_date, payment_amount)
else:
row += ["", "", "", "", ""]
@@ -82,7 +80,7 @@
def get_entries(filters):
conditions = get_conditions(filters)
entries = frappe.db.sql("""select jv.name, jvd.party_type, jvd.party, jv.posting_date,
- jvd.against_voucher, jvd.against_invoice, jvd.debit, jvd.credit,
+ jvd.reference_type, jvd.reference_name, jvd.debit, jvd.credit,
jv.cheque_no, jv.cheque_date, jv.remark
from `tabJournal Entry Account` jvd, `tabJournal Entry` jv
where jvd.parent = jv.name and jv.docstatus=1 %s order by jv.name DESC""" %
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 298ff8e..f41d19d 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -142,13 +142,6 @@
for d in args:
check_if_jv_modified(d)
validate_allocated_amount(d)
- against_fld = {
- 'Journal Entry' : 'against_jv',
- 'Sales Invoice' : 'against_invoice',
- 'Purchase Invoice' : 'against_voucher'
- }
-
- d['against_fld'] = against_fld[d['against_voucher_type']]
# cancel JV
jv_obj = frappe.get_doc('Journal Entry', d['voucher_no'])
@@ -173,8 +166,7 @@
select t2.{dr_or_cr} from `tabJournal Entry` t1, `tabJournal Entry Account` t2
where t1.name = t2.parent and t2.account = %(account)s
and t2.party_type = %(party_type)s and t2.party = %(party)s
- and ifnull(t2.against_voucher, '')=''
- and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')=''
+ and ifnull(t2.reference_type, '') in ("", "Sales Order", "Purchase Order")
and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s
and t1.docstatus=1 """.format(dr_or_cr = args.get("dr_or_cr")), args)
@@ -193,7 +185,12 @@
"""
jv_detail = jv_obj.get("accounts", {"name": d["voucher_detail_no"]})[0]
jv_detail.set(d["dr_or_cr"], d["allocated_amt"])
- jv_detail.set(d["against_fld"], d["against_voucher"])
+
+ original_reference_type = jv_detail.reference_type
+ original_reference_name = jv_detail.reference_name
+
+ jv_detail.set("reference_type", d["against_voucher_type"])
+ jv_detail.set("reference_name", d["against_voucher"])
if d['allocated_amt'] < d['unadjusted_amt']:
jvd = frappe.db.sql("""select cost_center, balance, against_account, is_advance
@@ -208,6 +205,8 @@
ch.set(d['dr_or_cr'], flt(d['unadjusted_amt']) - flt(d['allocated_amt']))
ch.set(d['dr_or_cr']== 'debit' and 'credit' or 'debit', 0)
ch.against_account = cstr(jvd[0][2])
+ ch.reference_type = original_reference_type
+ ch.reference_name = original_reference_name
ch.is_advance = cstr(jvd[0][3])
ch.docstatus = 1
@@ -215,15 +214,16 @@
jv_obj.flags.ignore_validate_update_after_submit = True
jv_obj.save()
-def remove_against_link_from_jv(ref_type, ref_no, against_field):
+def remove_against_link_from_jv(ref_type, ref_no):
linked_jv = frappe.db.sql_list("""select parent from `tabJournal Entry Account`
- where `%s`=%s and docstatus < 2""" % (against_field, "%s"), (ref_no))
+ where reference_type=%s and reference_name=%s and docstatus < 2""", (ref_type, ref_no))
if linked_jv:
- frappe.db.sql("""update `tabJournal Entry Account` set `%s`=null,
+ frappe.db.sql("""update `tabJournal Entry Account`
+ set reference_type=null, reference_name = null,
modified=%s, modified_by=%s
- where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"),
- (now(), frappe.session.user, ref_no))
+ where reference_type=%s and reference_name=%s
+ and docstatus < 2""", (now(), frappe.session.user, ref_type, ref_no))
frappe.db.sql("""update `tabGL Entry`
set against_voucher_type=null, against_voucher=null,
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 09a0e91..a5cd6ce 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -5,6 +5,14 @@
{% include 'buying/doctype/purchase_common/purchase_common.js' %};
+frappe.ui.form.on("Purchase Order", {
+ onload: function(frm) {
+ erpnext.queries.setup_queries(frm, "Warehouse", function() {
+ return erpnext.queries.warehouse(frm.doc);
+ });
+ }
+});
+
erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
refresh: function(doc, cdt, cdn) {
var me = this;
@@ -12,31 +20,38 @@
// this.frm.dashboard.reset();
if(doc.docstatus == 1 && doc.status != 'Stopped') {
+
+ if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100)
+ cur_frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Purchase Order']);
+
+ if(flt(doc.per_billed)==0) {
+ cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry);
+ }
+
if(flt(doc.per_received, 2) < 100) {
- cur_frm.add_custom_button(__('Make Purchase Receipt'), this.make_purchase_receipt);
-
+ cur_frm.add_custom_button(__('Receive'), this.make_purchase_receipt).addClass("btn-primary");
+
if(doc.is_subcontracted==="Yes") {
cur_frm.add_custom_button(__('Transfer Material to Supplier'), this.make_stock_entry);
}
}
+
if(flt(doc.per_billed, 2) < 100)
- cur_frm.add_custom_button(__('Make Invoice'), this.make_purchase_invoice);
-
- if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100)
- cur_frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Purchase Order']);
+ cur_frm.add_custom_button(__('Invoice'), this.make_purchase_invoice);
+
} else if(doc.docstatus===0) {
cur_frm.cscript.add_from_mappers();
}
if(doc.docstatus == 1 && doc.status == 'Stopped')
- cur_frm.add_custom_button(__('Unstop Purchase Order'), cur_frm.cscript['Unstop Purchase Order']);
+ cur_frm.add_custom_button(__('Unstop'), cur_frm.cscript['Unstop Purchase Order']);
},
make_stock_entry: function() {
var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
var me = this;
-
+
if(items.length===1) {
me._make_stock_entry(items[0]);
return;
@@ -126,7 +141,21 @@
items_add: function(doc, cdt, cdn) {
var row = frappe.get_doc(cdt, cdn);
this.frm.script_manager.copy_from_first_row("items", row, ["schedule_date"]);
+ },
+
+ make_bank_entry: function() {
+ return frappe.call({
+ method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_from_purchase_order",
+ args: {
+ "purchase_order": cur_frm.doc.name
+ },
+ callback: function(r) {
+ var doclist = frappe.model.sync(r.message);
+ frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
+ }
+ });
}
+
});
// for backward compatibility: combine new and previous states
diff --git a/erpnext/change_log/current/journal_entry_rename.md b/erpnext/change_log/current/journal_entry_rename.md
new file mode 100644
index 0000000..9bd1b66
--- /dev/null
+++ b/erpnext/change_log/current/journal_entry_rename.md
@@ -0,0 +1 @@
+- For referencing a line in **Journal Entry**, now you can reference by the **Reference Type** and **Reference Name** columns, instead of "Against Sales Invoice", "Against Purchase Invoice", etc.
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 915d294..ecd9e1a 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -211,29 +211,32 @@
and ifnull(allocated_amount, 0) = 0""" % (childtype, '%s', '%s'), (parentfield, self.name))
def get_advances(self, account_head, party_type, party, child_doctype, parentfield, dr_or_cr, against_order_field):
- so_list = list(set([d.get(against_order_field) for d in self.get("items") if d.get(against_order_field)]))
- cond = ""
- if so_list:
- cond = "or (ifnull(t2.%s, '') in (%s))" % ("against_" + against_order_field, ', '.join(['%s']*len(so_list)))
+ """Returns list of advances against Account, Party, Reference"""
+ order_list = list(set([d.get(against_order_field) for d in self.get("items") if d.get(against_order_field)]))
+
+ if not order_list:
+ return
+
+ in_placeholder = ', '.join(['%s'] * len(order_list))
+
+ # conver sales_order to "Sales Order"
+ reference_type = against_order_field.replace("_", " ").title()
res = frappe.db.sql("""
select
- t1.name as jv_no, t1.remark, t2.{0} as amount, t2.name as jv_detail_no, `against_{1}` as against_order
+ t1.name as jv_no, t1.remark, t2.{0} as amount, t2.name as jv_detail_no,
+ reference_name as against_order
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where
t1.name = t2.parent and t2.account = %s
- and t2.party_type=%s and t2.party=%s
+ and t2.party_type = %s and t2.party = %s
and t2.is_advance = 'Yes' and t1.docstatus = 1
- and ((
- ifnull(t2.against_voucher, '') = ''
- and ifnull(t2.against_invoice, '') = ''
- and ifnull(t2.against_jv, '') = ''
- and ifnull(t2.against_sales_order, '') = ''
- and ifnull(t2.against_purchase_order, '') = ''
- ) {2})
- order by t1.posting_date""".format(dr_or_cr, against_order_field, cond),
- [account_head, party_type, party] + so_list, as_dict=1)
+ and (
+ ifnull(t2.reference_type, '')=''
+ or (t2.reference_type = %s and ifnull(t2.reference_name, '') in ({1})))
+ order by t1.posting_date""".format(dr_or_cr, in_placeholder),
+ [account_head, party_type, party, reference_type] + order_list, as_dict=1)
self.set(parentfield, [])
for d in res:
@@ -246,25 +249,26 @@
"allocated_amount": flt(d.amount) if d.against_order else 0
})
- def validate_advance_jv(self, advance_table_fieldname, against_order_field):
+ def validate_advance_jv(self, reference_type):
+ against_order_field = frappe.scrub(reference_type)
order_list = list(set([d.get(against_order_field) for d in self.get("items") if d.get(against_order_field)]))
if order_list:
account = self.get("debit_to" if self.doctype=="Sales Invoice" else "credit_to")
- jv_against_order = frappe.db.sql("""select parent, %s as against_order
+ jv_against_order = frappe.db.sql("""select parent, reference_name as against_order
from `tabJournal Entry Account`
where docstatus=1 and account=%s and ifnull(is_advance, 'No') = 'Yes'
- and ifnull(against_sales_order, '') in (%s)
- group by parent, against_sales_order""" %
- ("against_" + against_order_field, '%s', ', '.join(['%s']*len(order_list))),
- tuple([account] + order_list), as_dict=1)
+ and reference_type=%s
+ and ifnull(reference_name, '') in ({0})
+ group by parent, reference_name""".format(', '.join(['%s']*len(order_list))),
+ tuple([account, reference_type] + order_list), as_dict=1)
if jv_against_order:
order_jv_map = {}
for d in jv_against_order:
order_jv_map.setdefault(d.against_order, []).append(d.parent)
- advance_jv_against_si = [d.journal_entry for d in self.get(advance_table_fieldname)]
+ advance_jv_against_si = [d.journal_entry for d in self.get("advances")]
for order, jv_list in order_jv_map.items():
for jv in jv_list:
@@ -318,10 +322,8 @@
def set_total_advance_paid(self):
if self.doctype == "Sales Order":
dr_or_cr = "credit"
- against_field = "against_sales_order"
else:
dr_or_cr = "debit"
- against_field = "against_purchase_order"
advance_paid = frappe.db.sql("""
select
@@ -329,8 +331,10 @@
from
`tabJournal Entry Account`
where
- {against_field} = %s and docstatus = 1 and is_advance = "Yes" """.format(dr_or_cr=dr_or_cr, \
- against_field=against_field), self.name)
+ reference_type = %s and
+ reference_name = %s and
+ docstatus = 1 and is_advance = "Yes" """.format(dr_or_cr=dr_or_cr),
+ (self.doctype, self.name))
if advance_paid:
advance_paid = flt(advance_paid[0][0], self.precision("advance_paid"))
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index a56929d..1d405da 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -24,13 +24,15 @@
var d1 = frappe.model.add_child(jv, 'Journal Entry Account', 'accounts');
d1.debit = expense[i].sanctioned_amount;
d1.account = expense[i].default_account;
- d1.against_expense_claim = cur_frm.doc.name;
+ d1.reference_type = cur_frm.doc.doctype;
+ d1.reference_name = cur_frm.doc.name;
}
// credit to bank
var d1 = frappe.model.add_child(jv, 'Journal Entry Account', 'accounts');
d1.credit = cur_frm.doc.total_sanctioned_amount;
- d1.against_expense_claim = cur_frm.doc.name;
+ d1.reference_type = cur_frm.doc.doctype;
+ d1.reference_name = cur_frm.doc.name;
if(r.message) {
d1.account = r.message.account;
d1.balance = r.message.balance;
@@ -179,5 +181,5 @@
filters:{
'project': doc.project
}
- }
-}
\ No newline at end of file
+ }
+}
diff --git a/erpnext/patches/v5_4/cleanup_journal_entry.py b/erpnext/patches/v5_4/cleanup_journal_entry.py
new file mode 100644
index 0000000..9968e3c
--- /dev/null
+++ b/erpnext/patches/v5_4/cleanup_journal_entry.py
@@ -0,0 +1,14 @@
+import frappe
+
+def execute():
+ for doctype, fieldname in (
+ ("Sales Invoice", "against_invoice"),
+ ("Purchase Invoice", "against_voucher"),
+ ("Sales Order", "against_sales_order"),
+ ("Purchase Order", "against_purchase_order"),
+ ("Journal Entry", "against_jv"),
+ ("Expense Claim", "against_expense_claim"),
+ ):
+ frappe.db.update("""update `tabJournal Entry Detail`
+ set reference_type=%s and reference_name={0} where ifnull({0}, '') != ''
+ """.format(fieldname), doctype)
diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js
index f5f7aa0..ff5cf53 100644
--- a/erpnext/public/js/controllers/stock_controller.js
+++ b/erpnext/public/js/controllers/stock_controller.js
@@ -12,31 +12,8 @@
},
setup_warehouse_query: function() {
- var me = this;
- var warehouse_query_method = function() {
+ erpnext.queries.setup_queries(me.frm, "Warehouse", function() {
return erpnext.queries.warehouse(me.frm.doc);
- };
-
- var _set_warehouse_query = function(doctype, parentfield) {
- var warehouse_link_fields = frappe.meta.get_docfields(doctype, me.frm.doc.name,
- {"fieldtype": "Link", "options": "Warehouse"});
- $.each(warehouse_link_fields, function(i, df) {
- if(parentfield) {
- me.frm.set_query(df.fieldname, parentfield, warehouse_query_method);
- } else {
- me.frm.set_query(df.fieldname, warehouse_query_method);
- }
- });
- };
-
- _set_warehouse_query(me.frm.doc.doctype);
-
- // warehouse field in tables
- var table_fields = frappe.meta.get_docfields(me.frm.doc.doctype, me.frm.doc.name,
- {"fieldtype": "Table"});
-
- $.each(table_fields, function(i, df) {
- _set_warehouse_query(df.options, df.fieldname);
});
},
diff --git a/erpnext/public/js/queries.js b/erpnext/public/js/queries.js
index b487c23..12307fb 100644
--- a/erpnext/public/js/queries.js
+++ b/erpnext/public/js/queries.js
@@ -75,3 +75,26 @@
}
}
});
+
+erpnext.queries.setup_queries = function(frm, options, query_fn) {
+ var me = this;
+ var set_query = function(doctype, parentfield) {
+ var link_fields = frappe.meta.get_docfields(doctype, frm.doc.name,
+ {"fieldtype": "Link", "options": options});
+ $.each(link_fields, function(i, df) {
+ if(parentfield) {
+ frm.set_query(df.fieldname, parentfield, query_fn);
+ } else {
+ frm.set_query(df.fieldname, query_fn);
+ }
+ });
+ };
+
+ set_query(frm.doc.doctype);
+
+ // warehouse field in tables
+ $.each(frappe.meta.get_docfields(frm.doc.doctype, frm.doc.name, {"fieldtype": "Table"}),
+ function(i, df) {
+ set_query(df.options, df.fieldname);
+ });
+}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index d06d550..4a047e4 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -3,6 +3,14 @@
{% include 'selling/sales_common.js' %}
+frappe.ui.form.on("Sales Order", {
+ onload: function(frm) {
+ erpnext.queries.setup_queries(frm, "Warehouse", function() {
+ return erpnext.queries.warehouse(frm.doc);
+ });
+ }
+});
+
erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({
refresh: function(doc, dt, dn) {
this._super();
@@ -16,29 +24,32 @@
// cur_frm.dashboard.add_progress(cint(doc.per_billed) + __("% Billed"),
// doc.per_billed);
- // delivery note
- if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1)
- cur_frm.add_custom_button(__('Make Delivery'), this.make_delivery_note);
-
// indent
if(!doc.order_type || ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1)
- cur_frm.add_custom_button(__('Make ') + __('Material Request'),
- this.make_material_request);
+ cur_frm.add_custom_button(__('Material Request'), this.make_material_request);
- // sales invoice
- if(flt(doc.per_billed, 2) < 100) {
- cur_frm.add_custom_button(__('Make Invoice'), this.make_sales_invoice);
+ if(flt(doc.per_billed)==0) {
+ cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry);
}
// stop
if(flt(doc.per_delivered, 2) < 100 || doc.per_billed < 100)
cur_frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Sales Order'])
- // maintenance
- if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
- cur_frm.add_custom_button(__('Make Maint. Visit'), this.make_maintenance_visit);
- cur_frm.add_custom_button(__('Make Maint. Schedule'), this.make_maintenance_schedule);
- }
+ // maintenance
+ if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
+ cur_frm.add_custom_button(__('Maint. Visit'), this.make_maintenance_visit);
+ cur_frm.add_custom_button(__('Maint. Schedule'), this.make_maintenance_schedule);
+ }
+
+ // delivery note
+ if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1)
+ cur_frm.add_custom_button(__('Delivery'), this.make_delivery_note).addClass("btn-primary");
+
+ // sales invoice
+ if(flt(doc.per_billed, 2) < 100) {
+ cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary");
+ }
} else {
// un-stop
@@ -122,6 +133,20 @@
frm: cur_frm
})
},
+
+ make_bank_entry: function() {
+ return frappe.call({
+ method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_from_sales_order",
+ args: {
+ "sales_order": cur_frm.doc.name
+ },
+ callback: function(r) {
+ var doclist = frappe.model.sync(r.message);
+ frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
+ }
+ });
+ }
+
});
// for backward compatibility: combine new and previous states
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 94356da..e7ede65 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -8,28 +8,28 @@
erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend({
refresh: function(doc, dt, dn) {
this._super();
-
+
if (!doc.is_return) {
if(doc.__onload && !doc.__onload.billing_complete && doc.docstatus==1) {
// show Make Invoice button only if Delivery Note is not created from Sales Invoice
var from_sales_invoice = false;
from_sales_invoice = cur_frm.doc.items.some(function(item) {
- return item.against_sales_invoice ? true : false;
- });
+ return item.against_sales_invoice ? true : false;
+ });
if(!from_sales_invoice)
- cur_frm.add_custom_button(__('Make Invoice'), this.make_sales_invoice);
+ cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary");
}
if(flt(doc.per_installed, 2) < 100 && doc.docstatus==1)
- cur_frm.add_custom_button(__('Make Installation Note'), this.make_installation_note);
+ cur_frm.add_custom_button(__('Installation Note'), this.make_installation_note);
if (doc.docstatus==1) {
- cur_frm.add_custom_button(__('Make Sales Return'), this.make_sales_return);
+ cur_frm.add_custom_button(__('Sales Return'), this.make_sales_return);
}
if(doc.docstatus==0 && !doc.__islocal) {
- cur_frm.add_custom_button(__('Make Packing Slip'),
+ cur_frm.add_custom_button(__('Packing Slip'),
cur_frm.cscript['Make Packing Slip'], frappe.boot.doctype_icons["Packing Slip"]);
}
@@ -51,15 +51,15 @@
});
}
}
-
+
if (doc.docstatus==1) {
this.show_stock_ledger();
if (cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
this.show_general_ledger();
}
}
-
-
+
+
erpnext.stock.delivery_note.set_print_hide(doc, dt, dn);
@@ -81,7 +81,7 @@
frm: cur_frm
});
},
-
+
make_sales_return: function() {
frappe.model.open_mapped_doc({
method: "erpnext.stock.doctype.delivery_note.delivery_note.make_sales_return",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index fcaf9f8..38b054c 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -50,16 +50,15 @@
})
});
}
-
+
if(this.frm.doc.docstatus == 1) {
+ cur_frm.add_custom_button(__('Return'), this.make_purchase_return);
if(this.frm.doc.__onload && !this.frm.doc.__onload.billing_complete) {
- cur_frm.add_custom_button(__('Make Purchase Invoice'), this.make_purchase_invoice);
+ cur_frm.add_custom_button(__('Invoice'), this.make_purchase_invoice).addClass("btn-primary");
}
-
- cur_frm.add_custom_button(__('Make Purchase Return'), this.make_purchase_return);
}
}
-
+
this.frm.toggle_reqd("supplier_warehouse", this.frm.doc.is_subcontracted==="Yes");
},
@@ -111,7 +110,7 @@
frm: cur_frm
})
},
-
+
make_purchase_return: function() {
frappe.model.open_mapped_doc({
method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return",