diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json index e27eaabedc..441266199a 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.json +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json @@ -74,36 +74,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "due_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Due Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -748,7 +718,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-08-10 18:06:44.904081", + "modified": "2017-12-20 12:40:09.611951", "modified_by": "Administrator", "module": "Accounts", "name": "GL Entry", @@ -824,4 +794,4 @@ "sort_order": "DESC", "track_changes": 0, "track_seen": 0 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index c92a7287eb..48062a3dc7 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -61,16 +61,6 @@ frappe.ui.form.on("Journal Entry", { } } }); - }, - - accounts_on_form_rendered: function(frm) { - const options = frm.doc.__onload; - - if (options && frm.cur_grid) { - frm.cur_grid.get_field("reference_due_date") - .df.options = options[frm.cur_grid.get_field('reference_name').value]; - frm.cur_grid.refresh_field('reference_due_date'); - } } }); @@ -204,39 +194,8 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ }) }, - due_date_options_cache: {}, - reference_name: function(doc, cdt, cdn) { var d = frappe.get_doc(cdt, cdn); - var me = this; - - const get_invoice_due_dates = invoice_name => { - const options = this.due_date_options_cache[invoice_name]; - const input = $(cur_frm.fields_dict["accounts"].wrapper).find("select[data-fieldname=reference_due_date]"); - - if (options) { - input.empty(); - input.add_options(options); - frappe.model.set_value(cdt, cdn, "reference_due_date", options[0]); - } - else { - frappe.call({ - method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_invoice_due_dates", - args: {name: invoice_name}, - callback: function(r) { - const options = []; - $.each(r.message, function(key, value) { - options.push(value.due_date); - }); - input.empty(); - input.add_options(options); - frappe.model.set_value(cdt, cdn, "reference_due_date", options[0]); - me.frm.cur_grid.get_field("reference_due_date").df.options = options.join('\n'); - me.due_date_options_cache[d.reference_name] = options; - } - }); - } - } if(d.reference_name) { if (d.reference_type==="Purchase Invoice" && !flt(d.debit)) { @@ -246,32 +205,6 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ } else if (d.reference_type==="Journal Entry" && !flt(d.credit) && !flt(d.debit)) { this.get_outstanding('Journal Entry', d.reference_name, doc.company, d); } - - if( in_list(["Sales Invoice", "Purchase Invoice"]), d.reference_type) { - get_invoice_due_dates(d.reference_name); - } - } - }, - - reference_due_date: function(doc, cdt, cdn) { - const d = frappe.get_doc(cdt, cdn); - - if (d.reference_type && d.reference_name && d.reference_due_date) { - if (in_list(["Sales Invoice", "Purchase Invoice"], d.reference_type)) { - frappe.model.set_value(cdt, cdn, 'debit_in_account_currency', ''); - frappe.model.set_value(cdt, cdn, 'credit_in_account_currency', ''); - } - if (d.reference_type==="Purchase Invoice") { - this.get_outstanding( - 'Purchase Invoice', d.reference_name, doc.company, d, d.reference_due_date - ); - } else if (d.reference_type==="Sales Invoice") { - this.get_outstanding( - 'Sales Invoice', d.reference_name, doc.company, d, d.reference_due_date - ); - } - - frappe.model.set_value(cdt, cdn, 'reference_due_date', d.reference_due_date); } }, @@ -286,8 +219,6 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ "company": company } - if (due_date) args.due_date = due_date; - return frappe.call({ method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_outstanding", args: { args: args}, diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 0c3503b683..5e67e4423f 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe, erpnext, json -from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, DATE_FORMAT +from frappe.utils import cstr, flt, fmt_money, formatdate, getdate from frappe import msgprint, _, scrub from erpnext.controllers.accounts_controller import AccountsController from erpnext.accounts.utils import get_balance_on, get_account_currency @@ -434,8 +434,7 @@ class JournalEntry(AccountsController): "against_voucher": d.reference_name, "remarks": self.remark, "cost_center": d.cost_center, - "project": d.project, - "due_date": d.reference_due_date + "project": d.project }) ) @@ -687,54 +686,22 @@ def get_payment_entry(ref_doc, args): "remark": args.get("remarks") }) - if not ref_doc.payment_schedule: - je.append("accounts", { - "account": args.get("party_account"), - "party_type": args.get("party_type"), - "party": ref_doc.get(args.get("party_type").lower()), - "cost_center": cost_center, - "account_type": frappe.db.get_value("Account", args.get("party_account"), "account_type"), - "account_currency": args.get("party_account_currency") or \ - get_account_currency(args.get("party_account")), - "balance": get_balance_on(args.get("party_account")), - "party_balance": get_balance_on(party=args.get("party"), party_type=args.get("party_type")), - "exchange_rate": exchange_rate, - args.get("amount_field_party"): args.get("amount"), - "is_advance": args.get("is_advance"), - "reference_type": ref_doc.doctype, - "reference_name": ref_doc.name - }) - - else: - options_ref_name_list = [ - d.due_date.strftime(DATE_FORMAT) for d in ref_doc.payment_schedule - if d.get('due_date') - ] - - for payment_term in ref_doc.payment_schedule: - je.append("accounts", { - "account": args.get("party_account"), - "party_type": args.get("party_type"), - "party": ref_doc.get(args.get("party_type").lower()), - "cost_center": cost_center, - "account_type": frappe.db.get_value("Account", args.get("party_account"), "account_type"), - "account_currency": args.get("party_account_currency") or \ - get_account_currency(args.get("party_account")), - "balance": get_balance_on(args.get("party_account")), - "party_balance": get_balance_on(party=args.get("party"), party_type=args.get("party_type")), - "exchange_rate": exchange_rate, - args.get("amount_field_party"): payment_term.payment_amount, - "is_advance": args.get("is_advance"), - "reference_type": ref_doc.doctype, - "reference_name": ref_doc.name, - "reference_due_date": payment_term.due_date - }) - je.set_onload(ref_doc.name, '\n'.join(options_ref_name_list)) - - # First multi currency check - for row in je.accounts: - if row.account_currency != ref_doc.company_currency: - je.multi_currency = 1 + party_row = je.append("accounts", { + "account": args.get("party_account"), + "party_type": args.get("party_type"), + "party": ref_doc.get(args.get("party_type").lower()), + "cost_center": cost_center, + "account_type": frappe.db.get_value("Account", args.get("party_account"), "account_type"), + "account_currency": args.get("party_account_currency") or \ + get_account_currency(args.get("party_account")), + "balance": get_balance_on(args.get("party_account")), + "party_balance": get_balance_on(party=args.get("party"), party_type=args.get("party_type")), + "exchange_rate": exchange_rate, + args.get("amount_field_party"): args.get("amount"), + "is_advance": args.get("is_advance"), + "reference_type": ref_doc.doctype, + "reference_name": ref_doc.name + }) bank_row = je.append("accounts") @@ -758,8 +725,8 @@ def get_payment_entry(ref_doc, args): bank_row.set(args.get("amount_field_bank"), amount * exchange_rate) # Multi currency check again - if not je.multi_currency: - if bank_row.account_currency and bank_row.account_currency != ref_doc.company_currency: + if party_row.account_currency != ref_doc.company_currency \ + or (bank_row.account_currency and bank_row.account_currency != ref_doc.company_currency): je.multi_currency = 1 je.set_amounts_in_company_currency() @@ -816,7 +783,8 @@ def get_outstanding(args): } elif args.get("doctype") in ("Sales Invoice", "Purchase Invoice"): party_type = "Customer" if args.get("doctype") == "Sales Invoice" else "Supplier" - invoice = frappe.get_doc(args['doctype'], args['docname']).as_dict() + invoice = frappe.db.get_value(args["doctype"], args["docname"], + ["outstanding_amount", "conversion_rate", scrub(party_type)], as_dict=1) exchange_rate = invoice.conversion_rate if (args.get("account_currency") != company_currency) else 1 @@ -827,23 +795,13 @@ def get_outstanding(args): amount_field = "debit_in_account_currency" \ if flt(invoice.outstanding_amount) > 0 else "credit_in_account_currency" - if args.get('due_date'): - outstanding = '' - for d in invoice.payment_schedule: - if d.due_date == getdate(args['due_date']): - outstanding = abs(flt(d.payment_amount)) - break - else: - outstanding = abs(flt(invoice.outstanding_amount)) - return { - amount_field: outstanding, + amount_field: abs(flt(invoice.outstanding_amount)), "exchange_rate": exchange_rate, "party_type": party_type, "party": invoice.get(scrub(party_type)) } - @frappe.whitelist() def get_party_account_and_balance(company, party_type, party): if not frappe.has_permission("Account"): @@ -941,15 +899,4 @@ def get_average_exchange_rate(account): bank_balance_in_company_currency = get_balance_on(account, in_account_currency=False) exchange_rate = bank_balance_in_company_currency / bank_balance_in_account_currency - return exchange_rate - - -@frappe.whitelist() -def get_invoice_due_dates(name): - result = frappe.get_list( - doctype='GL Entry', - filters={'voucher_no': name, "ifnull(due_date, '')": ('!=', '')}, - fields=['due_date'], distinct=True - ) - - return result + return exchange_rate \ No newline at end of file diff --git a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json index 23b6399c7b..76ff72763b 100644 --- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json +++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json @@ -661,39 +661,7 @@ "search_index": 0, "set_only_once": 0, "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.reference_type&&!in_list(doc.reference_type, ['Expense Claim', 'Asset', 'Employee Loan', 'Employee Advance'])", - "fieldname": "reference_due_date", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Reference Due Date", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index ca247ef9a2..1fac8e99f1 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -71,9 +71,10 @@ class PaymentEntry(AccountsController): def validate_duplicate_entry(self): reference_names = [] for d in self.get("references"): - if (d.reference_doctype, d.reference_name, d.due_date) in reference_names: - frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}").format(d.idx, d.reference_doctype, d.reference_name)) - reference_names.append((d.reference_doctype, d.reference_name, d.due_date)) + if (d.reference_doctype, d.reference_name) in reference_names: + frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}") + .format(d.idx, d.reference_doctype, d.reference_name)) + reference_names.append((d.reference_doctype, d.reference_name)) def validate_allocated_amount(self): for d in self.get("references"): @@ -413,8 +414,7 @@ class PaymentEntry(AccountsController): gle = party_gl_dict.copy() gle.update({ "against_voucher_type": d.reference_doctype, - "against_voucher": d.reference_name, - "due_date": d.due_date + "against_voucher": d.reference_name }) allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate), @@ -545,10 +545,8 @@ def get_outstanding_reference_documents(args): def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency): if party_type == "Customer": voucher_type = 'Sales Order' - payment_dr_or_cr = "credit_in_account_currency - debit_in_account_currency" elif party_type == "Supplier": voucher_type = 'Purchase Order' - payment_dr_or_cr = "debit_in_account_currency - credit_in_account_currency" elif party_type == "Employee": voucher_type = None @@ -557,131 +555,36 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" orders = frappe.db.sql(""" - select - name as voucher_no, - {ref_field} as invoice_amount, - ({ref_field} - advance_paid) as outstanding_amount, - transaction_date as posting_date - from - `tab{voucher_type}` - where - {party_type} = %s - and docstatus = 1 - and ifnull(status, "") != "Closed" - and {ref_field} > advance_paid - and abs(100 - per_billed) > 0.01 - order by - transaction_date, name - """.format(**{ - "ref_field": ref_field, - "voucher_type": voucher_type, - "party_type": scrub(party_type) - }), party, as_dict=True) - - if voucher_type and party_type is not "Employee": - ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" - - # find orders without considering if they have Payment Schedule - orders_without_schedule = frappe.db.sql(""" - select - name as voucher_no, - {ref_field} as invoice_amount, - ({ref_field} - advance_paid) as outstanding_amount, - transaction_date as posting_date - from - `tab{voucher_type}` - where - {party_type} = %s - and docstatus = 1 - and ifnull(status, "") != "Closed" - and {ref_field} > advance_paid - and abs(100 - per_billed) > 0.01 - order by - transaction_date, name - """.format(**{ - "ref_field": ref_field, - "voucher_type": voucher_type, - "party_type": scrub(party_type) - }), party, as_dict=True) - - # find orders considering if they have Payment Schedule - if voucher_type and party_type is not "Employee": - ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" - - orders_with_schedule = frappe.db.sql(""" select - VT.name as voucher_no, - PS.payment_amount as invoice_amount, - PS.payment_amount - (select - ifnull(sum({payment_dr_or_cr}), 0) - from `tabGL Entry` - where - against_voucher = VT.name - and due_date = PS.due_date - ) as outstanding_amount, - VT.transaction_date as posting_date, - PS.due_date + name as voucher_no, + {ref_field} as invoice_amount, + ({ref_field} - advance_paid) as outstanding_amount, + transaction_date as posting_date from - `tab{voucher_type}` VT - join - `tabPayment Schedule` PS on VT.name = PS.parent + `tab{voucher_type}` where {party_type} = %s - and VT.docstatus = 1 + and docstatus = 1 and ifnull(status, "") != "Closed" and {ref_field} > advance_paid and abs(100 - per_billed) > 0.01 order by - VT.transaction_date, VT.name - """.format(**{ - "ref_field": ref_field, - "voucher_type": voucher_type, - "party_type": scrub(party_type), - "payment_dr_or_cr": payment_dr_or_cr - }), party, as_dict=True) - - # reconcile both results such that we have a list that contains unique entries. - # Where both lists contain a record that is common, we select the one with - # linked Payment Schedule - orders = _merge_query_results(orders_without_schedule, orders_with_schedule, 'voucher_no') + transaction_date, name + """.format(**{ + "ref_field": ref_field, + "voucher_type": voucher_type, + "party_type": scrub(party_type) + }), party, as_dict=True) order_list = [] for d in orders: d["voucher_type"] = voucher_type # This assumes that the exchange rate required is the one in the SO - d["exchange_rate"] = get_exchange_rate(party_account_currency, - company_currency, posting_date) + d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency, posting_date) order_list.append(d) return order_list - -def _merge_query_results(result1, result2, dict_key): - """ - Merges two list of query results that are dictionaries. - For every item in result1 that is found in result2, the item is removed from - result1. At the end of processing result1, result1 and result2 are concatenated - and returned. - - :param result1: List of dict - :param result2: List of dict - :return: List of dict - """ - for item in result1[:]: - found = False - for item2 in result2: - if item[dict_key] == item2[dict_key]: - found = True - break - - if found: - result1.remove(item) - - final_result = result1 + result2 - - return final_result - - def get_negative_outstanding_invoices(party_type, party, party_account, party_account_currency, company_currency): voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice" if party_account_currency == company_currency: @@ -900,40 +803,15 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount= pe.allocate_payment_amount = 1 pe.letter_head = doc.get("letter_head") - if dt == "Employee Advance": - pe.append("references", { - 'reference_doctype': dt, - 'reference_name': dn, - 'total_amount': grand_total, - 'outstanding_amount': outstanding_amount, - 'allocated_amount': outstanding_amount - }) - else: - args = { - 'party_account': party_account, - 'company': pe.company, - 'party_type': pe.party_type, - 'party': pe.party, - 'posting_date': pe.posting_date, - 'voucher_type': dt, - 'voucher_no': dn - } - references = get_outstanding_reference_documents(args=args) - - for reference in references: - if reference.voucher_no == dn: - allocated_amount = min(paid_amount, reference.outstanding_amount) - pe.append("references", { - 'reference_doctype': reference.voucher_type, - 'reference_name': reference.voucher_no, - 'due_date': reference.due_date, - 'total_amount': reference.invoice_amount, - 'outstanding_amount': reference.outstanding_amount, - 'allocated_amount': allocated_amount, - "bill_no": reference.get("bill_no") - }) - if paid_amount: - paid_amount -= allocated_amount + pe.append("references", { + 'reference_doctype': dt, + 'reference_name': dn, + "bill_no": doc.get("bill_no"), + "due_date": doc.get("due_date"), + 'total_amount': grand_total, + 'outstanding_amount': outstanding_amount, + 'allocated_amount': outstanding_amount + }) pe.setup_party_account_field() pe.set_missing_values() diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py index a3a78a33e7..7ec8245188 100644 --- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py @@ -66,18 +66,6 @@ class TestPaymentEntry(unittest.TestCase): outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount")) self.assertEqual(outstanding_amount, 100) - def test_payment_entry_against_si_multi_due_dates(self): - si = create_sales_invoice(do_not_save=1) - si.payment_terms_template = '_Test Payment Term Template' - si.insert() - si.submit() - - pe = get_payment_entry(si.doctype, si.name) - pe.reference_no = "1" - pe.reference_date = "2016-01-01" - pe.insert() - pe.submit() - def test_payment_entry_against_pi(self): pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC", currency="USD", conversion_rate=50) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index b1dab508f5..07c136bf71 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -363,27 +363,7 @@ class PurchaseInvoice(BuyingController): def make_supplier_gl_entry(self, gl_entries): grand_total = self.rounded_total or self.grand_total - if self.get("payment_schedule"): - for d in self.get("payment_schedule"): - payment_amount_in_company_currency = flt(d.payment_amount * self.conversion_rate, - d.precision("payment_amount")) - - gl_entries.append( - self.get_gl_dict({ - "account": self.credit_to, - "party_type": "Supplier", - "party": self.supplier, - "due_date": d.due_date, - "against": self.against_expense_account, - "credit": payment_amount_in_company_currency, - "credit_in_account_currency": payment_amount_in_company_currency \ - if self.party_account_currency==self.company_currency else d.payment_amount, - "against_voucher": self.return_against if cint(self.is_return) else self.name, - "against_voucher_type": self.doctype - }, self.party_account_currency) - ) - - elif grand_total: + if grand_total: # Didnot use base_grand_total to book rounding loss gle grand_total_in_company_currency = flt(grand_total * self.conversion_rate, self.precision("grand_total")) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 3ac521a7cd..4b0b991cc4 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals import unittest import frappe, erpnext import frappe.model -from frappe.utils import cint, flt, today, nowdate, getdate, add_days +from frappe.utils import cint, flt, today, nowdate, add_days import frappe.defaults from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \ test_records as pr_test_records @@ -647,39 +647,6 @@ class TestPurchaseInvoice(unittest.TestCase): self.assertEquals(pi.total_taxes_and_charges, 462.3) self.assertEquals(pi.grand_total, 1712.3) - def test_gl_entry_based_on_payment_schedule(self): - pi = make_purchase_invoice(do_not_save=True, supplier="_Test Supplier P") - pi.append("payment_schedule", { - "due_date": add_days(nowdate(), 15), - "payment_amount": 100, - "invoice_portion": 40.00 - }) - pi.append("payment_schedule", { - "due_date": add_days(nowdate(), 25), - "payment_amount": 150, - "invoice_portion": 60.00 - }) - - pi.save() - pi.submit() - - gl_entries = frappe.db.sql("""select account, debit, credit, due_date - from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s - order by account asc, debit asc""", pi.name, as_dict=1) - self.assertTrue(gl_entries) - - expected_gl_entries = sorted([ - [pi.credit_to, 0.0, 100.0, add_days(nowdate(), 15)], - [pi.credit_to, 0.0, 150.0, add_days(nowdate(), 25)], - ["_Test Account Cost for Goods Sold - _TC", 250.0, 0.0, None] - ]) - - for i, gle in enumerate(sorted(gl_entries, key=lambda gle: gle.account)): - self.assertEquals(expected_gl_entries[i][0], gle.account) - self.assertEquals(expected_gl_entries[i][1], gle.debit) - self.assertEquals(expected_gl_entries[i][2], gle.credit) - self.assertEquals(getdate(expected_gl_entries[i][3]), getdate(gle.due_date)) - def test_make_pi_without_terms(self): pi = make_purchase_invoice(do_not_save=1) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 76b50c21a6..c457f9ad51 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -637,27 +637,7 @@ class SalesInvoice(SellingController): def make_customer_gl_entry(self, gl_entries): grand_total = self.rounded_total or self.grand_total - if self.get("payment_schedule"): - for d in self.get("payment_schedule"): - payment_amount_in_company_currency = flt(d.payment_amount * self.conversion_rate, - d.precision("payment_amount")) - - gl_entries.append( - self.get_gl_dict({ - "account": self.debit_to, - "party_type": "Customer", - "party": self.customer, - "due_date": d.due_date, - "against": self.against_income_account, - "debit": payment_amount_in_company_currency, - "debit_in_account_currency": payment_amount_in_company_currency \ - if self.party_account_currency==self.company_currency else d.payment_amount, - "against_voucher": self.return_against if cint(self.is_return) else self.name, - "against_voucher_type": self.doctype - }, self.party_account_currency) - ) - - elif grand_total: + if grand_total: # Didnot use base_grand_total to book rounding loss gle grand_total_in_company_currency = flt(grand_total * self.conversion_rate, self.precision("grand_total")) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index b3a143cbce..b866794b89 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe import unittest, copy, time -from frappe.utils import nowdate, add_days, flt, getdate, cint +from frappe.utils import nowdate, flt, getdate, cint from frappe.model.dynamic_links import get_dynamic_link_map from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice @@ -1321,40 +1321,6 @@ class TestSalesInvoice(unittest.TestCase): }) si.insert() return si - - def test_gl_entry_based_on_payment_schedule(self): - si = create_sales_invoice(do_not_save=True, customer="_Test Customer P") - si.append("payment_schedule", { - "due_date": add_days(nowdate(), 15), - "payment_amount": 20, - "invoice_portion": 20.00 - }) - si.append("payment_schedule", { - "due_date": add_days(nowdate(), 45), - "payment_amount": 80, - "invoice_portion": 80.00 - }) - - si.save() - si.submit() - - gl_entries = frappe.db.sql("""select account, debit, credit, due_date - from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s - order by account asc, debit asc""", si.name, as_dict=1) - self.assertTrue(gl_entries) - - expected_gl_entries = sorted([ - [si.debit_to, 20.0, 0.0, add_days(nowdate(), 15)], - [si.debit_to, 80.0, 0.0, add_days(nowdate(), 45)], - ["Sales - _TC", 0.0, 100.0, None] - ]) - - for i, gle in enumerate(sorted(gl_entries, key=lambda gle: gle.account)): - self.assertEquals(expected_gl_entries[i][0], gle.account) - self.assertEquals(expected_gl_entries[i][1], gle.debit) - self.assertEquals(expected_gl_entries[i][2], gle.credit) - self.assertEquals(getdate(expected_gl_entries[i][3]), getdate(gle.due_date)) - def test_company_monthly_sales(self): existing_current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales") diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index d370c496fb..c575d59ae7 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe, erpnext -from frappe.utils import flt, cstr, cint, getdate +from frappe.utils import flt, cstr, cint from frappe import _ from frappe.model.meta import get_field_precision from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget @@ -75,8 +75,7 @@ def check_if_in_list(gle, gl_map): and cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \ and cstr(e.get('against_voucher_type')) == cstr(gle.get('against_voucher_type')) \ and cstr(e.get('cost_center')) == cstr(gle.get('cost_center')) \ - and cstr(e.get('project')) == cstr(gle.get('project')) \ - and getdate(e.get('due_date')) == getdate(gle.get('due_date')): + and cstr(e.get('project')) == cstr(gle.get('project')): return e def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False): diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 300e6a8198..522abe85b4 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -113,7 +113,7 @@ class ReceivablePayableReport(object): row += [self.get_party_name(gle.party_type, gle.party)] # get due date - due_date = gle.due_date or voucher_details.get(gle.voucher_no, {}).get("due_date", "") + due_date = voucher_details.get(gle.voucher_no, {}).get("due_date", "") row += [gle.voucher_type, gle.voucher_no, due_date] @@ -188,8 +188,7 @@ class ReceivablePayableReport(object): reverse_dr_or_cr = "credit" if dr_or_cr=="debit" else "debit" for e in self.get_gl_entries_for(gle.party, gle.party_type, gle.voucher_type, gle.voucher_no): - if getdate(e.posting_date) <= report_date and e.name!=gle.name \ - and (not gle.due_date or getdate(e.due_date) == getdate(gle.due_date)): + if getdate(e.posting_date) <= report_date and e.name!=gle.name: amount = flt(e.get(reverse_dr_or_cr)) - flt(e.get(dr_or_cr)) if e.voucher_no not in return_entries: payment_amount += amount @@ -251,11 +250,11 @@ class ReceivablePayableReport(object): select_fields = "sum(debit) as debit, sum(credit) as credit" self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party, - voucher_type, voucher_no, against_voucher_type, against_voucher, due_date, + voucher_type, voucher_no, against_voucher_type, against_voucher, account_currency, remarks, {0} from `tabGL Entry` where docstatus < 2 and party_type=%s and (party is not null and party != '') {1} - group by voucher_type, voucher_no, against_voucher_type, against_voucher, party, due_date + group by voucher_type, voucher_no, against_voucher_type, against_voucher, party order by posting_date, party""" .format(select_fields, conditions), values, as_dict=True) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 9c42f6435e..bd223b50b2 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -583,9 +583,10 @@ def get_outstanding_invoices(party_type, party, account, condition=None): dr_or_cr = "credit_in_account_currency - debit_in_account_currency" payment_dr_or_cr = "payment_gl_entry.debit_in_account_currency - payment_gl_entry.credit_in_account_currency" + invoice = 'Sales Invoice' if party_type == 'Customer' else 'Purchase Invoice' invoice_list = frappe.db.sql(""" select - voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount, due_date, + voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount, ( select ifnull(sum({payment_dr_or_cr}), 0) from `tabGL Entry` payment_gl_entry @@ -596,7 +597,6 @@ def get_outstanding_invoices(party_type, party, account, condition=None): and payment_gl_entry.party_type = invoice_gl_entry.party_type and payment_gl_entry.party = invoice_gl_entry.party and payment_gl_entry.account = invoice_gl_entry.account - and payment_gl_entry.due_date = invoice_gl_entry.due_date and {payment_dr_or_cr} > 0 ) as payment_amount from @@ -608,10 +608,11 @@ def get_outstanding_invoices(party_type, party, account, condition=None): and ((voucher_type = 'Journal Entry' and (against_voucher = '' or against_voucher is null)) or (voucher_type not in ('Journal Entry', 'Payment Entry'))) - group by voucher_type, voucher_no, due_date + group by voucher_type, voucher_no having (invoice_amount - payment_amount) > 0.005 order by posting_date, name, due_date""".format( dr_or_cr=dr_or_cr, + invoice = invoice, payment_dr_or_cr=payment_dr_or_cr, condition=condition or "" ), { @@ -621,12 +622,8 @@ def get_outstanding_invoices(party_type, party, account, condition=None): }, as_dict=True) for d in invoice_list: - due_date = d.due_date or ( - frappe.db.get_value( - d.voucher_type, d.voucher_no, - "posting_date" if party_type == "Employee" else "due_date" - ) - ) + due_date = frappe.db.get_value(d.voucher_type, d.voucher_no, + "posting_date" if party_type == "Employee" else "due_date") outstanding_invoices.append( frappe._dict({ diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 9a7ec7c832..7966d81a5d 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -485,4 +485,3 @@ erpnext.patches.v10_0.enabled_regional_print_format_based_on_country erpnext.patches.v10_0.update_asset_calculate_depreciation erpnext.patches.v10_0.enabled_regional_print_format_based_on_country erpnext.patches.v10_0.update_asset_calculate_depreciation -erpnext.patches.v10_0.update_due_date_in_gle_and_payment_entries diff --git a/erpnext/patches/v10_0/update_due_date_in_gle_and_payment_entries.py b/erpnext/patches/v10_0/update_due_date_in_gle_and_payment_entries.py deleted file mode 100644 index 268b84314d..0000000000 --- a/erpnext/patches/v10_0/update_due_date_in_gle_and_payment_entries.py +++ /dev/null @@ -1,100 +0,0 @@ -from __future__ import unicode_literals -import frappe -from frappe.utils import update_progress_bar - -def execute(): - frappe.reload_doc("accounts", "doctype", "gl_entry") - frappe.reload_doc("accounts", "doctype", "payment_entry_reference") - frappe.reload_doc("accounts", "doctype", "journal_entry_account") - - print "Updating Due Date in GL Entry, Journal Entry and Payment Entry" - for doctype in ("Sales Invoice", "Purchase Invoice"): - invoice_due_dates = frappe.db.sql("""select name, due_date from `tab{0}` - where docstatus=1 order by name""".format(doctype)) - - # update gle - count = 0 - total_count = len(invoice_due_dates) - batch_size = 1000 - - while(count < total_count): - update_progress_bar("Based on {0}".format(doctype), count, total_count) - sub_set = invoice_due_dates[count:count+batch_size] - invoices = [d[0] for d in sub_set] - - update_gl_entries(doctype, invoices, sub_set) - update_payment_entries(doctype, invoices, sub_set) - - count += batch_size - -def update_gl_entries(doctype, invoices, invoice_due_dates): - when_then = get_when_then_for_gle(doctype, invoice_due_dates) - - frappe.db.sql(""" - UPDATE `tabGL Entry` - SET due_date = CASE - %s - ELSE `due_date` END - WHERE - ( - (voucher_type = %s and voucher_no in (%s)) - or (voucher_type in ('Journal Entry', 'Payment Entry') - and against_voucher in (%s)) - ) - and ifnull(party, '') != '' - and ifnull(due_date, '') = '' - """ % (when_then, '%s', ', '.join(['%s']*len(invoices)), ', '.join(['%s']*len(invoices))), - tuple([doctype] + invoices + invoices)) - -def get_when_then_for_gle(doctype, data): - cond = "" - for d in data: - cond += """ - WHEN ( - (voucher_type = '{voucher_type}' and voucher_no = '{voucher_no}') - or (voucher_type in ('Journal Entry', 'Payment Entry') - and against_voucher = '{voucher_no}') - ) THEN '{date}' - """.format(voucher_type=doctype, voucher_no=frappe.db.escape(d[0]), date=d[1]) - - return cond - -def update_payment_entries(ref_doctype, invoices, invoice_due_dates): - for d in ( - ("Payment Entry Reference", "reference_doctype", "due_date"), - ("Journal Entry Account", "reference_type", "reference_due_date")): - - when_then = get_when_then_for_payment_entries(ref_doctype, d[1], invoice_due_dates) - - frappe.db.sql(""" - UPDATE `tab{doctype}` - SET {due_date_field} = CASE - {when_then} - ELSE `{due_date_field}` END - WHERE - {ref_doctype_fieldname} = '{ref_doctype}' - and reference_name in ({reference_names}) - and ifnull({due_date_field}, '') = '' - """.format( - doctype = d[0], - due_date_field = d[2], - when_then = when_then, - ref_doctype_fieldname = d[1], - ref_doctype = ref_doctype, - reference_names = ', '.join(['%s']*len(invoices)) - ), tuple(invoices)) - -def get_when_then_for_payment_entries(ref_doctype, ref_doctype_fieldname, data): - cond = "" - for d in data: - cond += """ - WHEN {ref_doctype_fieldname} = '{ref_doctype}' - and reference_name = '{voucher_no}' - THEN '{date}' - """.format( - ref_doctype_fieldname=ref_doctype_fieldname, - ref_doctype=ref_doctype, - voucher_no=frappe.db.escape(d[0]), - date=d[1]) - - return cond \ No newline at end of file