diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index 7cd27977d0..dab2d82092 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -25,7 +25,8 @@ class GLEntry(Document): validate_balance_type(self.account, adv_adj) # Update outstanding amt on against voucher - if self.against_voucher and update_outstanding == 'Yes': + if self.against_voucher_type in ['Journal Voucher', 'Sales Invoice', 'Purchase Invoice'] \ + and self.against_voucher and update_outstanding == 'Yes': update_outstanding_amt(self.account, self.against_voucher_type, self.against_voucher) diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py index 03bedc708d..7bf6fcc54e 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe from frappe.utils import cint, cstr, flt, fmt_money, formatdate, getdate -from frappe import msgprint, _ +from frappe import msgprint, _, scrub from erpnext.setup.utils import get_company_currency from erpnext.controllers.accounts_controller import AccountsController @@ -35,18 +35,35 @@ class JournalVoucher(AccountsController): self.create_remarks() self.set_aging_date() self.set_print_format_fields() + self.validate_against_sales_order() + self.validate_against_purchase_order() def on_submit(self): if self.voucher_type in ['Bank Voucher', 'Contra Voucher', 'Journal Entry']: self.check_credit_days() self.make_gl_entries() self.check_credit_limit() + self.update_advance_paid() + + def update_advance_paid(self): + advance_paid = frappe._dict() + for d in self.get("entries"): + 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) + + for voucher_type, order_list in advance_paid.items(): + for voucher_no in list(set(order_list)): + frappe.get_doc(voucher_type, voucher_no).set_total_advance_paid() 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") self.make_gl_entries(1) + self.update_advance_paid() def validate_cheque_info(self): if self.voucher_type in ['Bank Voucher']: @@ -64,7 +81,8 @@ class JournalVoucher(AccountsController): master_type = frappe.db.get_value("Account", d.account, "master_type") if (master_type == 'Customer' and flt(d.credit) > 0) or \ (master_type == 'Supplier' and flt(d.debit) > 0): - msgprint(_("Please check 'Is Advance' against Account {0} if this is an advance entry.").format(d.account)) + msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this \ + is an advance entry.").format(d.idx, d.account)) def validate_against_jv(self): for d in self.get('entries'): @@ -90,24 +108,86 @@ class JournalVoucher(AccountsController): .format(d.against_jv, dr_or_cr)) def validate_against_sales_invoice(self): - for d in self.get("entries"): - if d.against_invoice: - if d.debit > 0: - frappe.throw(_("Row {0}: Debit entry can not be linked with a Sales Invoice") - .format(d.idx)) - if frappe.db.get_value("Sales Invoice", d.against_invoice, "debit_to") != d.account: - frappe.throw(_("Row {0}: Account does not match with \ - Sales Invoice Debit To account").format(d.idx, d.account)) + payment_against_voucher = self.validate_account_in_against_voucher("against_invoice", "Sales Invoice") + self.validate_against_invoice_fields("Sales Invoice", payment_against_voucher) def validate_against_purchase_invoice(self): + payment_against_voucher = self.validate_account_in_against_voucher("against_voucher", "Purchase Invoice") + self.validate_against_invoice_fields("Purchase Invoice", payment_against_voucher) + + 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': "Debit To", + 'Purchase Invoice': "Credit To", + 'Sales Order': "Customer", + 'Purchase Order': "Supplier" + } + for d in self.get("entries"): - if d.against_voucher: - if flt(d.credit) > 0: - frappe.throw(_("Row {0}: Credit entry can not be linked with a Purchase Invoice") - .format(d.idx)) - if frappe.db.get_value("Purchase Invoice", d.against_voucher, "credit_to") != d.account: - frappe.throw(_("Row {0}: Account does not match with \ - Purchase Invoice Credit To account").format(d.idx, d.account)) + if d.get(against_field): + dr_or_cr = "credit" if against_field in ["against_invoice", "against_sales_order"] \ + else "debit" + if against_field in ["against_invoice", "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 in ["against_voucher", "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)) + + voucher_account = frappe.db.get_value(doctype, d.get(against_field), \ + scrub(field_dict.get(doctype))) + + account_master_name = frappe.db.get_value("Account", d.account, "master_name") + + if against_field in ["against_invoice", "against_voucher"] \ + and voucher_account != d.account: + frappe.throw(_("Row {0}: Account {1} does not match with {2} {3} account") \ + .format(d.idx, d.account, doctype, field_dict.get(doctype))) + + if against_field in ["against_sales_order", "against_purchase_order"]: + if voucher_account != account_master_name: + frappe.throw(_("Row {0}: Account {1} does not match with {2} {3} Name") \ + .format(d.idx, d.account, doctype, field_dict.get(doctype))) + elif d.is_advance == "Yes": + payment_against_voucher.setdefault(d.get(against_field), []).append(flt(d.get(dr_or_cr))) + + return payment_against_voucher + + 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"]) + + if voucher_properties[0] != 1: + frappe.throw(_("{0} {1} is not submitted").format(doctype, voucher_no)) + + 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])) + + 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", "advance_paid", "grand_total"]) + + if voucher_properties[0] != 1: + frappe.throw(_("{0} {1} is not submitted").format(doctype, voucher_no)) + + if flt(voucher_properties[1]) >= 100: + frappe.throw(_("{0} {1} is fully billed").format(doctype, voucher_no)) + + if flt(voucher_properties[3]) < flt(voucher_properties[2]) + 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])) def set_against_account(self): accounts_debited, accounts_credited = [], [] @@ -147,7 +227,13 @@ class JournalVoucher(AccountsController): for d in self.get('entries'): if d.against_invoice and d.credit: currency = frappe.db.get_value("Sales Invoice", d.against_invoice, "currency") - r.append(_("{0} {1} against Invoice {2}").format(currency, fmt_money(flt(d.credit)), d.against_invoice)) + r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = currency), \ + d.against_invoice)) + + if d.against_sales_order and d.credit: + currency = frappe.db.get_value("Sales Order", d.against_sales_order, "currency") + r.append(_("{0} against Sales Order {1}").format(fmt_money(flt(d.credit), currency = currency), \ + d.against_sales_order)) if d.against_voucher and d.debit: bill_no = frappe.db.sql("""select bill_no, bill_date, currency @@ -158,13 +244,17 @@ class JournalVoucher(AccountsController): fmt_money(flt(d.debit)), 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: + currency = frappe.db.get_value("Purchase Order", d.against_purchase_order, "currency") + r.append(_("{0} against Purchase Order {1}").format(fmt_money(flt(d.credit), currency = currency), \ + d.against_purchase_order)) + if self.user_remark: r.append(_("Note: {0}").format(self.user_remark)) if r: - self.remark = ("\n").join(r) - else: - frappe.msgprint(_("User Remarks is mandatory"), raise_exception=frappe.MandatoryError) + self.remark = ("\n").join(r) #User Remarks is not mandatory + def set_aging_date(self): if self.is_opening != 'Yes': @@ -264,14 +354,18 @@ class JournalVoucher(AccountsController): "against": d.against_account, "debit": flt(d.debit, self.precision("debit", "entries")), "credit": flt(d.credit, self.precision("credit", "entries")), - "against_voucher_type": ((d.against_voucher and "Purchase Invoice") - or (d.against_invoice and "Sales Invoice") - or (d.against_jv and "Journal Voucher")), - "against_voucher": d.against_voucher or d.against_invoice or d.against_jv, + "against_voucher_type": (("Purchase Invoice" if d.against_voucher else None) + or ("Sales Invoice" if d.against_invoice else None) + or ("Journal Voucher" 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, "remarks": self.remark, "cost_center": d.cost_center }) ) + if gl_map: make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj) diff --git a/erpnext/accounts/doctype/journal_voucher/test_journal_voucher.py b/erpnext/accounts/doctype/journal_voucher/test_journal_voucher.py index 425baf16f4..2aac2b6942 100644 --- a/erpnext/accounts/doctype/journal_voucher/test_journal_voucher.py +++ b/erpnext/accounts/doctype/journal_voucher/test_journal_voucher.py @@ -1,41 +1,88 @@ # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # License: GNU General Public License v3. See license.txt - from __future__ import unicode_literals -import unittest -import frappe +import unittest, frappe +from frappe.utils import flt class TestJournalVoucher(unittest.TestCase): def test_journal_voucher_with_against_jv(self): - self.clear_account_balance() + jv_invoice = frappe.copy_doc(test_records[2]) - jv_invoice.insert() - jv_invoice.submit() + base_jv = frappe.copy_doc(test_records[0]) + self.jv_against_voucher_testcase(base_jv, jv_invoice) - self.assertTrue(frappe.db.sql("""select name from `tabJournal Voucher Detail` - where account = %s and docstatus = 1 and parent = %s""", - ("_Test Customer - _TC", jv_invoice.name))) + def test_jv_against_sales_order(self): + from erpnext.selling.doctype.sales_order.test_sales_order \ + import test_records as so_test_records + + sales_order = frappe.copy_doc(so_test_records[0]) + base_jv = frappe.copy_doc(test_records[0]) + self.jv_against_voucher_testcase(base_jv, sales_order) + + def test_jv_against_purchase_order(self): + from erpnext.buying.doctype.purchase_order.test_purchase_order \ + import test_records as po_test_records + + purchase_order = frappe.copy_doc(po_test_records[0]) + base_jv = frappe.copy_doc(test_records[1]) + self.jv_against_voucher_testcase(base_jv, purchase_order) + + def jv_against_voucher_testcase(self, base_jv, test_voucher): + dr_or_cr = "credit" if test_voucher.doctype in ["Sales Order", "Journal Voucher"] else "debit" + field_dict = {'Journal Voucher': "against_jv", + 'Sales Order': "against_sales_order", + 'Purchase Order': "against_purchase_order" + } + + self.clear_account_balance() + test_voucher.insert() + test_voucher.submit() + + if test_voucher.doctype == "Journal Voucher": + self.assertTrue(frappe.db.sql("""select name from `tabJournal Voucher Detail` + where account = %s and docstatus = 1 and parent = %s""", + ("_Test Customer - _TC", test_voucher.name))) self.assertTrue(not frappe.db.sql("""select name from `tabJournal Voucher Detail` - where against_jv=%s""", jv_invoice.name)) + where %s=%s""" % (field_dict.get(test_voucher.doctype), '%s'), (test_voucher.name))) - jv_payment = frappe.copy_doc(test_records[0]) - jv_payment.get("entries")[0].against_jv = jv_invoice.name - jv_payment.insert() - jv_payment.submit() + base_jv.get("entries")[0].is_advance = "Yes" if (test_voucher.doctype in ["Sales Order", "Purchase Order"]) else "No" + base_jv.get("entries")[0].set(field_dict.get(test_voucher.doctype), 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 Voucher Detail` - where against_jv=%s""", jv_invoice.name)) + where %s=%s""" % (field_dict.get(test_voucher.doctype), '%s'), (submitted_voucher.name))) self.assertTrue(frappe.db.sql("""select name from `tabJournal Voucher Detail` - where against_jv=%s and credit=400""", jv_invoice.name)) + where %s=%s and %s=400""" % (field_dict.get(submitted_voucher.doctype), '%s', dr_or_cr), (submitted_voucher.name))) - # cancel jv_invoice - jv_invoice.cancel() + if base_jv.get("entries")[0].is_advance == "Yes": + self.advance_paid_testcase(base_jv, submitted_voucher, dr_or_cr) + self.cancel_against_voucher_testcase(submitted_voucher) - self.assertTrue(not frappe.db.sql("""select name from `tabJournal Voucher Detail` - where against_jv=%s""", jv_invoice.name)) + def advance_paid_testcase(self, base_jv, test_voucher, dr_or_cr): + #Test advance paid field + advance_paid = frappe.db.sql("""select advance_paid from `tab%s` + where name=%s""" % (test_voucher.doctype, '%s'), (test_voucher.name)) + payment_against_order = base_jv.get("entries")[0].get(dr_or_cr) + + self.assertTrue(flt(advance_paid[0][0]) == flt(payment_against_order)) + + def cancel_against_voucher_testcase(self, test_voucher): + if test_voucher.doctype == "Journal Voucher": + # if test_voucher is a Journal Voucher, test cancellation of test_voucher + test_voucher.cancel() + self.assertTrue(not frappe.db.sql("""select name from `tabJournal Voucher Detail` + where against_jv=%s""", test_voucher.name)) + + elif test_voucher.doctype in ["Sales Order", "Purchase Order"]: + # if test_voucher is a Sales Order/Purchase Order, test error on cancellation of test_voucher + submitted_voucher = frappe.get_doc(test_voucher.doctype, test_voucher.name) + self.assertRaises(frappe.LinkExistsError, submitted_voucher.cancel) def test_jv_against_stock_account(self): from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory diff --git a/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json b/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json index a751ed9c66..2f15b0ba1e 100644 --- a/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json +++ b/erpnext/accounts/doctype/journal_voucher_detail/journal_voucher_detail.json @@ -117,11 +117,6 @@ "print_hide": 0, "search_index": 1 }, - { - "fieldname": "col_break3", - "fieldtype": "Column Break", - "permlevel": 0 - }, { "fieldname": "against_jv", "fieldtype": "Link", @@ -135,6 +130,25 @@ "print_hide": 0, "search_index": 1 }, + { + "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": "is_advance", "fieldtype": "Select", @@ -160,7 +174,7 @@ ], "idx": 1, "istable": 1, - "modified": "2014-07-25 03:16:51.149899", + "modified": "2014-08-20 12:19:55.049973", "modified_by": "Administrator", "module": "Accounts", "name": "Journal Voucher Detail", diff --git a/erpnext/accounts/doctype/payment_tool/__init__.py b/erpnext/accounts/doctype/payment_tool/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.js b/erpnext/accounts/doctype/payment_tool/payment_tool.js new file mode 100644 index 0000000000..3e0d2eec9f --- /dev/null +++ b/erpnext/accounts/doctype/payment_tool/payment_tool.js @@ -0,0 +1,217 @@ +// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +// For license information, please see license.txt + +frappe.provide("erpnext.payment_tool"); + +// Help content +frappe.ui.form.on("Payment Tool", "onload", function(frm) { + frm.set_value("make_jv_help", ' ' + + __("Note: If payment is not made against any reference, make Journal Voucher manually.")); + + frm.set_query("payment_account", function() { + return { + filters: [ + ['Account', 'account_type', 'in', 'Bank, Cash'], + ['Account', 'group_or_ledger', '=', 'Ledger'], + ['Account', 'company', '=', frm.doc.company] + ] + } + }); + + frm.set_query("against_voucher_type", "payment_tool_details", function() { + return { + filters: {"name": ["in", ["Sales Invoice", "Purchase Invoice", "Journal Voucher", "Sales Order", "Purchase Order"]]} + }; + }); +}); + +frappe.ui.form.on("Payment Tool", "refresh", function(frm) { + frappe.ui.form.trigger("Payment Tool", "party_type"); +}); + +frappe.ui.form.on("Payment Tool", "party_type", function(frm) { + frm.toggle_reqd("customer", frm.doc.party_type == "Customer"); + frm.toggle_reqd("supplier", frm.doc.party_type == "Supplier"); +}); + +frappe.ui.form.on("Payment Tool", "company", function(frm) { + erpnext.payment_tool.check_mandatory_to_set_button(frm); +}); + +frappe.ui.form.on("Payment Tool", "received_or_paid", function(frm) { + erpnext.payment_tool.check_mandatory_to_set_button(frm); +}); + +// Fetch bank/cash account based on payment mode +cur_frm.add_fetch("payment_mode", "default_account", "payment_account"); + +// Set party account name +frappe.ui.form.on("Payment Tool", "customer", function(frm) { + erpnext.payment_tool.set_party_account(frm); + erpnext.payment_tool.check_mandatory_to_set_button(frm); +}); + +frappe.ui.form.on("Payment Tool", "supplier", function(frm) { + erpnext.payment_tool.set_party_account(frm); + erpnext.payment_tool.check_mandatory_to_set_button(frm); +}); + +erpnext.payment_tool.check_mandatory_to_set_button = function(frm) { + if (frm.doc.company && frm.doc.party_type && frm.doc.received_or_paid && (frm.doc.customer || frm.doc.supplier)) { + frm.fields_dict.get_outstanding_vouchers.$input.addClass("btn-primary"); + } +} + +//Set Button color +erpnext.payment_tool.set_party_account = function(frm) { + if(frm.doc.party_type == "Customer") { + var party_name = frm.doc.customer; + } else { + var party_name = frm.doc.supplier; + } + return frappe.call({ + method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_party_account', + args: { + party_type: frm.doc.party_type, + party_name: party_name + }, + callback: function(r, rt) { + if(!r.exc) { + frm.set_value("party_account", r.message); + } + } + }); +} + +// Get outstanding vouchers +frappe.ui.form.on("Payment Tool", "get_outstanding_vouchers", function(frm) { + erpnext.payment_tool.check_mandatory_to_fetch(frm.doc); + + frm.set_value("payment_tool_details", []); + + return frappe.call({ + method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_outstanding_vouchers', + args: { + args: { + "company": frm.doc.company, + "party_type": frm.doc.party_type, + "received_or_paid": frm.doc.received_or_paid, + "party_name": frm.doc.party_type == "Customer" ? frm.doc.customer : frm.doc.supplier, + "party_account": frm.doc.party_account + } + }, + callback: function(r, rt) { + if(r.message) { + frm.fields_dict.get_outstanding_vouchers.$input.removeClass("btn-primary"); + frm.fields_dict.make_journal_voucher.$input.addClass("btn-primary"); + + frappe.model.clear_table(frm.doc, "payment_tool_details"); + $.each(r.message, function(i, d) { + var invoice_detail = frappe.model.add_child(frm.doc, "Payment Tool Detail", "payment_tool_details"); + invoice_detail.against_voucher_type = d.voucher_type; + invoice_detail.against_voucher_no = d.voucher_no; + invoice_detail.total_amount = d.invoice_amount; + invoice_detail.outstanding_amount = d.outstanding_amount; + }); + } + refresh_field("payment_tool_details"); + erpnext.payment_tool.set_total_payment_amount(frm); + } + }); +}); + +// validate against_voucher_type +frappe.ui.form.on("Payment Tool Detail", "against_voucher_type", function(frm) { + erpnext.payment_tool.validate_against_voucher(frm); +}); + +erpnext.payment_tool.validate_against_voucher = function(frm) { + $.each(frm.doc.payment_tool_details || [], function(i, row) { + if(frm.doc.party_type=="Customer" + && !in_list(["Sales Order", "Sales Invoice", "Journal Voucher"], row.against_voucher_type)) { + frappe.model.set_value(row.doctype, row.name, "against_voucher_type", ""); + frappe.throw(__("Against Voucher Type must be one of Sales Order, Sales Invoice or Journal Voucher")) + } + + if(frm.doc.party_type=="Supplier" + && !in_list(["Purchase Order", "Purchase Invoice", "Journal Voucher"], row.against_voucher_type)) { + frappe.model.set_value(row.doctype, row.name, "against_voucher_type", ""); + frappe.throw(__("Against Voucher Type must be one of Purchase Order, Purchase Invoice or Journal Voucher")) + } + + }); +} + +// validate against_voucher_type +frappe.ui.form.on("Payment Tool Detail", "against_voucher_no", function(frm, cdt, cdn) { + var row = locals[cdt][cdn]; + frappe.call({ + method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_against_voucher_amount', + args: { + "against_voucher_type": row.against_voucher_type, + "against_voucher_no": row.against_voucher_no + }, + callback: function(r) { + if(!r.exc) { + $.each(r.message, function(k, v) { + frappe.model.set_value(cdt, cdn, k, v); + }); + } + } + }); +}); + +// Set total payment amount +frappe.ui.form.on("Payment Tool Detail", "payment_amount", function(frm) { + erpnext.payment_tool.set_total_payment_amount(frm); +}); + +frappe.ui.form.on("Payment Tool Detail", "payment_tool_details_remove", function(frm) { + erpnext.payment_tool.set_total_payment_amount(frm); +}); + +erpnext.payment_tool.set_total_payment_amount = function(frm) { + var total_amount = 0.00; + $.each(frm.doc.payment_tool_details || [], function(i, row) { + if (row.payment_amount && (row.payment_amount <= row.outstanding_amount)) { + total_amount = total_amount + row.payment_amount; + } else { + if(row.payment_amount < 0) + msgprint(__("Row {0}: Payment amount can not be negative", [row.idx])); + else if(row.payment_amount >= row.outstanding_amount) + msgprint(__("Row {0}: Payment Amount cannot be greater than Outstanding Amount", [__(row.idx)])); + + frappe.model.set_value(row.doctype, row.name, "payment_amount", 0.0); + } + }); + frm.set_value("total_payment_amount", total_amount); +} + + +// Make Journal voucher +frappe.ui.form.on("Payment Tool", "make_journal_voucher", function(frm) { + erpnext.payment_tool.check_mandatory_to_fetch(frm.doc); + + return frappe.call({ + method: 'make_journal_voucher', + doc: frm.doc, + callback: function(r) { + frm.fields_dict.make_journal_voucher.$input.addClass("btn-primary"); + var doclist = frappe.model.sync(r.message); + frappe.set_route("Form", doclist[0].doctype, doclist[0].name); + } + }); +}); + +erpnext.payment_tool.check_mandatory_to_fetch = function(doc) { + var check_fields = [ + ['Company', doc.company], + ['Party Type', doc.party_type], + ['Received Or Paid', doc.received_or_paid], + ['Customer / Supplier', doc.party_type == "Customer" ? doc.customer : doc.supplier] + ]; + + $.each(check_fields, function(i, v) { + if(!v[1]) frappe.throw(__("Please select {0} first", [v[0]])); + }); +} diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.json b/erpnext/accounts/doctype/payment_tool/payment_tool.json new file mode 100644 index 0000000000..b2949a99a9 --- /dev/null +++ b/erpnext/accounts/doctype/payment_tool/payment_tool.json @@ -0,0 +1,381 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 0, + "creation": "2014-07-23 15:12:27.746665", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "fields": [ + { + "fieldname": "sec_break1", + "fieldtype": "Section Break", + "label": "Party Details", + "permlevel": 0 + }, + { + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company", + "permlevel": 0, + "reqd": 1 + }, + { + "allow_on_submit": 0, + "default": "Customer", + "fieldname": "party_type", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Party Type", + "no_copy": 0, + "options": "Customer\nSupplier", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "depends_on": "eval:(doc.party_type == 'Customer')", + "fieldname": "customer", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Customer", + "no_copy": 0, + "options": "Customer", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "depends_on": "eval:(doc.party_type == 'Supplier')", + "fieldname": "supplier", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Supplier", + "no_copy": 0, + "options": "Supplier", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "fieldname": "party_account", + "fieldtype": "Link", + "hidden": 1, + "label": "Party Account", + "no_copy": 1, + "options": "Account", + "permlevel": 0, + "read_only": 1 + }, + { + "allow_on_submit": 0, + "fieldname": "received_or_paid", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Received Or Paid", + "no_copy": 0, + "options": "Received\nPaid", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "fieldname": "get_outstanding_vouchers", + "fieldtype": "Button", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Get Outstanding Vouchers", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "fieldname": "col_break1", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Column Break 1", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "fieldname": "payment_mode", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Mode", + "no_copy": 0, + "options": "Mode of Payment", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "fieldname": "payment_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Account", + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "fieldname": "reference_no", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Reference No", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "fieldname": "reference_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Reference Date", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "depends_on": "eval:(doc.company && doc.party_type && doc.received_or_paid && (doc.customer || doc.supplier))", + "fieldname": "sec_break3", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Against Voucher", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "fieldname": "payment_tool_details", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Payment Tool Details", + "no_copy": 0, + "options": "Payment Tool Detail", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "depends_on": "eval:(doc.company && doc.party_type && doc.received_or_paid && (doc.customer || doc.supplier))", + "fieldname": "section_break_19", + "fieldtype": "Section Break", + "permlevel": 0, + "precision": "" + }, + { + "fieldname": "total_payment_amount", + "fieldtype": "Currency", + "label": "Total Payment Amount", + "permlevel": 0, + "read_only": 1 + }, + { + "allow_on_submit": 0, + "fieldname": "make_journal_voucher", + "fieldtype": "Button", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Make Journal Voucher", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "fieldname": "data_22", + "fieldtype": "Column Break", + "permlevel": 0, + "precision": "" + }, + { + "depends_on": "eval:(doc.company && doc.party_type && doc.received_or_paid && (doc.customer || doc.supplier))", + "fieldname": "section_break_21", + "fieldtype": "Section Break", + "permlevel": 0, + "precision": "" + }, + { + "allow_on_submit": 0, + "fieldname": "make_jv_help", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 1, + "icon": "icon-magic", + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 1, + "istable": 0, + "modified": "2014-09-12 04:43:05.963218", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Payment Tool", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 0, + "export": 0, + "import": 0, + "permlevel": 0, + "print": 0, + "read": 1, + "report": 0, + "role": "Accounts Manager", + "set_user_permissions": 0, + "submit": 0, + "write": 1 + }, + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 0, + "export": 0, + "import": 0, + "permlevel": 0, + "print": 0, + "read": 1, + "report": 0, + "role": "Accounts User", + "set_user_permissions": 0, + "submit": 0, + "write": 1 + } + ], + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.py b/erpnext/accounts/doctype/payment_tool/payment_tool.py new file mode 100644 index 0000000000..d8d6df3da2 --- /dev/null +++ b/erpnext/accounts/doctype/payment_tool/payment_tool.py @@ -0,0 +1,118 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _, scrub +from frappe.utils import flt +from frappe.model.document import Document +import json + +class PaymentTool(Document): + def make_journal_voucher(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 Voucher': 'against_jv', + 'Sales Order': 'against_sales_order', + 'Purchase Order': 'against_purchase_order', + } + + jv = frappe.new_doc('Journal Voucher') + jv.voucher_type = 'Journal Entry' + jv.company = self.company + jv.cheque_no = self.reference_no + jv.cheque_date = self.reference_date + + if not self.total_payment_amount: + frappe.throw(_("Please enter Payment Amount in atleast one row")) + + for v in self.get("payment_tool_details"): + if not frappe.db.get_value(v.against_voucher_type, {"name": v.against_voucher_no}): + frappe.throw(_("Row {0}: {1} is not a valid {2}").format(v.idx, v.against_voucher_no, + v.against_voucher_type)) + + if v.payment_amount: + d1 = jv.append("entries") + d1.account = self.party_account + 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('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) + + d2 = jv.append("entries") + d2.account = self.payment_account + d2.set('debit' if total_payment_amount < 0 else 'credit', abs(total_payment_amount)) + if self.payment_account: + d2.balance = get_balance_on(self.payment_account) + + return jv.as_dict() + +@frappe.whitelist() +def get_party_account(party_type, party_name): + return frappe.db.get_value("Account", {"master_type": party_type, "master_name": party_name}) + +@frappe.whitelist() +def get_outstanding_vouchers(args): + from erpnext.accounts.utils import get_outstanding_invoices + + if not frappe.has_permission("Payment Tool"): + frappe.throw(_("No permission to use Payment Tool"), frappe.PermissionError) + + args = json.loads(args) + + if args.get("party_type") == "Customer" and args.get("received_or_paid") == "Received": + amount_query = "ifnull(debit, 0) - ifnull(credit, 0)" + elif args.get("party_type") == "Supplier" and args.get("received_or_paid") == "Paid": + amount_query = "ifnull(credit, 0) - ifnull(debit, 0)" + else: + frappe.throw(_("Please enter the Against Vouchers manually")) + + # Get all outstanding sales /purchase invoices + outstanding_invoices = get_outstanding_invoices(amount_query, 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_name")) + return outstanding_invoices + orders_to_be_billed + +def get_orders_to_be_billed(party_type, party_name): + voucher_type = 'Sales Order' if party_type == "Customer" else 'Purchase Order' + orders = frappe.db.sql(""" + select + name as voucher_no, + ifnull(grand_total, 0) as invoice_amount, + (ifnull(grand_total, 0) - ifnull(advance_paid, 0)) as outstanding_amount, + transaction_date as posting_date + from + `tab%s` + where + %s = %s + and docstatus = 1 + and ifnull(grand_total, 0) > ifnull(advance_paid, 0) + and ifnull(per_billed, 0) < 100.0 + """ % (voucher_type, 'customer' if party_type == "Customer" else 'supplier', '%s'), + party_name, as_dict = True) + + order_list = [] + for d in orders: + d["voucher_type"] = voucher_type + order_list.append(d) + + return order_list + +@frappe.whitelist() +def get_against_voucher_amount(against_voucher_type, against_voucher_no): + if against_voucher_type in ["Sales Order", "Purchase Order"]: + select_cond = "grand_total as total_amount, ifnull(grand_total, 0) - ifnull(advance_paid, 0) as outstanding_amount" + elif against_voucher_type in ["Sales Invoice", "Purchase Invoice"]: + select_cond = "grand_total as total_amount, outstanding_amount" + elif against_voucher_type == "Journal Voucher": + select_cond = "total_debit as total_amount" + + details = frappe.db.sql("""select {0} from `tab{1}` where name = %s""" + .format(select_cond, against_voucher_type), against_voucher_no, as_dict=1) + + return details[0] if details else {} diff --git a/erpnext/accounts/doctype/payment_tool/test_payment_tool.py b/erpnext/accounts/doctype/payment_tool/test_payment_tool.py new file mode 100644 index 0000000000..c91a5de2e1 --- /dev/null +++ b/erpnext/accounts/doctype/payment_tool/test_payment_tool.py @@ -0,0 +1,193 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import unittest, frappe, json +from frappe.utils import flt + +test_dependencies = ["Item"] + +class TestPaymentTool(unittest.TestCase): + def test_make_journal_voucher(self): + from erpnext.accounts.doctype.journal_voucher.test_journal_voucher \ + import test_records as jv_test_records + from erpnext.selling.doctype.sales_order.test_sales_order \ + import test_records as so_test_records + from erpnext.buying.doctype.purchase_order.test_purchase_order \ + import test_records as po_test_records + from erpnext.accounts.doctype.sales_invoice.test_sales_invoice \ + import test_records as si_test_records + from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice \ + import test_records as pi_test_records + + self.clear_table_entries() + + base_customer_jv = self.create_against_jv(jv_test_records[2], { "account": "_Test Customer 3 - _TC"}) + base_supplier_jv = self.create_against_jv(jv_test_records[1], { "account": "_Test Supplier 1 - _TC"}) + + + #Create SO with partial outstanding + so1 = self.create_voucher(so_test_records[0], { + "customer": "_Test Customer 3" + }) + + jv_against_so1 = self.create_against_jv(jv_test_records[0], { + "account": "_Test Customer 3 - _TC", + "against_sales_order": so1.name + }) + + + #Create SO with no outstanding + so2 = self.create_voucher(so_test_records[0], { + "customer": "_Test Customer 3" + }) + + jv_against_so2 = self.create_against_jv(jv_test_records[0], { + "account": "_Test Customer 3 - _TC", + "against_sales_order": so2.name, + "credit": 1000 + }) + po = self.create_voucher(po_test_records[1], { + "supplier": "_Test Supplier 1" + }) + + #Create SI with partial outstanding + si1 = self.create_voucher(si_test_records[0], { + "customer": "_Test Customer 3", + "debit_to": "_Test Customer 3 - _TC" + }) + + jv_against_si1 = self.create_against_jv(jv_test_records[0], { + "account": "_Test Customer 3 - _TC", + "against_invoice": si1.name + }) + #Create SI with no outstanding + si2 = self.create_voucher(si_test_records[0], { + "customer": "_Test Customer 3", + "debit_to": "_Test Customer 3 - _TC" + }) + + jv_against_si2 = self.create_against_jv(jv_test_records[0], { + "account": "_Test Customer 3 - _TC", + "against_invoice": si2.name, + "credit": 561.80 + }) + + pi = self.create_voucher(pi_test_records[0], { + "supplier": "_Test Supplier 1", + "credit_to": "_Test Supplier 1 - _TC" + }) + + #Create a dict containing properties and expected values + expected_outstanding = { + "Journal Voucher" : [base_customer_jv.name, 400.00], + "Sales Invoice" : [si1.name, 161.80], + "Purchase Invoice" : [pi.name, 1512.30], + "Sales Order" : [so1.name, 600.00], + "Purchase Order" : [po.name, 5000.00] + } + + args = { + "company": "_Test Company", + "party_type": "Customer", + "received_or_paid": "Received", + "customer": "_Test Customer", + "party_account": "_Test Customer 3 - _TC", + "payment_mode": "Cheque", + "payment_account": "_Test Account Bank Account - _TC", + "reference_no": "123456", + "reference_date": "2013-02-14" + } + + self.make_voucher_for_party(args, expected_outstanding) + + args.update({ + "party_type": "Supplier", + "received_or_paid": "Paid", + "supplier": "_Test Supplier 1", + "party_account": "_Test Supplier 1 - _TC" + }) + expected_outstanding["Journal Voucher"] = [base_supplier_jv.name, 400.00] + self.make_voucher_for_party(args, expected_outstanding) + + def create_voucher(self, test_record, args): + doc = frappe.copy_doc(test_record) + doc.update(args) + doc.insert() + doc.submit() + return doc + + def create_against_jv(self, test_record, args): + jv = frappe.copy_doc(test_record) + jv.get("entries")[0].update(args) + if args.get("debit"): + jv.get("entries")[1].credit = args["debit"] + elif args.get("credit"): + jv.get("entries")[1].debit = args["credit"] + + jv.insert() + jv.submit() + return jv + + def make_voucher_for_party(self, args, expected_outstanding): + #Make Journal Voucher for Party + payment_tool_doc = frappe.new_doc("Payment Tool") + + for k, v in args.items(): + payment_tool_doc.set(k, v) + + self.check_outstanding_vouchers(payment_tool_doc, args, expected_outstanding) + + + def check_outstanding_vouchers(self, doc, args, expected_outstanding): + from erpnext.accounts.doctype.payment_tool.payment_tool import get_outstanding_vouchers + + outstanding_entries = get_outstanding_vouchers(json.dumps(args)) + + for d in outstanding_entries: + self.assertEquals(flt(d.get("outstanding_amount"), 2), expected_outstanding.get(d.get("voucher_type"))[1]) + + self.check_jv_entries(doc, outstanding_entries, expected_outstanding) + + def check_jv_entries(self, paytool, outstanding_entries, expected_outstanding): + for e in outstanding_entries: + d1 = paytool.append("payment_tool_details") + d1.against_voucher_type = e.get("voucher_type") + d1.against_voucher_no = e.get("voucher_no") + d1.total_amount = e.get("invoice_amount") + d1.outstanding_amount = e.get("outstanding_amount") + d1.payment_amount = 100.00 + paytool.total_payment_amount = 300 + + new_jv = paytool.make_journal_voucher() + + #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, 100.00, expected_outstanding.get("Journal Voucher")[0], None, None, None, None], + [paytool.party_account, 100.00, None, expected_outstanding.get("Sales Invoice")[0], None, None, None], + [paytool.party_account, 100.00, None, None, expected_outstanding.get("Purchase Invoice")[0], None, None], + [paytool.party_account, 100.00, None, None, None, expected_outstanding.get("Sales Order")[0], None], + [paytool.party_account, 100.00, None, None, None, None, expected_outstanding.get("Purchase Order")[0]] + ] + + for jv_entry in new_jv.get("entries"): + if paytool.party_account == jv_entry.get("account"): + row = [ + jv_entry.get("account"), + 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(new_jv.get("cheque_no"), paytool.reference_no) + self.assertEquals(new_jv.get("cheque_date"), paytool.reference_date) + + def clear_table_entries(self): + frappe.db.sql("""delete from `tabGL Entry` where (account = "_Test Customer 3 - _TC" or account = "_Test Supplier 1 - _TC")""") + frappe.db.sql("""delete from `tabSales Order` where customer_name = "_Test Customer 3" """) + frappe.db.sql("""delete from `tabPurchase Order` where supplier_name = "_Test Supplier 1" """) diff --git a/erpnext/accounts/doctype/payment_tool_detail/__init__.py b/erpnext/accounts/doctype/payment_tool_detail/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.json b/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.json new file mode 100644 index 0000000000..5f0e7ecb6f --- /dev/null +++ b/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.json @@ -0,0 +1,130 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 0, + "creation": "2014-08-11 14:27:54.463897", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "fields": [ + { + "allow_on_submit": 0, + "fieldname": "against_voucher_type", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Against Voucher Type", + "no_copy": 0, + "options": "DocType", + "permlevel": 0, + "print_hide": 0, + "print_width": "", + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "width": "" + }, + { + "allow_on_submit": 0, + "fieldname": "against_voucher_no", + "fieldtype": "Dynamic Link", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Against Voucher No", + "no_copy": 0, + "options": "against_voucher_type", + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "fieldname": "column_break_3", + "fieldtype": "Column Break", + "permlevel": 0, + "precision": "" + }, + { + "allow_on_submit": 0, + "fieldname": "total_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Total Amount", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "fieldname": "outstanding_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Outstanding Amount", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0 + }, + { + "allow_on_submit": 0, + "fieldname": "payment_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Payment Amount", + "no_copy": 0, + "permlevel": 0, + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "modified": "2014-09-11 08:55:34.384017", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Payment Tool Detail", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.py b/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.py new file mode 100644 index 0000000000..80c5532842 --- /dev/null +++ b/erpnext/accounts/doctype/payment_tool_detail/payment_tool_detail.py @@ -0,0 +1,9 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class PaymentToolDetail(Document): + pass diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index d1b65846d5..c658cdd09f 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -391,3 +391,42 @@ def get_stock_rbnb_difference(posting_date, company): # Amount should be credited return flt(stock_rbnb) + flt(sys_bal) + +def get_outstanding_invoices(amount_query, account): + all_outstanding_vouchers = [] + outstanding_voucher_list = frappe.db.sql(""" + select + voucher_no, voucher_type, posting_date, + ifnull(sum({amount_query}), 0) as invoice_amount + from + `tabGL Entry` + where + account = %s and {amount_query} > 0 + group by voucher_type, voucher_no + """.format(amount_query = amount_query), account, as_dict = True) + + for d in outstanding_voucher_list: + payment_amount = frappe.db.sql(""" + select ifnull(sum(ifnull({amount_query}, 0)), 0) + from + `tabGL Entry` + where + account = %s and {amount_query} < 0 + and against_voucher_type = %s and ifnull(against_voucher, '') = %s + """.format(**{ + "amount_query": amount_query + }), (account, d.voucher_type, d.voucher_no)) + + payment_amount = -1*payment_amount[0][0] if payment_amount else 0 + + if d.invoice_amount > payment_amount: + + all_outstanding_vouchers.append({ + 'voucher_no': d.voucher_no, + 'voucher_type': d.voucher_type, + 'posting_date': d.posting_date, + 'invoice_amount': flt(d.invoice_amount), + 'outstanding_amount': d.invoice_amount - payment_amount + }) + + return all_outstanding_vouchers diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 912022cbc6..2224db7ca2 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -1,724 +1,732 @@ { - "allow_import": 1, - "autoname": "naming_series:", - "creation": "2013-05-21 16:16:39", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Transaction", + "allow_import": 1, + "autoname": "naming_series:", + "creation": "2013-05-21 16:16:39", + "docstatus": 0, + "doctype": "DocType", + "document_type": "Transaction", "fields": [ { - "fieldname": "supplier_section", - "fieldtype": "Section Break", - "label": "Supplier", - "options": "icon-user", + "fieldname": "supplier_section", + "fieldtype": "Section Break", + "label": "Supplier", + "options": "icon-user", "permlevel": 0 - }, + }, { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Series", - "no_copy": 1, - "oldfieldname": "naming_series", - "oldfieldtype": "Select", - "options": "PO-", - "permlevel": 0, - "print_hide": 1, + "fieldname": "naming_series", + "fieldtype": "Select", + "label": "Series", + "no_copy": 1, + "oldfieldname": "naming_series", + "oldfieldtype": "Select", + "options": "PO-", + "permlevel": 0, + "print_hide": 1, "reqd": 1 - }, + }, { - "description": "Supplier (vendor) name as entered in supplier master", - "fieldname": "supplier", - "fieldtype": "Link", - "in_filter": 1, - "label": "Supplier", - "oldfieldname": "supplier", - "oldfieldtype": "Link", - "options": "Supplier", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "description": "Supplier (vendor) name as entered in supplier master", + "fieldname": "supplier", + "fieldtype": "Link", + "in_filter": 1, + "label": "Supplier", + "oldfieldname": "supplier", + "oldfieldtype": "Link", + "options": "Supplier", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "fieldname": "supplier_name", - "fieldtype": "Data", - "hidden": 0, - "in_list_view": 1, - "label": "Name", - "permlevel": 0, + "fieldname": "supplier_name", + "fieldtype": "Data", + "hidden": 0, + "in_list_view": 1, + "label": "Name", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "address_display", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Address", - "permlevel": 0, + "fieldname": "address_display", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Address", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_display", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Contact", - "permlevel": 0, + "fieldname": "contact_display", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Contact", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_mobile", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Mobile No", - "permlevel": 0, + "fieldname": "contact_mobile", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Mobile No", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_email", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Contact Email", - "permlevel": 0, - "print_hide": 1, + "fieldname": "contact_email", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Contact Email", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "column_break1", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 0, - "print_width": "50%", + "fieldname": "column_break1", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 0, + "print_width": "50%", "width": "50%" - }, + }, { - "fieldname": "transaction_date", - "fieldtype": "Date", - "in_filter": 1, - "label": "Date", - "oldfieldname": "transaction_date", - "oldfieldtype": "Date", - "permlevel": 0, - "reqd": 1, + "fieldname": "transaction_date", + "fieldtype": "Date", + "in_filter": 1, + "label": "Date", + "oldfieldname": "transaction_date", + "oldfieldtype": "Date", + "permlevel": 0, + "reqd": 1, "search_index": 1 - }, + }, { - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "label": "Amended From", - "no_copy": 1, - "oldfieldname": "amended_from", - "oldfieldtype": "Data", - "options": "Purchase Order", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "fieldname": "amended_from", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 1, + "label": "Amended From", + "no_copy": 1, + "oldfieldname": "amended_from", + "oldfieldtype": "Data", + "options": "Purchase Order", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "report_hide": 0 - }, + }, { - "description": "Select the relevant company name if you have multiple companies", - "fieldname": "company", - "fieldtype": "Link", - "in_filter": 1, - "label": "Company", - "no_copy": 0, - "oldfieldname": "company", - "oldfieldtype": "Link", - "options": "Company", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "description": "Select the relevant company name if you have multiple companies", + "fieldname": "company", + "fieldtype": "Link", + "in_filter": 1, + "label": "Company", + "no_copy": 0, + "oldfieldname": "company", + "oldfieldtype": "Link", + "options": "Company", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "fieldname": "price_list_and_currency", - "fieldtype": "Section Break", - "label": "Currency and Price List", - "options": "icon-tag", + "fieldname": "price_list_and_currency", + "fieldtype": "Section Break", + "label": "Currency and Price List", + "options": "icon-tag", "permlevel": 0 - }, + }, { - "fieldname": "cb_currency", - "fieldtype": "Column Break", + "fieldname": "cb_currency", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "currency", - "fieldtype": "Link", - "label": "Currency", - "no_copy": 0, - "oldfieldname": "currency", - "oldfieldtype": "Select", - "options": "Currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "currency", + "fieldtype": "Link", + "label": "Currency", + "no_copy": 0, + "oldfieldname": "currency", + "oldfieldtype": "Select", + "options": "Currency", + "permlevel": 0, + "print_hide": 1, "reqd": 1 - }, + }, { - "description": "Rate at which supplier's currency is converted to company's base currency", - "fieldname": "conversion_rate", - "fieldtype": "Float", - "hidden": 0, - "label": "Exchange Rate", - "no_copy": 0, - "oldfieldname": "conversion_rate", - "oldfieldtype": "Currency", - "permlevel": 0, - "print_hide": 1, + "description": "Rate at which supplier's currency is converted to company's base currency", + "fieldname": "conversion_rate", + "fieldtype": "Float", + "hidden": 0, + "label": "Exchange Rate", + "no_copy": 0, + "oldfieldname": "conversion_rate", + "oldfieldtype": "Currency", + "permlevel": 0, + "print_hide": 1, "reqd": 1 - }, + }, { - "fieldname": "cb_price_list", - "fieldtype": "Column Break", + "fieldname": "cb_price_list", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "buying_price_list", - "fieldtype": "Link", - "label": "Price List", - "options": "Price List", - "permlevel": 0, + "fieldname": "buying_price_list", + "fieldtype": "Link", + "label": "Price List", + "options": "Price List", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "price_list_currency", - "fieldtype": "Link", - "label": "Price List Currency", - "options": "Currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "price_list_currency", + "fieldtype": "Link", + "label": "Price List Currency", + "options": "Currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "plc_conversion_rate", - "fieldtype": "Float", - "label": "Price List Exchange Rate", - "permlevel": 0, + "fieldname": "plc_conversion_rate", + "fieldtype": "Float", + "label": "Price List Exchange Rate", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "ignore_pricing_rule", - "fieldtype": "Check", - "label": "Ignore Pricing Rule", - "no_copy": 1, - "permlevel": 1, + "fieldname": "ignore_pricing_rule", + "fieldtype": "Check", + "label": "Ignore Pricing Rule", + "no_copy": 1, + "permlevel": 1, "print_hide": 1 - }, + }, { - "fieldname": "items", - "fieldtype": "Section Break", - "label": "Items", - "oldfieldtype": "Section Break", - "options": "icon-shopping-cart", + "fieldname": "items", + "fieldtype": "Section Break", + "label": "Items", + "oldfieldtype": "Section Break", + "options": "icon-shopping-cart", "permlevel": 0 - }, + }, { - "allow_on_submit": 1, - "fieldname": "po_details", - "fieldtype": "Table", - "label": "Purchase Order Items", - "no_copy": 0, - "oldfieldname": "po_details", - "oldfieldtype": "Table", - "options": "Purchase Order Item", + "allow_on_submit": 1, + "fieldname": "po_details", + "fieldtype": "Table", + "label": "Purchase Order Items", + "no_copy": 0, + "oldfieldname": "po_details", + "oldfieldtype": "Table", + "options": "Purchase Order Item", "permlevel": 0 - }, + }, { - "fieldname": "sb_last_purchase", - "fieldtype": "Section Break", + "fieldname": "sb_last_purchase", + "fieldtype": "Section Break", "permlevel": 0 - }, + }, { - "fieldname": "net_total", - "fieldtype": "Currency", - "label": "Net Total (Company Currency)", - "no_copy": 1, - "oldfieldname": "net_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "fieldname": "net_total", + "fieldtype": "Currency", + "label": "Net Total (Company Currency)", + "no_copy": 1, + "oldfieldname": "net_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "reqd": 0 - }, + }, { - "fieldname": "column_break_26", - "fieldtype": "Column Break", + "fieldname": "column_break_26", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "net_total_import", - "fieldtype": "Currency", - "label": "Net Total", - "no_copy": 0, - "oldfieldname": "net_total_import", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 0, + "fieldname": "net_total_import", + "fieldtype": "Currency", + "label": "Net Total", + "no_copy": 0, + "oldfieldname": "net_total_import", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 0, "read_only": 1 - }, + }, { - "fieldname": "get_last_purchase_rate", - "fieldtype": "Button", - "label": "Get Last Purchase Rate", - "oldfieldtype": "Button", - "permlevel": 0, + "fieldname": "get_last_purchase_rate", + "fieldtype": "Button", + "label": "Get Last Purchase Rate", + "oldfieldtype": "Button", + "permlevel": 0, "print_hide": 0 - }, + }, { - "fieldname": "taxes", - "fieldtype": "Section Break", - "label": "Taxes and Charges", - "oldfieldtype": "Section Break", - "options": "icon-money", - "permlevel": 0, + "fieldname": "taxes", + "fieldtype": "Section Break", + "label": "Taxes and Charges", + "oldfieldtype": "Section Break", + "options": "icon-money", + "permlevel": 0, "print_hide": 0 - }, + }, { - "description": "If you have created a standard template in Purchase Taxes and Charges Master, select one and click on the button below.", - "fieldname": "taxes_and_charges", - "fieldtype": "Link", - "label": "Taxes and Charges", - "no_copy": 0, - "oldfieldname": "purchase_other_charges", - "oldfieldtype": "Link", - "options": "Purchase Taxes and Charges Master", - "permlevel": 0, + "description": "If you have created a standard template in Purchase Taxes and Charges Master, select one and click on the button below.", + "fieldname": "taxes_and_charges", + "fieldtype": "Link", + "label": "Taxes and Charges", + "no_copy": 0, + "oldfieldname": "purchase_other_charges", + "oldfieldtype": "Link", + "options": "Purchase Taxes and Charges Master", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "other_charges", - "fieldtype": "Table", - "label": "Purchase Taxes and Charges", - "no_copy": 0, - "oldfieldname": "purchase_tax_details", - "oldfieldtype": "Table", - "options": "Purchase Taxes and Charges", + "fieldname": "other_charges", + "fieldtype": "Table", + "label": "Purchase Taxes and Charges", + "no_copy": 0, + "oldfieldname": "purchase_tax_details", + "oldfieldtype": "Table", + "options": "Purchase Taxes and Charges", "permlevel": 0 - }, + }, { - "fieldname": "other_charges_calculation", - "fieldtype": "HTML", - "label": "Taxes and Charges Calculation", - "no_copy": 1, - "oldfieldtype": "HTML", - "permlevel": 0, + "fieldname": "other_charges_calculation", + "fieldtype": "HTML", + "label": "Taxes and Charges Calculation", + "no_copy": 1, + "oldfieldtype": "HTML", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "totals", - "fieldtype": "Section Break", - "label": "Totals", - "oldfieldtype": "Section Break", - "options": "icon-money", + "fieldname": "totals", + "fieldtype": "Section Break", + "label": "Totals", + "oldfieldtype": "Section Break", + "options": "icon-money", "permlevel": 0 - }, + }, { - "fieldname": "other_charges_added", - "fieldtype": "Currency", - "label": "Taxes and Charges Added (Company Currency)", - "no_copy": 0, - "oldfieldname": "other_charges_added", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "other_charges_added", + "fieldtype": "Currency", + "label": "Taxes and Charges Added (Company Currency)", + "no_copy": 0, + "oldfieldname": "other_charges_added", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "other_charges_deducted", - "fieldtype": "Currency", - "label": "Taxes and Charges Deducted (Company Currency)", - "no_copy": 0, - "oldfieldname": "other_charges_deducted", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "other_charges_deducted", + "fieldtype": "Currency", + "label": "Taxes and Charges Deducted (Company Currency)", + "no_copy": 0, + "oldfieldname": "other_charges_deducted", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "total_tax", - "fieldtype": "Currency", - "label": "Total Tax (Company Currency)", - "no_copy": 1, - "oldfieldname": "total_tax", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "total_tax", + "fieldtype": "Currency", + "label": "Total Tax (Company Currency)", + "no_copy": 1, + "oldfieldname": "total_tax", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "grand_total", - "fieldtype": "Currency", - "label": "Grand Total (Company Currency)", - "no_copy": 1, - "oldfieldname": "grand_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "grand_total", + "fieldtype": "Currency", + "label": "Grand Total (Company Currency)", + "no_copy": 1, + "oldfieldname": "grand_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "description": "In Words will be visible once you save the Purchase Order.", - "fieldname": "in_words", - "fieldtype": "Data", - "label": "In Words (Company Currency)", - "oldfieldname": "in_words", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 1, + "description": "In Words will be visible once you save the Purchase Order.", + "fieldname": "in_words", + "fieldtype": "Data", + "label": "In Words (Company Currency)", + "oldfieldname": "in_words", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "rounded_total", - "fieldtype": "Currency", - "label": "Rounded Total (Company Currency)", - "oldfieldname": "rounded_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "rounded_total", + "fieldtype": "Currency", + "label": "Rounded Total (Company Currency)", + "oldfieldname": "rounded_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "column_break4", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, + "fieldname": "advance_paid", + "fieldtype": "Currency", + "label": "Advance Paid", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "column_break4", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, "print_hide": 0 - }, + }, { - "fieldname": "other_charges_added_import", - "fieldtype": "Currency", - "label": "Taxes and Charges Added", - "no_copy": 0, - "oldfieldname": "other_charges_added_import", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "fieldname": "other_charges_added_import", + "fieldtype": "Currency", + "label": "Taxes and Charges Added", + "no_copy": 0, + "oldfieldname": "other_charges_added_import", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "report_hide": 0 - }, + }, { - "fieldname": "other_charges_deducted_import", - "fieldtype": "Currency", - "label": "Taxes and Charges Deducted", - "no_copy": 0, - "oldfieldname": "other_charges_deducted_import", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "fieldname": "other_charges_deducted_import", + "fieldtype": "Currency", + "label": "Taxes and Charges Deducted", + "no_copy": 0, + "oldfieldname": "other_charges_deducted_import", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "report_hide": 0 - }, + }, { - "fieldname": "grand_total_import", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Grand Total", - "no_copy": 0, - "oldfieldname": "grand_total_import", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 0, - "read_only": 1, + "fieldname": "grand_total_import", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Grand Total", + "no_copy": 0, + "oldfieldname": "grand_total_import", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 0, + "read_only": 1, "report_hide": 0 - }, + }, { - "fieldname": "in_words_import", - "fieldtype": "Data", - "label": "In Words", - "oldfieldname": "in_words_import", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, + "fieldname": "in_words_import", + "fieldtype": "Data", + "label": "In Words", + "oldfieldname": "in_words_import", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, "read_only": 1 - }, + }, { - "fieldname": "fold", - "fieldtype": "Fold", + "fieldname": "fold", + "fieldtype": "Fold", "permlevel": 0 - }, + }, { - "fieldname": "terms_section_break", - "fieldtype": "Section Break", - "label": "Terms and Conditions", - "oldfieldtype": "Section Break", - "options": "icon-legal", + "fieldname": "terms_section_break", + "fieldtype": "Section Break", + "label": "Terms and Conditions", + "oldfieldtype": "Section Break", + "options": "icon-legal", "permlevel": 0 - }, + }, { - "fieldname": "tc_name", - "fieldtype": "Link", - "label": "Terms", - "oldfieldname": "tc_name", - "oldfieldtype": "Link", - "options": "Terms and Conditions", - "permlevel": 0, + "fieldname": "tc_name", + "fieldtype": "Link", + "label": "Terms", + "oldfieldname": "tc_name", + "oldfieldtype": "Link", + "options": "Terms and Conditions", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "terms", - "fieldtype": "Text Editor", - "label": "Terms and Conditions", - "oldfieldname": "terms", - "oldfieldtype": "Text Editor", + "fieldname": "terms", + "fieldtype": "Text Editor", + "label": "Terms and Conditions", + "oldfieldname": "terms", + "oldfieldtype": "Text Editor", "permlevel": 0 - }, + }, { - "depends_on": "supplier", - "fieldname": "contact_section", - "fieldtype": "Section Break", - "label": "Contact Info", - "options": "icon-bullhorn", + "depends_on": "supplier", + "fieldname": "contact_section", + "fieldtype": "Section Break", + "label": "Contact Info", + "options": "icon-bullhorn", "permlevel": 0 - }, + }, { - "fieldname": "supplier_address", - "fieldtype": "Link", - "in_filter": 1, - "label": "Supplier Address", - "options": "Address", - "permlevel": 0, + "fieldname": "supplier_address", + "fieldtype": "Link", + "in_filter": 1, + "label": "Supplier Address", + "options": "Address", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "cb_contact", - "fieldtype": "Column Break", + "fieldname": "cb_contact", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "contact_person", - "fieldtype": "Link", - "in_filter": 1, - "label": "Contact Person", - "options": "Contact", - "permlevel": 0, + "fieldname": "contact_person", + "fieldtype": "Link", + "in_filter": 1, + "label": "Contact Person", + "options": "Contact", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "more_info", - "fieldtype": "Section Break", - "label": "More Info", - "oldfieldtype": "Section Break", + "fieldname": "more_info", + "fieldtype": "Section Break", + "label": "More Info", + "oldfieldtype": "Section Break", "permlevel": 0 - }, + }, { - "fieldname": "status", - "fieldtype": "Select", - "in_filter": 1, - "label": "Status", - "no_copy": 1, - "oldfieldname": "status", - "oldfieldtype": "Select", - "options": "\nDraft\nSubmitted\nStopped\nCancelled", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, - "reqd": 1, + "fieldname": "status", + "fieldtype": "Select", + "in_filter": 1, + "label": "Status", + "no_copy": 1, + "oldfieldname": "status", + "oldfieldtype": "Select", + "options": "\nDraft\nSubmitted\nStopped\nCancelled", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "default": "No", - "fieldname": "is_subcontracted", - "fieldtype": "Select", - "label": "Is Subcontracted", - "options": "\nYes\nNo", - "permlevel": 0, + "default": "No", + "fieldname": "is_subcontracted", + "fieldtype": "Select", + "label": "Is Subcontracted", + "options": "\nYes\nNo", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "ref_sq", - "fieldtype": "Data", - "hidden": 1, - "label": "Ref SQ", - "no_copy": 1, - "oldfieldname": "ref_sq", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 1, + "fieldname": "ref_sq", + "fieldtype": "Data", + "hidden": 1, + "label": "Ref SQ", + "no_copy": 1, + "oldfieldname": "ref_sq", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "allow_on_submit": 1, - "fieldname": "letter_head", - "fieldtype": "Link", - "label": "Letter Head", - "oldfieldname": "letter_head", - "oldfieldtype": "Select", - "options": "Letter Head", - "permlevel": 0, + "allow_on_submit": 1, + "fieldname": "letter_head", + "fieldtype": "Link", + "label": "Letter Head", + "oldfieldname": "letter_head", + "oldfieldtype": "Select", + "options": "Letter Head", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "fiscal_year", - "fieldtype": "Link", - "in_filter": 1, - "label": "Fiscal Year", - "no_copy": 0, - "oldfieldname": "fiscal_year", - "oldfieldtype": "Select", - "options": "Fiscal Year", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "fieldname": "fiscal_year", + "fieldtype": "Link", + "in_filter": 1, + "label": "Fiscal Year", + "no_copy": 0, + "oldfieldname": "fiscal_year", + "oldfieldtype": "Select", + "options": "Fiscal Year", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "allow_on_submit": 1, - "fieldname": "select_print_heading", - "fieldtype": "Link", - "label": "Print Heading", - "no_copy": 1, - "oldfieldname": "select_print_heading", - "oldfieldtype": "Link", - "options": "Print Heading", - "permlevel": 0, - "print_hide": 1, + "allow_on_submit": 1, + "fieldname": "select_print_heading", + "fieldtype": "Link", + "label": "Print Heading", + "no_copy": 1, + "oldfieldname": "select_print_heading", + "oldfieldtype": "Link", + "options": "Print Heading", + "permlevel": 0, + "print_hide": 1, "report_hide": 1 - }, + }, { - "fieldname": "column_break5", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 1, - "print_width": "50%", + "fieldname": "column_break5", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 1, + "print_width": "50%", "width": "50%" - }, + }, { - "depends_on": "eval:!doc.__islocal", - "description": "% of materials received against this Purchase Order", - "fieldname": "per_received", - "fieldtype": "Percent", - "in_list_view": 1, - "label": "% Received", - "no_copy": 1, - "oldfieldname": "per_received", - "oldfieldtype": "Currency", - "permlevel": 0, - "print_hide": 1, + "depends_on": "eval:!doc.__islocal", + "description": "% of materials received against this Purchase Order", + "fieldname": "per_received", + "fieldtype": "Percent", + "in_list_view": 1, + "label": "% Received", + "no_copy": 1, + "oldfieldname": "per_received", + "oldfieldtype": "Currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "depends_on": "eval:!doc.__islocal", - "description": "% of materials billed against this Purchase Order.", - "fieldname": "per_billed", - "fieldtype": "Percent", - "in_list_view": 1, - "label": "% Billed", - "no_copy": 1, - "oldfieldname": "per_billed", - "oldfieldtype": "Currency", - "permlevel": 0, - "print_hide": 1, + "depends_on": "eval:!doc.__islocal", + "description": "% of materials billed against this Purchase Order.", + "fieldname": "per_billed", + "fieldtype": "Percent", + "in_list_view": 1, + "label": "% Billed", + "no_copy": 1, + "oldfieldname": "per_billed", + "oldfieldtype": "Currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "description": "Required raw materials issued to the supplier for producing a sub - contracted item.", - "fieldname": "raw_material_details", - "fieldtype": "Section Break", - "label": "Raw Materials Supplied", - "oldfieldtype": "Section Break", - "options": "icon-truck", - "permlevel": 0, + "description": "Required raw materials issued to the supplier for producing a sub - contracted item.", + "fieldname": "raw_material_details", + "fieldtype": "Section Break", + "label": "Raw Materials Supplied", + "oldfieldtype": "Section Break", + "options": "icon-truck", + "permlevel": 0, "print_hide": 1 - }, + }, { - "allow_on_submit": 1, - "fieldname": "po_raw_material_details", - "fieldtype": "Table", - "label": "Purchase Order Items Supplied", - "no_copy": 0, - "oldfieldname": "po_raw_material_details", - "oldfieldtype": "Table", - "options": "Purchase Order Item Supplied", - "permlevel": 0, - "print_hide": 1, + "allow_on_submit": 1, + "fieldname": "po_raw_material_details", + "fieldtype": "Table", + "label": "Purchase Order Items Supplied", + "no_copy": 0, + "oldfieldname": "po_raw_material_details", + "oldfieldtype": "Table", + "options": "Purchase Order Item Supplied", + "permlevel": 0, + "print_hide": 1, "read_only": 1 } - ], - "icon": "icon-file-text", - "idx": 1, - "is_submittable": 1, - "modified": "2014-09-09 05:35:32.583024", - "modified_by": "Administrator", - "module": "Buying", - "name": "Purchase Order", - "owner": "Administrator", + ], + "icon": "icon-file-text", + "idx": 1, + "is_submittable": 1, + "modified": "2014-09-10 05:35:32.583024", + "modified_by": "Administrator", + "module": "Buying", + "name": "Purchase Order", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "apply_user_permissions": 1, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 1, - "role": "Material User", - "submit": 0, + "amend": 0, + "apply_user_permissions": 1, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 0, + "permlevel": 0, + "print": 0, + "read": 1, + "report": 1, + "role": "Material User", + "submit": 0, "write": 0 - }, + }, { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase Manager", - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase Manager", + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "apply_user_permissions": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase User", - "submit": 1, + "amend": 1, + "apply_user_permissions": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase User", + "submit": 1, "write": 1 - }, + }, { - "apply_user_permissions": 1, - "cancel": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, + "apply_user_permissions": 1, + "cancel": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, "role": "Supplier" - }, + }, { - "permlevel": 1, - "read": 1, - "role": "Purchase Manager", + "permlevel": 1, + "read": 1, + "role": "Purchase Manager", "write": 1 } - ], - "read_only_onload": 1, - "search_fields": "status, transaction_date, supplier,grand_total", - "sort_field": "modified", + ], + "read_only_onload": 1, + "search_fields": "status, transaction_date, supplier,grand_total", + "sort_field": "modified", "sort_order": "DESC" -} \ No newline at end of file +} diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 6c7c0c6d08..4def1db979 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -238,6 +238,11 @@ def make_purchase_receipt(source_name, target_doc=None): @frappe.whitelist() def make_purchase_invoice(source_name, target_doc=None): + def postprocess(source, target): + set_missing_values(source, target) + #Get the advance paid Journal Vouchers in Purchase Invoice Advance + target.get_advances() + def update_item(obj, target, source_parent): target.amount = flt(obj.amount) - flt(obj.billed_amt) target.base_amount = target.amount * flt(source_parent.conversion_rate) @@ -263,6 +268,6 @@ def make_purchase_invoice(source_name, target_doc=None): "doctype": "Purchase Taxes and Charges", "add_if_empty": True } - }, target_doc, set_missing_values) + }, target_doc, postprocess) return doc diff --git a/erpnext/buying/doctype/purchase_order/test_records.json b/erpnext/buying/doctype/purchase_order/test_records.json index 3aaf542a32..6b89bdc3de 100644 --- a/erpnext/buying/doctype/purchase_order/test_records.json +++ b/erpnext/buying/doctype/purchase_order/test_records.json @@ -1,5 +1,6 @@ [ { + "advance_paid": 0.0, "buying_price_list": "_Test Price List", "company": "_Test Company", "conversion_rate": 1.0, @@ -31,5 +32,39 @@ "supplier": "_Test Supplier", "supplier_name": "_Test Supplier", "transaction_date": "2013-02-12" + }, + { + "advance_paid": 0.0, + "buying_price_list": "_Test Price List", + "company": "_Test Company", + "conversion_rate": 1.0, + "currency": "INR", + "doctype": "Purchase Order", + "fiscal_year": "_Test Fiscal Year 2013", + "grand_total": 5000.0, + "grand_total_import": 5000.0, + "is_subcontracted": "No", + "naming_series": "_T-Purchase Order-", + "net_total": 5000.0, + "po_details": [ + { + "base_amount": 5000.0, + "conversion_factor": 1.0, + "description": "_Test Item", + "doctype": "Purchase Order Item", + "item_code": "_Test Item", + "item_name": "_Test Item", + "parentfield": "po_details", + "qty": 10.0, + "rate": 500.0, + "schedule_date": "2013-03-01", + "stock_uom": "_Test UOM", + "uom": "_Test UOM", + "warehouse": "_Test Warehouse - _TC" + } + ], + "supplier": "_Test Supplier", + "supplier_name": "_Test Supplier", + "transaction_date": "2013-02-12" } -] \ No newline at end of file +] diff --git a/erpnext/buying/doctype/supplier/test_records.json b/erpnext/buying/doctype/supplier/test_records.json index a1d1054ff2..dfa5d46f24 100644 --- a/erpnext/buying/doctype/supplier/test_records.json +++ b/erpnext/buying/doctype/supplier/test_records.json @@ -4,5 +4,11 @@ "doctype": "Supplier", "supplier_name": "_Test Supplier", "supplier_type": "_Test Supplier Type" + }, + { + "company": "_Test Company", + "doctype": "Supplier", + "supplier_name": "_Test Supplier 1", + "supplier_type": "_Test Supplier Type" } -] \ No newline at end of file +] diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py index 646d596387..27a0725070 100644 --- a/erpnext/config/accounts.py +++ b/erpnext/config/accounts.py @@ -61,6 +61,11 @@ def get_data(): "name": "Period Closing Voucher", "description": _("Close Balance Sheet and book Profit or Loss.") }, + { + "type": "doctype", + "name": "Payment Tool", + "description": _("Create Payment Entries against Orders or Invoices.") + }, ] }, { diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 4af9f5ed8a..7fa81c9926 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -363,9 +363,10 @@ class AccountsController(TransactionBase): and ifnull(allocated_amount, 0) = 0""" % (childtype, '%s', '%s'), (parentfield, self.name)) def get_advances(self, account_head, child_doctype, parentfield, dr_or_cr): + against_order_list = [] res = frappe.db.sql(""" select - t1.name as jv_no, t1.remark, t2.%s as amount, t2.name as jv_detail_no + t1.name as jv_no, t1.remark, t2.%s as amount, t2.name as jv_detail_no, t2.%s as order_no from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 where @@ -374,18 +375,25 @@ class AccountsController(TransactionBase): and ifnull(t2.against_invoice, '') = '' and ifnull(t2.against_jv, '') = '' order by t1.posting_date""" % - (dr_or_cr, '%s'), account_head, as_dict=1) + (dr_or_cr, "against_sales_order" if dr_or_cr == "credit" \ + else "against_purchase_order", '%s'), + account_head, as_dict= True) + + if self.get("entries"): + for i in self.get("entries"): + against_order_list.append(i.sales_order if dr_or_cr == "credit" else i.purchase_order) self.set(parentfield, []) for d in res: - self.append(parentfield, { - "doctype": child_doctype, - "journal_voucher": d.jv_no, - "jv_detail_no": d.jv_detail_no, - "remarks": d.remark, - "advance_amount": flt(d.amount), - "allocate_amount": 0 - }) + if not against_order_list or d.order_no in against_order_list: + self.append(parentfield, { + "doctype": child_doctype, + "journal_voucher": d.jv_no, + "jv_detail_no": d.jv_detail_no, + "remarks": d.remark, + "advance_amount": flt(d.amount), + "allocate_amount": 0 + }) def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield): from erpnext.controllers.status_updater import get_tolerance_for @@ -430,6 +438,32 @@ class AccountsController(TransactionBase): return stock_items + 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 + sum(ifnull({dr_or_cr}, 0)) + from + `tabJournal Voucher Detail` + where + {against_field} = %s and docstatus = 1 and is_advance = "Yes" """.format(dr_or_cr=dr_or_cr, \ + against_field=against_field), self.name) + + if advance_paid: + advance_paid = flt(advance_paid[0][0], self.precision("advance_paid")) + if flt(self.grand_total) >= advance_paid: + frappe.db.set_value(self.doctype, self.name, "advance_paid", advance_paid) + else: + frappe.throw(_("Total advance ({0}) against Order {1} cannot be greater \ + than the Grand Total ({2})") + .format(advance_paid, self.name, self.grand_total)) + @property def company_abbr(self): if not hasattr(self, "_abbr"): diff --git a/erpnext/selling/doctype/customer/test_records.json b/erpnext/selling/doctype/customer/test_records.json index 6bac5439f5..e076f7a893 100644 --- a/erpnext/selling/doctype/customer/test_records.json +++ b/erpnext/selling/doctype/customer/test_records.json @@ -22,5 +22,13 @@ "customer_type": "Individual", "doctype": "Customer", "territory": "_Test Territory" + }, + { + "company": "_Test Company", + "customer_group": "_Test Customer Group", + "customer_name": "_Test Customer 3", + "customer_type": "Individual", + "doctype": "Customer", + "territory": "_Test Territory" } ] diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 7ddfd3a2fb..844e8cd2e0 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -1,1114 +1,1122 @@ { - "allow_import": 1, - "autoname": "naming_series:", - "creation": "2013-06-18 12:39:59", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Transaction", + "allow_import": 1, + "autoname": "naming_series:", + "creation": "2013-06-18 12:39:59", + "docstatus": 0, + "doctype": "DocType", + "document_type": "Transaction", "fields": [ { - "fieldname": "customer_section", - "fieldtype": "Section Break", - "label": "Customer", - "options": "icon-user", + "fieldname": "customer_section", + "fieldtype": "Section Break", + "label": "Customer", + "options": "icon-user", "permlevel": 0 - }, + }, { - "fieldname": "column_break0", - "fieldtype": "Column Break", - "in_filter": 0, - "oldfieldtype": "Column Break", - "permlevel": 0, - "search_index": 0, + "fieldname": "column_break0", + "fieldtype": "Column Break", + "in_filter": 0, + "oldfieldtype": "Column Break", + "permlevel": 0, + "search_index": 0, "width": "50%" - }, + }, { - "fieldname": "naming_series", - "fieldtype": "Select", - "label": "Series", - "no_copy": 1, - "oldfieldname": "naming_series", - "oldfieldtype": "Select", - "options": "SO-", - "permlevel": 0, - "print_hide": 1, + "fieldname": "naming_series", + "fieldtype": "Select", + "label": "Series", + "no_copy": 1, + "oldfieldname": "naming_series", + "oldfieldtype": "Select", + "options": "SO-", + "permlevel": 0, + "print_hide": 1, "reqd": 1 - }, + }, { - "fieldname": "customer", - "fieldtype": "Link", - "in_filter": 1, - "in_list_view": 1, - "label": "Customer", - "oldfieldname": "customer", - "oldfieldtype": "Link", - "options": "Customer", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "fieldname": "customer", + "fieldtype": "Link", + "in_filter": 1, + "in_list_view": 1, + "label": "Customer", + "oldfieldname": "customer", + "oldfieldtype": "Link", + "options": "Customer", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "fieldname": "customer_name", - "fieldtype": "Data", - "hidden": 0, - "label": "Name", - "permlevel": 0, + "fieldname": "customer_name", + "fieldtype": "Data", + "hidden": 0, + "label": "Name", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "address_display", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Address", - "permlevel": 0, + "fieldname": "address_display", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Address", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_display", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Contact", - "permlevel": 0, + "fieldname": "contact_display", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Contact", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_mobile", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Mobile No", - "permlevel": 0, + "fieldname": "contact_mobile", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Mobile No", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_email", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Contact Email", - "permlevel": 0, - "print_hide": 1, + "fieldname": "contact_email", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Contact Email", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "default": "Sales", - "fieldname": "order_type", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Order Type", - "oldfieldname": "order_type", - "oldfieldtype": "Select", - "options": "\nSales\nMaintenance\nShopping Cart", - "permlevel": 0, - "print_hide": 1, + "default": "Sales", + "fieldname": "order_type", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Order Type", + "oldfieldname": "order_type", + "oldfieldtype": "Select", + "options": "\nSales\nMaintenance\nShopping Cart", + "permlevel": 0, + "print_hide": 1, "reqd": 1 - }, + }, { - "fieldname": "column_break1", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, + "fieldname": "column_break1", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, "width": "50%" - }, + }, { - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 1, - "ignore_user_permissions": 1, - "label": "Amended From", - "no_copy": 1, - "oldfieldname": "amended_from", - "oldfieldtype": "Data", - "options": "Sales Order", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "fieldname": "amended_from", + "fieldtype": "Link", + "hidden": 1, + "ignore_user_permissions": 1, + "label": "Amended From", + "no_copy": 1, + "oldfieldname": "amended_from", + "oldfieldtype": "Data", + "options": "Sales Order", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "width": "150px" - }, + }, { - "description": "Select the relevant company name if you have multiple companies.", - "fieldname": "company", - "fieldtype": "Link", - "in_filter": 1, - "label": "Company", - "oldfieldname": "company", - "oldfieldtype": "Link", - "options": "Company", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, - "search_index": 1, + "description": "Select the relevant company name if you have multiple companies.", + "fieldname": "company", + "fieldtype": "Link", + "in_filter": 1, + "label": "Company", + "oldfieldname": "company", + "oldfieldtype": "Link", + "options": "Company", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, + "search_index": 1, "width": "150px" - }, + }, { - "default": "Today", - "fieldname": "transaction_date", - "fieldtype": "Date", - "in_filter": 1, - "label": "Date", - "no_copy": 1, - "oldfieldname": "transaction_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 0, - "reqd": 1, - "search_index": 1, + "default": "Today", + "fieldname": "transaction_date", + "fieldtype": "Date", + "in_filter": 1, + "label": "Date", + "no_copy": 1, + "oldfieldname": "transaction_date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 0, + "reqd": 1, + "search_index": 1, "width": "160px" - }, + }, { - "depends_on": "eval:doc.order_type == 'Sales'", - "fieldname": "delivery_date", - "fieldtype": "Date", - "hidden": 0, - "in_filter": 1, - "label": "Delivery Date", - "oldfieldname": "delivery_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 1, - "reqd": 0, - "search_index": 1, + "depends_on": "eval:doc.order_type == 'Sales'", + "fieldname": "delivery_date", + "fieldtype": "Date", + "hidden": 0, + "in_filter": 1, + "label": "Delivery Date", + "oldfieldname": "delivery_date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 1, + "reqd": 0, + "search_index": 1, "width": "160px" - }, + }, { - "allow_on_submit": 1, - "description": "Start date of current order's period", - "fieldname": "from_date", - "fieldtype": "Date", - "label": "From", - "no_copy": 1, + "allow_on_submit": 1, + "description": "Start date of current order's period", + "fieldname": "from_date", + "fieldtype": "Date", + "label": "From", + "no_copy": 1, "permlevel": 0 - }, + }, { - "allow_on_submit": 1, - "description": "End date of current order's period", - "fieldname": "to_date", - "fieldtype": "Date", - "label": "To", - "no_copy": 1, + "allow_on_submit": 1, + "description": "End date of current order's period", + "fieldname": "to_date", + "fieldtype": "Date", + "label": "To", + "no_copy": 1, "permlevel": 0 - }, + }, { - "description": "Customer's Purchase Order Number", - "fieldname": "po_no", - "fieldtype": "Data", - "hidden": 0, - "label": "PO No", - "oldfieldname": "po_no", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "reqd": 0, + "description": "Customer's Purchase Order Number", + "fieldname": "po_no", + "fieldtype": "Data", + "hidden": 0, + "label": "PO No", + "oldfieldname": "po_no", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "reqd": 0, "width": "100px" - }, + }, { - "depends_on": "eval:doc.po_no", - "description": "Customer's Purchase Order Date", - "fieldname": "po_date", - "fieldtype": "Date", - "hidden": 0, - "label": "PO Date", - "oldfieldname": "po_date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 0, - "reqd": 0, + "depends_on": "eval:doc.po_no", + "description": "Customer's Purchase Order Date", + "fieldname": "po_date", + "fieldtype": "Date", + "hidden": 0, + "label": "PO Date", + "oldfieldname": "po_date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 0, + "reqd": 0, "width": "100px" - }, + }, { - "fieldname": "shipping_address_name", - "fieldtype": "Link", - "hidden": 1, - "in_filter": 1, - "label": "Shipping Address", - "options": "Address", - "permlevel": 0, - "print_hide": 1, + "fieldname": "shipping_address_name", + "fieldtype": "Link", + "hidden": 1, + "in_filter": 1, + "label": "Shipping Address", + "options": "Address", + "permlevel": 0, + "print_hide": 1, "read_only": 0 - }, + }, { - "fieldname": "shipping_address", - "fieldtype": "Small Text", - "hidden": 1, - "in_filter": 0, - "label": "Shipping Address", - "permlevel": 0, - "print_hide": 1, + "fieldname": "shipping_address", + "fieldtype": "Small Text", + "hidden": 1, + "in_filter": 0, + "label": "Shipping Address", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "sec_break45", - "fieldtype": "Section Break", - "label": "Currency and Price List", - "options": "icon-tag", - "permlevel": 0, + "fieldname": "sec_break45", + "fieldtype": "Section Break", + "label": "Currency and Price List", + "options": "icon-tag", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "currency", - "fieldtype": "Link", - "label": "Currency", - "oldfieldname": "currency", - "oldfieldtype": "Select", - "options": "Currency", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "fieldname": "currency", + "fieldtype": "Link", + "label": "Currency", + "oldfieldname": "currency", + "oldfieldtype": "Select", + "options": "Currency", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "width": "100px" - }, + }, { - "description": "Rate at which customer's currency is converted to company's base currency", - "fieldname": "conversion_rate", - "fieldtype": "Float", - "label": "Exchange Rate", - "oldfieldname": "conversion_rate", - "oldfieldtype": "Currency", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "description": "Rate at which customer's currency is converted to company's base currency", + "fieldname": "conversion_rate", + "fieldtype": "Float", + "label": "Exchange Rate", + "oldfieldname": "conversion_rate", + "oldfieldtype": "Currency", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "width": "100px" - }, + }, { - "fieldname": "column_break2", - "fieldtype": "Column Break", - "permlevel": 0, + "fieldname": "column_break2", + "fieldtype": "Column Break", + "permlevel": 0, "width": "50%" - }, + }, { - "fieldname": "selling_price_list", - "fieldtype": "Link", - "label": "Price List", - "oldfieldname": "price_list_name", - "oldfieldtype": "Select", - "options": "Price List", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "fieldname": "selling_price_list", + "fieldtype": "Link", + "label": "Price List", + "oldfieldname": "price_list_name", + "oldfieldtype": "Select", + "options": "Price List", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "width": "100px" - }, + }, { - "fieldname": "price_list_currency", - "fieldtype": "Link", - "label": "Price List Currency", - "options": "Currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "fieldname": "price_list_currency", + "fieldtype": "Link", + "label": "Price List Currency", + "options": "Currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "reqd": 1 - }, + }, { - "description": "Rate at which Price list currency is converted to company's base currency", - "fieldname": "plc_conversion_rate", - "fieldtype": "Float", - "label": "Price List Exchange Rate", - "permlevel": 0, - "print_hide": 1, + "description": "Rate at which Price list currency is converted to company's base currency", + "fieldname": "plc_conversion_rate", + "fieldtype": "Float", + "label": "Price List Exchange Rate", + "permlevel": 0, + "print_hide": 1, "reqd": 1 - }, + }, { - "fieldname": "ignore_pricing_rule", - "fieldtype": "Check", - "label": "Ignore Pricing Rule", - "no_copy": 1, - "permlevel": 1, + "fieldname": "ignore_pricing_rule", + "fieldtype": "Check", + "label": "Ignore Pricing Rule", + "no_copy": 1, + "permlevel": 1, "print_hide": 1 - }, + }, { - "fieldname": "items", - "fieldtype": "Section Break", - "label": "Items", - "oldfieldtype": "Section Break", - "options": "icon-shopping-cart", + "fieldname": "items", + "fieldtype": "Section Break", + "label": "Items", + "oldfieldtype": "Section Break", + "options": "icon-shopping-cart", "permlevel": 0 - }, + }, { - "allow_on_submit": 1, - "fieldname": "sales_order_details", - "fieldtype": "Table", - "label": "Sales Order Items", - "oldfieldname": "sales_order_details", - "oldfieldtype": "Table", - "options": "Sales Order Item", - "permlevel": 0, - "print_hide": 0, + "allow_on_submit": 1, + "fieldname": "sales_order_details", + "fieldtype": "Table", + "label": "Sales Order Items", + "oldfieldname": "sales_order_details", + "oldfieldtype": "Table", + "options": "Sales Order Item", + "permlevel": 0, + "print_hide": 0, "reqd": 1 - }, + }, { - "fieldname": "section_break_31", - "fieldtype": "Section Break", + "fieldname": "section_break_31", + "fieldtype": "Section Break", "permlevel": 0 - }, + }, { - "fieldname": "column_break_33a", - "fieldtype": "Column Break", + "fieldname": "column_break_33a", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "column_break_33", - "fieldtype": "Column Break", + "fieldname": "column_break_33", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "net_total_export", - "fieldtype": "Currency", - "label": "Net Total", - "options": "currency", - "permlevel": 0, + "fieldname": "net_total_export", + "fieldtype": "Currency", + "label": "Net Total", + "options": "currency", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "net_total", - "fieldtype": "Currency", - "label": "Net Total (Company Currency)", - "oldfieldname": "net_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, - "reqd": 0, + "fieldname": "net_total", + "fieldtype": "Currency", + "label": "Net Total (Company Currency)", + "oldfieldname": "net_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, + "reqd": 0, "width": "150px" - }, + }, { - "fieldname": "taxes", - "fieldtype": "Section Break", - "label": "Taxes and Charges", - "oldfieldtype": "Section Break", - "options": "icon-money", - "permlevel": 0, + "fieldname": "taxes", + "fieldtype": "Section Break", + "label": "Taxes and Charges", + "oldfieldtype": "Section Break", + "options": "icon-money", + "permlevel": 0, "print_hide": 0 - }, + }, { - "fieldname": "taxes_and_charges", - "fieldtype": "Link", - "label": "Taxes and Charges", - "oldfieldname": "charge", - "oldfieldtype": "Link", - "options": "Sales Taxes and Charges Master", - "permlevel": 0, + "fieldname": "taxes_and_charges", + "fieldtype": "Link", + "label": "Taxes and Charges", + "oldfieldname": "charge", + "oldfieldtype": "Link", + "options": "Sales Taxes and Charges Master", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "column_break_38", - "fieldtype": "Column Break", + "fieldname": "column_break_38", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "shipping_rule", - "fieldtype": "Link", - "label": "Shipping Rule", - "oldfieldtype": "Button", - "options": "Shipping Rule", - "permlevel": 0, + "fieldname": "shipping_rule", + "fieldtype": "Link", + "label": "Shipping Rule", + "oldfieldtype": "Button", + "options": "Shipping Rule", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "section_break_40", - "fieldtype": "Section Break", + "fieldname": "section_break_40", + "fieldtype": "Section Break", "permlevel": 0 - }, + }, { - "fieldname": "other_charges", - "fieldtype": "Table", - "label": "Sales Taxes and Charges", - "oldfieldname": "other_charges", - "oldfieldtype": "Table", - "options": "Sales Taxes and Charges", + "fieldname": "other_charges", + "fieldtype": "Table", + "label": "Sales Taxes and Charges", + "oldfieldname": "other_charges", + "oldfieldtype": "Table", + "options": "Sales Taxes and Charges", "permlevel": 0 - }, + }, { - "fieldname": "other_charges_calculation", - "fieldtype": "HTML", - "label": "Taxes and Charges Calculation", - "oldfieldtype": "HTML", - "permlevel": 0, + "fieldname": "other_charges_calculation", + "fieldtype": "HTML", + "label": "Taxes and Charges Calculation", + "oldfieldtype": "HTML", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "section_break_43", - "fieldtype": "Section Break", + "fieldname": "section_break_43", + "fieldtype": "Section Break", "permlevel": 0 - }, + }, { - "fieldname": "other_charges_total", - "fieldtype": "Currency", - "label": "Taxes and Charges Total (Company Currency)", - "oldfieldname": "other_charges_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, - "width": "150px" - }, - { - "fieldname": "column_break_46", - "fieldtype": "Column Break", - "permlevel": 0 - }, - { - "fieldname": "other_charges_total_export", - "fieldtype": "Currency", - "label": "Taxes and Charges Total", - "options": "currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "other_charges_total_export", + "fieldtype": "Currency", + "label": "Taxes and Charges Total", + "options": "currency", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "discount_amount", - "fieldtype": "Currency", - "label": "Discount Amount", - "options": "Company:company:default_currency", + "fieldname": "column_break_46", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "totals", - "fieldtype": "Section Break", - "label": "Totals", - "oldfieldtype": "Section Break", - "options": "icon-money", - "permlevel": 0, + "fieldname": "other_charges_total", + "fieldtype": "Currency", + "label": "Taxes and Charges Total (Company Currency)", + "oldfieldname": "other_charges_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, + "width": "150px" + }, + { + "fieldname": "discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount", + "options": "Company:company:default_currency", + "permlevel": 0 + }, + { + "fieldname": "totals", + "fieldtype": "Section Break", + "label": "Totals", + "oldfieldtype": "Section Break", + "options": "icon-money", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "grand_total", - "fieldtype": "Currency", - "label": "Grand Total (Company Currency)", - "oldfieldname": "grand_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, - "reqd": 0, + "fieldname": "grand_total", + "fieldtype": "Currency", + "label": "Grand Total (Company Currency)", + "oldfieldname": "grand_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, + "reqd": 0, "width": "150px" - }, + }, { - "fieldname": "rounded_total", - "fieldtype": "Currency", - "label": "Rounded Total (Company Currency)", - "oldfieldname": "rounded_total", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "fieldname": "rounded_total", + "fieldtype": "Currency", + "label": "Rounded Total (Company Currency)", + "oldfieldname": "rounded_total", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "width": "150px" - }, + }, { - "description": "In Words will be visible once you save the Sales Order.", - "fieldname": "in_words", - "fieldtype": "Data", - "label": "In Words (Company Currency)", - "oldfieldname": "in_words", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "description": "In Words will be visible once you save the Sales Order.", + "fieldname": "in_words", + "fieldtype": "Data", + "label": "In Words (Company Currency)", + "oldfieldname": "in_words", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "width": "200px" - }, + }, { - "fieldname": "column_break3", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 1, + "fieldname": "advance_paid", + "fieldtype": "Currency", + "label": "Advance Paid", + "permlevel": 0, + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "column_break3", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 1, "width": "50%" - }, + }, { - "fieldname": "grand_total_export", - "fieldtype": "Currency", - "label": "Grand Total", - "oldfieldname": "grand_total_export", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 0, - "read_only": 1, - "reqd": 0, + "fieldname": "grand_total_export", + "fieldtype": "Currency", + "label": "Grand Total", + "oldfieldname": "grand_total_export", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 0, + "read_only": 1, + "reqd": 0, "width": "150px" - }, + }, { - "fieldname": "rounded_total_export", - "fieldtype": "Currency", - "label": "Rounded Total", - "oldfieldname": "rounded_total_export", - "oldfieldtype": "Currency", - "options": "currency", - "permlevel": 0, - "print_hide": 0, - "read_only": 1, + "fieldname": "rounded_total_export", + "fieldtype": "Currency", + "label": "Rounded Total", + "oldfieldname": "rounded_total_export", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 0, + "read_only": 1, "width": "150px" - }, + }, { - "fieldname": "in_words_export", - "fieldtype": "Data", - "label": "In Words", - "oldfieldname": "in_words_export", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "read_only": 1, + "fieldname": "in_words_export", + "fieldtype": "Data", + "label": "In Words", + "oldfieldname": "in_words_export", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "read_only": 1, "width": "200px" - }, + }, { - "fieldname": "view_details", - "fieldtype": "Fold", - "label": "View Details", + "fieldname": "view_details", + "fieldtype": "Fold", + "label": "View Details", "permlevel": 0 - }, + }, { - "description": "Display all the individual items delivered with the main items", - "fieldname": "packing_list", - "fieldtype": "Section Break", - "hidden": 0, - "label": "Packing List", - "oldfieldtype": "Section Break", - "options": "icon-suitcase", - "permlevel": 0, + "description": "Display all the individual items delivered with the main items", + "fieldname": "packing_list", + "fieldtype": "Section Break", + "hidden": 0, + "label": "Packing List", + "oldfieldtype": "Section Break", + "options": "icon-suitcase", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "packing_details", - "fieldtype": "Table", - "label": "Packing Details", - "oldfieldname": "packing_details", - "oldfieldtype": "Table", - "options": "Packed Item", - "permlevel": 0, - "print_hide": 1, + "fieldname": "packing_details", + "fieldtype": "Table", + "label": "Packing Details", + "oldfieldname": "packing_details", + "oldfieldtype": "Table", + "options": "Packed Item", + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "fieldname": "terms_section_break", - "fieldtype": "Section Break", - "label": "Terms and Conditions", - "oldfieldtype": "Section Break", - "options": "icon-legal", - "permlevel": 0, + "fieldname": "terms_section_break", + "fieldtype": "Section Break", + "label": "Terms and Conditions", + "oldfieldtype": "Section Break", + "options": "icon-legal", + "permlevel": 0, "print_hide": 0 - }, + }, { - "fieldname": "tc_name", - "fieldtype": "Link", - "label": "Terms", - "oldfieldname": "tc_name", - "oldfieldtype": "Link", - "options": "Terms and Conditions", - "permlevel": 0, - "print_hide": 1, + "fieldname": "tc_name", + "fieldtype": "Link", + "label": "Terms", + "oldfieldname": "tc_name", + "oldfieldtype": "Link", + "options": "Terms and Conditions", + "permlevel": 0, + "print_hide": 1, "search_index": 0 - }, + }, { - "fieldname": "terms", - "fieldtype": "Text Editor", - "label": "Terms and Conditions Details", - "oldfieldname": "terms", - "oldfieldtype": "Text Editor", - "permlevel": 0, + "fieldname": "terms", + "fieldtype": "Text Editor", + "label": "Terms and Conditions Details", + "oldfieldname": "terms", + "oldfieldtype": "Text Editor", + "permlevel": 0, "print_hide": 0 - }, + }, { - "depends_on": "customer", - "fieldname": "contact_info", - "fieldtype": "Section Break", - "label": "Contact Info", - "options": "icon-bullhorn", + "depends_on": "customer", + "fieldname": "contact_info", + "fieldtype": "Section Break", + "label": "Contact Info", + "options": "icon-bullhorn", "permlevel": 0 - }, + }, { - "fieldname": "col_break45", - "fieldtype": "Column Break", - "permlevel": 0, + "fieldname": "col_break45", + "fieldtype": "Column Break", + "permlevel": 0, "width": "50%" - }, + }, { - "description": "Add / Edit", - "fieldname": "territory", - "fieldtype": "Link", - "in_filter": 1, - "label": "Territory", - "options": "Territory", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "description": "Add / Edit", + "fieldname": "territory", + "fieldtype": "Link", + "in_filter": 1, + "label": "Territory", + "options": "Territory", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "description": "Add / Edit", - "fieldname": "customer_group", - "fieldtype": "Link", - "in_filter": 1, - "label": "Customer Group", - "options": "Customer Group", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "description": "Add / Edit", + "fieldname": "customer_group", + "fieldtype": "Link", + "in_filter": 1, + "label": "Customer Group", + "options": "Customer Group", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "search_index": 1 - }, + }, { - "fieldname": "col_break46", - "fieldtype": "Column Break", - "permlevel": 0, + "fieldname": "col_break46", + "fieldtype": "Column Break", + "permlevel": 0, "width": "50%" - }, + }, { - "fieldname": "customer_address", - "fieldtype": "Link", - "hidden": 0, - "in_filter": 1, - "label": "Customer Address", - "options": "Address", - "permlevel": 0, + "fieldname": "customer_address", + "fieldtype": "Link", + "hidden": 0, + "in_filter": 1, + "label": "Customer Address", + "options": "Address", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "contact_person", - "fieldtype": "Link", - "in_filter": 1, - "label": "Contact Person", - "options": "Contact", - "permlevel": 0, + "fieldname": "contact_person", + "fieldtype": "Link", + "in_filter": 1, + "label": "Contact Person", + "options": "Contact", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "more_info", - "fieldtype": "Section Break", - "label": "More Info", - "oldfieldtype": "Section Break", - "options": "icon-file-text", - "permlevel": 0, + "fieldname": "more_info", + "fieldtype": "Section Break", + "label": "More Info", + "oldfieldtype": "Section Break", + "options": "icon-file-text", + "permlevel": 0, "print_hide": 1 - }, + }, { - "description": "Track this Sales Order against any Project", - "fieldname": "project_name", - "fieldtype": "Link", - "in_filter": 1, - "label": "Project Name", - "oldfieldname": "project_name", - "oldfieldtype": "Link", - "options": "Project", - "permlevel": 0, + "description": "Track this Sales Order against any Project", + "fieldname": "project_name", + "fieldtype": "Link", + "in_filter": 1, + "label": "Project Name", + "oldfieldname": "project_name", + "oldfieldtype": "Link", + "options": "Project", + "permlevel": 0, "search_index": 1 - }, + }, { - "depends_on": "eval:doc.source == 'Campaign'", - "fieldname": "campaign", - "fieldtype": "Link", - "label": "Campaign", - "oldfieldname": "campaign", - "oldfieldtype": "Link", - "options": "Campaign", - "permlevel": 0, + "depends_on": "eval:doc.source == 'Campaign'", + "fieldname": "campaign", + "fieldtype": "Link", + "label": "Campaign", + "oldfieldname": "campaign", + "oldfieldtype": "Link", + "options": "Campaign", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "source", - "fieldtype": "Select", - "label": "Source", - "oldfieldname": "source", - "oldfieldtype": "Select", - "options": "\nExisting Customer\nReference\nAdvertisement\nCold Calling\nExhibition\nSupplier Reference\nMass Mailing\nCustomer's Vendor\nCampaign", - "permlevel": 0, + "fieldname": "source", + "fieldtype": "Select", + "label": "Source", + "oldfieldname": "source", + "oldfieldtype": "Select", + "options": "\nExisting Customer\nReference\nAdvertisement\nCold Calling\nExhibition\nSupplier Reference\nMass Mailing\nCustomer's Vendor\nCampaign", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "column_break4", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 1, + "fieldname": "column_break4", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 1, "width": "50%" - }, + }, { - "allow_on_submit": 1, - "fieldname": "letter_head", - "fieldtype": "Link", - "label": "Letter Head", - "oldfieldname": "letter_head", - "oldfieldtype": "Select", - "options": "Letter Head", - "permlevel": 0, + "allow_on_submit": 1, + "fieldname": "letter_head", + "fieldtype": "Link", + "label": "Letter Head", + "oldfieldname": "letter_head", + "oldfieldtype": "Select", + "options": "Letter Head", + "permlevel": 0, "print_hide": 1 - }, + }, { - "allow_on_submit": 1, - "fieldname": "select_print_heading", - "fieldtype": "Link", - "label": "Print Heading", - "no_copy": 1, - "oldfieldname": "select_print_heading", - "oldfieldtype": "Link", - "options": "Print Heading", - "permlevel": 0, - "print_hide": 1, + "allow_on_submit": 1, + "fieldname": "select_print_heading", + "fieldtype": "Link", + "label": "Print Heading", + "no_copy": 1, + "oldfieldname": "select_print_heading", + "oldfieldtype": "Link", + "options": "Print Heading", + "permlevel": 0, + "print_hide": 1, "report_hide": 1 - }, + }, { - "fieldname": "fiscal_year", - "fieldtype": "Link", - "in_filter": 1, - "label": "Fiscal Year", - "oldfieldname": "fiscal_year", - "oldfieldtype": "Select", - "options": "Fiscal Year", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, - "search_index": 1, + "fieldname": "fiscal_year", + "fieldtype": "Link", + "in_filter": 1, + "label": "Fiscal Year", + "oldfieldname": "fiscal_year", + "oldfieldtype": "Select", + "options": "Fiscal Year", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, + "search_index": 1, "width": "150px" - }, + }, { - "fieldname": "section_break_78", - "fieldtype": "Section Break", - "oldfieldtype": "Column Break", - "permlevel": 0, - "print_hide": 1, + "fieldname": "section_break_78", + "fieldtype": "Section Break", + "oldfieldtype": "Column Break", + "permlevel": 0, + "print_hide": 1, "width": "50%" - }, + }, { - "default": "Draft", - "fieldname": "status", - "fieldtype": "Select", - "in_filter": 1, - "in_list_view": 1, - "label": "Status", - "no_copy": 1, - "oldfieldname": "status", - "oldfieldtype": "Select", - "options": "\nDraft\nSubmitted\nStopped\nCancelled", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, - "reqd": 1, - "search_index": 1, + "default": "Draft", + "fieldname": "status", + "fieldtype": "Select", + "in_filter": 1, + "in_list_view": 1, + "label": "Status", + "no_copy": 1, + "oldfieldname": "status", + "oldfieldtype": "Select", + "options": "\nDraft\nSubmitted\nStopped\nCancelled", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, + "reqd": 1, + "search_index": 1, "width": "100px" - }, + }, { - "fieldname": "delivery_status", - "fieldtype": "Select", - "hidden": 1, - "label": "Delivery Status", - "no_copy": 1, - "options": "Not Delivered\nFully Delivered\nPartly Delivered\nClosed\nNot Applicable", - "permlevel": 0, + "fieldname": "delivery_status", + "fieldtype": "Select", + "hidden": 1, + "label": "Delivery Status", + "no_copy": 1, + "options": "Not Delivered\nFully Delivered\nPartly Delivered\nClosed\nNot Applicable", + "permlevel": 0, "print_hide": 1 - }, + }, { - "depends_on": "eval:!doc.__islocal", - "description": "% of materials delivered against this Sales Order", - "fieldname": "per_delivered", - "fieldtype": "Percent", - "in_filter": 1, - "in_list_view": 1, - "label": "% Delivered", - "no_copy": 1, - "oldfieldname": "per_delivered", - "oldfieldtype": "Currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "depends_on": "eval:!doc.__islocal", + "description": "% of materials delivered against this Sales Order", + "fieldname": "per_delivered", + "fieldtype": "Percent", + "in_filter": 1, + "in_list_view": 1, + "label": "% Delivered", + "no_copy": 1, + "oldfieldname": "per_delivered", + "oldfieldtype": "Currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "width": "100px" - }, + }, { - "fieldname": "column_break_81", - "fieldtype": "Column Break", + "fieldname": "column_break_81", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "depends_on": "eval:!doc.__islocal", - "description": "% of materials billed against this Sales Order", - "fieldname": "per_billed", - "fieldtype": "Percent", - "in_filter": 1, - "in_list_view": 1, - "label": "% Amount Billed", - "no_copy": 1, - "oldfieldname": "per_billed", - "oldfieldtype": "Currency", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "depends_on": "eval:!doc.__islocal", + "description": "% of materials billed against this Sales Order", + "fieldname": "per_billed", + "fieldtype": "Percent", + "in_filter": 1, + "in_list_view": 1, + "label": "% Amount Billed", + "no_copy": 1, + "oldfieldname": "per_billed", + "oldfieldtype": "Currency", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "width": "100px" - }, + }, { - "fieldname": "billing_status", - "fieldtype": "Select", - "hidden": 1, - "label": "Billing Status", - "no_copy": 1, - "options": "Not Billed\nFully Billed\nPartly Billed\nClosed", - "permlevel": 0, + "fieldname": "billing_status", + "fieldtype": "Select", + "hidden": 1, + "label": "Billing Status", + "no_copy": 1, + "options": "Not Billed\nFully Billed\nPartly Billed\nClosed", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "sales_team_section_break", - "fieldtype": "Section Break", - "label": "Sales Team", - "oldfieldtype": "Section Break", - "options": "icon-group", - "permlevel": 0, + "fieldname": "sales_team_section_break", + "fieldtype": "Section Break", + "label": "Sales Team", + "oldfieldtype": "Section Break", + "options": "icon-group", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "sales_partner", - "fieldtype": "Link", - "in_filter": 1, - "label": "Sales Partner", - "oldfieldname": "sales_partner", - "oldfieldtype": "Link", - "options": "Sales Partner", - "permlevel": 0, - "print_hide": 1, - "search_index": 1, + "fieldname": "sales_partner", + "fieldtype": "Link", + "in_filter": 1, + "label": "Sales Partner", + "oldfieldname": "sales_partner", + "oldfieldtype": "Link", + "options": "Sales Partner", + "permlevel": 0, + "print_hide": 1, + "search_index": 1, "width": "150px" - }, + }, { - "fieldname": "column_break7", - "fieldtype": "Column Break", - "permlevel": 0, - "print_hide": 1, + "fieldname": "column_break7", + "fieldtype": "Column Break", + "permlevel": 0, + "print_hide": 1, "width": "50%" - }, + }, { - "fieldname": "commission_rate", - "fieldtype": "Float", - "label": "Commission Rate", - "oldfieldname": "commission_rate", - "oldfieldtype": "Currency", - "permlevel": 0, - "print_hide": 1, + "fieldname": "commission_rate", + "fieldtype": "Float", + "label": "Commission Rate", + "oldfieldname": "commission_rate", + "oldfieldtype": "Currency", + "permlevel": 0, + "print_hide": 1, "width": "100px" - }, + }, { - "fieldname": "total_commission", - "fieldtype": "Currency", - "label": "Total Commission", - "oldfieldname": "total_commission", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "permlevel": 0, + "fieldname": "total_commission", + "fieldtype": "Currency", + "label": "Total Commission", + "oldfieldname": "total_commission", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "section_break1", - "fieldtype": "Section Break", - "permlevel": 0, + "fieldname": "section_break1", + "fieldtype": "Section Break", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "sales_team", - "fieldtype": "Table", - "label": "Sales Team1", - "oldfieldname": "sales_team", - "oldfieldtype": "Table", - "options": "Sales Team", - "permlevel": 0, + "fieldname": "sales_team", + "fieldtype": "Table", + "label": "Sales Team1", + "oldfieldname": "sales_team", + "oldfieldtype": "Table", + "options": "Sales Team", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "recurring_order", - "fieldtype": "Section Break", - "label": "Recurring Order", - "options": "icon-time", + "fieldname": "recurring_order", + "fieldtype": "Section Break", + "label": "Recurring Order", + "options": "icon-time", "permlevel": 0 - }, + }, { - "fieldname": "column_break82", - "fieldtype": "Column Break", - "label": "Column Break", + "fieldname": "column_break82", + "fieldtype": "Column Break", + "label": "Column Break", "permlevel": 0 - }, + }, { - "allow_on_submit": 1, - "depends_on": "eval:doc.docstatus<2", - "description": "Check if recurring order, uncheck to stop recurring or put proper End Date", - "fieldname": "is_recurring", - "fieldtype": "Check", - "label": "Is Recurring", - "no_copy": 1, - "permlevel": 0, + "allow_on_submit": 1, + "depends_on": "eval:doc.docstatus<2", + "description": "Check if recurring order, uncheck to stop recurring or put proper End Date", + "fieldname": "is_recurring", + "fieldtype": "Check", + "label": "Is Recurring", + "no_copy": 1, + "permlevel": 0, "print_hide": 1 - }, + }, { - "allow_on_submit": 1, - "depends_on": "eval:doc.is_recurring==1", - "description": "Select the period when the invoice will be generated automatically", - "fieldname": "recurring_type", - "fieldtype": "Select", - "label": "Recurring Type", - "no_copy": 1, - "options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly", - "permlevel": 0, + "allow_on_submit": 1, + "depends_on": "eval:doc.is_recurring==1", + "description": "Select the period when the invoice will be generated automatically", + "fieldname": "recurring_type", + "fieldtype": "Select", + "label": "Recurring Type", + "no_copy": 1, + "options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly", + "permlevel": 0, "print_hide": 1 - }, + }, { - "allow_on_submit": 1, - "depends_on": "eval:doc.is_recurring==1", - "description": "The day of the month on which auto order will be generated e.g. 05, 28 etc ", - "fieldname": "repeat_on_day_of_month", - "fieldtype": "Int", - "label": "Repeat on Day of Month", - "no_copy": 1, - "permlevel": 0, + "allow_on_submit": 1, + "depends_on": "eval:doc.is_recurring==1", + "description": "The day of the month on which auto order will be generated e.g. 05, 28 etc ", + "fieldname": "repeat_on_day_of_month", + "fieldtype": "Int", + "label": "Repeat on Day of Month", + "no_copy": 1, + "permlevel": 0, "print_hide": 1 - }, + }, { - "depends_on": "eval:doc.is_recurring==1", - "description": "The date on which next invoice will be generated. It is generated on submit.", - "fieldname": "next_date", - "fieldtype": "Date", - "label": "Next Date", - "no_copy": 1, - "permlevel": 0, - "print_hide": 1, + "depends_on": "eval:doc.is_recurring==1", + "description": "The date on which next invoice will be generated. It is generated on submit.", + "fieldname": "next_date", + "fieldtype": "Date", + "label": "Next Date", + "no_copy": 1, + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "allow_on_submit": 1, - "depends_on": "eval:doc.is_recurring==1", - "description": "The date on which recurring order will be stop", - "fieldname": "end_date", - "fieldtype": "Date", - "label": "End Date", - "no_copy": 1, - "permlevel": 0, + "allow_on_submit": 1, + "depends_on": "eval:doc.is_recurring==1", + "description": "The date on which recurring order will be stop", + "fieldname": "end_date", + "fieldtype": "Date", + "label": "End Date", + "no_copy": 1, + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "column_break83", - "fieldtype": "Column Break", - "label": "Column Break", - "permlevel": 0, + "fieldname": "column_break83", + "fieldtype": "Column Break", + "label": "Column Break", + "permlevel": 0, "print_hide": 1 - }, + }, { - "depends_on": "eval:doc.is_recurring==1", - "fieldname": "recurring_id", - "fieldtype": "Data", - "label": "Recurring Id", - "no_copy": 1, - "permlevel": 0, - "print_hide": 1, + "depends_on": "eval:doc.is_recurring==1", + "fieldname": "recurring_id", + "fieldtype": "Data", + "label": "Recurring Id", + "no_copy": 1, + "permlevel": 0, + "print_hide": 1, "read_only": 1 - }, + }, { - "allow_on_submit": 1, - "depends_on": "eval:doc.is_recurring==1", - "description": "Enter email id separated by commas, order will be mailed automatically on particular date", - "fieldname": "notification_email_address", - "fieldtype": "Small Text", - "ignore_user_permissions": 0, - "label": "Notification Email Address", - "no_copy": 1, - "permlevel": 0, + "allow_on_submit": 1, + "depends_on": "eval:doc.is_recurring==1", + "description": "Enter email id separated by commas, order will be mailed automatically on particular date", + "fieldname": "notification_email_address", + "fieldtype": "Small Text", + "ignore_user_permissions": 0, + "label": "Notification Email Address", + "no_copy": 1, + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "against_income_account", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Against Income Account", - "no_copy": 1, - "permlevel": 0, - "print_hide": 1, + "fieldname": "against_income_account", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Against Income Account", + "no_copy": 1, + "permlevel": 0, + "print_hide": 1, "report_hide": 1 } - ], - "icon": "icon-file-text", - "idx": 1, - "is_submittable": 1, - "issingle": 0, - "modified": "2014-09-09 05:35:34.761247", - "modified_by": "Administrator", - "module": "Selling", - "name": "Sales Order", - "owner": "Administrator", + ], + "icon": "icon-file-text", + "idx": 1, + "is_submittable": 1, + "issingle": 0, + "modified": "2014-09-10 05:35:34.761247", + "modified_by": "Administrator", + "module": "Selling", + "name": "Sales Order", + "owner": "Administrator", "permissions": [ { - "amend": 1, - "apply_user_permissions": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales User", - "submit": 1, + "amend": 1, + "apply_user_permissions": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales User", + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "import": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales Manager", - "set_user_permissions": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "import": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales Manager", + "set_user_permissions": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "apply_user_permissions": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Maintenance User", - "submit": 1, + "amend": 1, + "apply_user_permissions": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Maintenance User", + "submit": 1, "write": 1 - }, + }, { - "apply_user_permissions": 1, - "cancel": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, + "apply_user_permissions": 1, + "cancel": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, "role": "Accounts User" - }, + }, { - "apply_user_permissions": 1, - "cancel": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, + "apply_user_permissions": 1, + "cancel": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, "role": "Customer" - }, + }, { - "apply_user_permissions": 1, - "permlevel": 0, - "read": 1, - "report": 1, + "apply_user_permissions": 1, + "permlevel": 0, + "read": 1, + "report": 1, "role": "Material User" - }, + }, { - "permlevel": 1, - "read": 1, - "role": "Sales Manager", + "permlevel": 1, + "read": 1, + "role": "Sales Manager", "write": 1 } - ], - "read_only_onload": 1, - "search_fields": "status,transaction_date,customer,customer_name, territory,order_type,company", - "sort_field": "modified", + ], + "read_only_onload": 1, + "search_fields": "status,transaction_date,customer,customer_name, territory,order_type,company", + "sort_field": "modified", "sort_order": "DESC" -} \ No newline at end of file +} diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index ff14f9d0c1..d2996e9574 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -326,6 +326,11 @@ def make_delivery_note(source_name, target_doc=None): @frappe.whitelist() def make_sales_invoice(source_name, target_doc=None): + def postprocess(source, target): + set_missing_values(source, target) + #Get the advance paid Journal Vouchers in Sales Invoice Advance + target.get_advances() + def set_missing_values(source, target): target.is_pos = 0 target.ignore_pricing_rule = 1 @@ -361,7 +366,18 @@ def make_sales_invoice(source_name, target_doc=None): "doctype": "Sales Team", "add_if_empty": True } - }, target_doc, set_missing_values) + }, target_doc, postprocess) + + def set_advance_vouchers(source, target): + advance_voucher_list = [] + + advance_voucher = frappe.db.sql(""" + select + t1.name as voucher_no, t1.posting_date, t1.remark, t2.account, + t2.name as voucher_detail_no, {amount_query} as payment_amount, t2.is_advance + from + `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 + """) return doclist diff --git a/erpnext/selling/doctype/sales_order/test_records.json b/erpnext/selling/doctype/sales_order/test_records.json index 88af30c1f9..8db9915c2d 100644 --- a/erpnext/selling/doctype/sales_order/test_records.json +++ b/erpnext/selling/doctype/sales_order/test_records.json @@ -1,5 +1,6 @@ [ { + "advance_paid": 0.0, "company": "_Test Company", "conversion_rate": 1.0, "currency": "INR", diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index b07eab74fb..14c409ba80 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -223,8 +223,8 @@ def validate_serial_no(sle, item_det): sr = frappe.get_doc("Serial No", serial_no) if sr.item_code!=sle.item_code: - frappe.throw(_("Serial No {0} does not belong to Item {1}").format(sle.item_code, - serial_no), SerialNoItemError) + frappe.throw(_("Serial No {0} does not belong to Item {1}").format(serial_no, + sle.item_code), SerialNoItemError) if sr.warehouse and sle.actual_qty > 0: frappe.throw(_("Serial No {0} has already been received").format(sr.name),