From 7afaeb082029f489d0e04f07ed92bf5e7cce5d40 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 1 Oct 2015 18:55:25 +0530 Subject: [PATCH 1/6] [fix] the case when party account currency is missing --- erpnext/controllers/accounts_controller.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index a92d070780..daf3377aa7 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -428,7 +428,10 @@ class AccountsController(TransactionBase): if party_type and party: party_account_currency = get_party_account_currency(party_type, party, self.company) - if party_account_currency != self.company_currency and self.currency != party_account_currency: + if (party_account_currency + and party_account_currency != self.company_currency + and self.currency != party_account_currency): + frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}") .format(party_type, party, party_account_currency), InvalidCurrency) From d9ab725be45c4d29408434c75e8c3743c3cf8e29 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 1 Oct 2015 19:15:06 +0530 Subject: [PATCH 2/6] [fix] In Payment Tool, Set Payment Amount = Outstanding Amount if checked --- .../doctype/payment_tool/payment_tool.js | 5 +++- .../doctype/payment_tool/payment_tool.json | 24 ++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.js b/erpnext/accounts/doctype/payment_tool/payment_tool.js index 0b4fb2dade..ec15b47eb1 100644 --- a/erpnext/accounts/doctype/payment_tool/payment_tool.js +++ b/erpnext/accounts/doctype/payment_tool/payment_tool.js @@ -141,7 +141,10 @@ frappe.ui.form.on("Payment Tool", "get_outstanding_vouchers", function(frm) { c.against_voucher_no = d.voucher_no; c.total_amount = d.invoice_amount; c.outstanding_amount = d.outstanding_amount; - c.payment_amount = d.outstanding_amount; + + if (frm.doc.set_payment_amount) { + c.payment_amount = d.outstanding_amount; + } }); } refresh_field("vouchers"); diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.json b/erpnext/accounts/doctype/payment_tool/payment_tool.json index 55e70481e2..a99054fba1 100644 --- a/erpnext/accounts/doctype/payment_tool/payment_tool.json +++ b/erpnext/accounts/doctype/payment_tool/payment_tool.json @@ -185,6 +185,28 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "set_payment_amount", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Set Payment Amount = Outstanding Amount", + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -474,7 +496,7 @@ "is_submittable": 0, "issingle": 1, "istable": 0, - "modified": "2015-08-31 18:58:21.813054", + "modified": "2015-10-01 09:43:24.199025", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Tool", From 83c0899c83e4946342f5c6fd354941918ad1bbca Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 30 Sep 2015 16:55:26 +0530 Subject: [PATCH 3/6] [fix] [minor] default ranges for demo --- .../accounts_receivable/accounts_receivable.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 7cbd4ddc83..76f51ee4c2 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -40,6 +40,13 @@ class ReceivablePayableReport(object): columns += [_("Age (Days)") + "::80"] + if not "range1" in self.filters: + self.filters["range1"] = "30" + if not "range2" in self.filters: + self.filters["range2"] = "60" + if not "range3" in self.filters: + self.filters["range3"] = "90" + for label in ("0-{range1}".format(**self.filters), "{range1}-{range2}".format(**self.filters), "{range2}-{range3}".format(**self.filters), @@ -75,9 +82,9 @@ class ReceivablePayableReport(object): voucher_details = self.get_voucher_details(args.get("party_type")) future_vouchers = self.get_entries_after(self.filters.report_date, args.get("party_type")) - + company_currency = frappe.db.get_value("Company", self.filters.get("company"), "default_currency") - + data = [] for gle in self.get_entries_till(self.filters.report_date, args.get("party_type")): if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers): @@ -117,7 +124,7 @@ class ReceivablePayableReport(object): row += [self.get_territory(gle.party)] if args.get("party_type") == "Supplier": row += [self.get_supplier_type(gle.party)] - + if self.filters.get(scrub(args.get("party_type"))): row.append(gle.account_currency) else: @@ -209,7 +216,7 @@ class ReceivablePayableReport(object): self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party, voucher_type, voucher_no, against_voucher_type, against_voucher, account_currency, remarks, {0} from `tabGL Entry` - where docstatus < 2 and party_type=%s and ifnull(party, '') != '' {1} + where docstatus < 2 and party_type=%s and ifnull(party, '') != '' {1} order by posting_date, party""" .format(select_fields, conditions), values, as_dict=True) From db48b7d7647e011241761369b4f0829b3d9cb045 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 2 Oct 2015 12:05:55 +0530 Subject: [PATCH 4/6] [fix] Payment Reconciliation in multi-currency --- .../payment_reconciliation.js | 39 +++++++++++-------- .../payment_reconciliation.py | 27 ++++++------- erpnext/accounts/utils.py | 15 ++++++- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js index ab6db9d381..eb84cb0c85 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js @@ -74,21 +74,7 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext doc: me.frm.doc, method: 'get_unreconciled_entries', callback: function(r, rt) { - var invoices = []; - - $.each(me.frm.doc.invoices || [], function(i, row) { - if (row.invoice_number && !inList(invoices, row.invoice_number)) - invoices.push(row.invoice_type + " | " + row.invoice_number); - }); - - frappe.meta.get_docfield("Payment Reconciliation Payment", "invoice_number", - me.frm.doc.name).options = invoices.join("\n"); - - $.each(me.frm.doc.payments || [], function(i, p) { - if(!inList(invoices, cstr(p.invoice_number))) p.invoice_number = null; - }); - - refresh_field("payments"); + me.set_invoice_options(); } }); @@ -98,8 +84,29 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext var me = this; return this.frm.call({ doc: me.frm.doc, - method: 'reconcile' + method: 'reconcile', + callback: function(r, rt) { + me.set_invoice_options(); + } }); + }, + + set_invoice_options: function() { + var invoices = []; + + $.each(me.frm.doc.invoices || [], function(i, row) { + if (row.invoice_number && !inList(invoices, row.invoice_number)) + invoices.push(row.invoice_type + " | " + row.invoice_number); + }); + + frappe.meta.get_docfield("Payment Reconciliation Payment", "invoice_number", + me.frm.doc.name).options = invoices.join("\n"); + + $.each(me.frm.doc.payments || [], function(i, p) { + if(!inList(invoices, cstr(p.invoice_number))) p.invoice_number = null; + }); + + refresh_field("payments"); } }); diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index 81bfec5b0f..13b8f02bbb 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -3,11 +3,8 @@ from __future__ import unicode_literals import frappe - from frappe.utils import flt - from frappe import msgprint, _ - from frappe.model.document import Document class PaymentReconciliation(Document): @@ -17,7 +14,8 @@ class PaymentReconciliation(Document): def get_jv_entries(self): self.check_mandatory_to_fetch() - dr_or_cr = "credit" if self.party_type == "Customer" else "debit" + dr_or_cr = "credit_in_account_currency" if self.party_type == "Customer" \ + else "debit_in_account_currency" cond = self.check_condition(dr_or_cr) @@ -68,7 +66,7 @@ class PaymentReconciliation(Document): def get_invoice_entries(self): #Fetch JVs, Sales and Purchase Invoices for 'invoices' to reconcile against non_reconciled_invoices = [] - dr_or_cr = "debit" if self.party_type == "Customer" else "credit" + dr_or_cr = "debit_in_account_currency" if self.party_type == "Customer" else "credit_in_account_currency" cond = self.check_condition(dr_or_cr) invoice_list = frappe.db.sql(""" @@ -106,13 +104,15 @@ class PaymentReconciliation(Document): and account = %(account)s and {0} > 0 and against_voucher_type = %(against_voucher_type)s and ifnull(against_voucher, '') = %(against_voucher)s - """.format("credit" if self.party_type == "Customer" else "debit"), { - "party_type": self.party_type, - "party": self.party, - "account": self.receivable_payable_account, - "against_voucher_type": d.voucher_type, - "against_voucher": d.voucher_no - }) + """.format("credit_in_account_currency" if self.party_type == "Customer" + else "debit_in_account_currency"), { + "party_type": self.party_type, + "party": self.party, + "account": self.receivable_payable_account, + "against_voucher_type": d.voucher_type, + "against_voucher": d.voucher_no + } + ) payment_amount = payment_amount[0][0] if payment_amount else 0 @@ -147,7 +147,8 @@ class PaymentReconciliation(Document): self.get_invoice_entries() self.validate_invoice() - dr_or_cr = "credit" if self.party_type == "Customer" else "debit" + dr_or_cr = "credit_in_account_currency" if self.party_type == "Customer" \ + else "debit_in_account_currency" lst = [] for e in self.get('payments'): if e.invoice_number and e.allocated_amount: diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 2a77fa1465..199769416e 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -198,6 +198,8 @@ def update_against_doc(d, jv_obj): """ jv_detail = jv_obj.get("accounts", {"name": d["voucher_detail_no"]})[0] jv_detail.set(d["dr_or_cr"], d["allocated_amt"]) + jv_detail.set('debit' if d['dr_or_cr']=='debit_in_account_currency' else 'credit', + d["allocated_amt"]*flt(jv_detail.exchange_rate)) original_reference_type = jv_detail.reference_type original_reference_name = jv_detail.reference_name @@ -210,6 +212,9 @@ def update_against_doc(d, jv_obj): select cost_center, balance, against_account, is_advance, account_type, exchange_rate from `tabJournal Entry Account` where name = %s """, d['voucher_detail_no'], as_dict=True) + + amount_in_account_currency = flt(d['unadjusted_amt']) - flt(d['allocated_amt']) + amount_in_company_currency = amount_in_account_currency * flt(jvd[0]['exchange_rate']) # new entry with balance amount ch = jv_obj.append("accounts") @@ -220,8 +225,14 @@ def update_against_doc(d, jv_obj): ch.party = d["party"] ch.cost_center = cstr(jvd[0]["cost_center"]) ch.balance = flt(jvd[0]["balance"]) - ch.set(d['dr_or_cr'], flt(d['unadjusted_amt']) - flt(d['allocated_amt'])) - ch.set(d['dr_or_cr']== 'debit' and 'credit' or 'debit', 0) + + ch.set(d['dr_or_cr'], amount_in_account_currency) + ch.set('debit' if d['dr_or_cr']=='debit_in_account_currency' else 'credit', amount_in_company_currency) + + ch.set('credit_in_account_currency' if d['dr_or_cr']== 'debit_in_account_currency' + else 'debit_in_account_currency', 0) + ch.set('credit' if d['dr_or_cr']== 'debit_in_account_currency' else 'debit', 0) + ch.against_account = cstr(jvd[0]["against_account"]) ch.reference_type = original_reference_type ch.reference_name = original_reference_name From 1a1f790150ebe6647d6311ab41a11904a35a8a6b Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 2 Oct 2015 12:34:18 +0530 Subject: [PATCH 5/6] [fix] test case --- .../doctype/fiscal_year/test_records.json | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/erpnext/accounts/doctype/fiscal_year/test_records.json b/erpnext/accounts/doctype/fiscal_year/test_records.json index 09fb90e9e3..abaab9797c 100644 --- a/erpnext/accounts/doctype/fiscal_year/test_records.json +++ b/erpnext/accounts/doctype/fiscal_year/test_records.json @@ -1,32 +1,38 @@ [ { - "doctype": "Fiscal Year", - "year": "_Test Fiscal Year 2012", - "year_end_date": "2012-12-31", + "doctype": "Fiscal Year", + "year": "_Test Fiscal Year 2012", + "year_end_date": "2012-12-31", "year_start_date": "2012-01-01" - }, + }, { - "doctype": "Fiscal Year", - "year": "_Test Fiscal Year 2013", - "year_end_date": "2013-12-31", + "doctype": "Fiscal Year", + "year": "_Test Fiscal Year 2013", + "year_end_date": "2013-12-31", "year_start_date": "2013-01-01" - }, + }, { - "doctype": "Fiscal Year", - "year": "_Test Fiscal Year 2014", - "year_end_date": "2014-12-31", + "doctype": "Fiscal Year", + "year": "_Test Fiscal Year 2014", + "year_end_date": "2014-12-31", "year_start_date": "2014-01-01" - }, + }, { - "doctype": "Fiscal Year", - "year": "_Test Fiscal Year 2015", - "year_end_date": "2015-12-31", + "doctype": "Fiscal Year", + "year": "_Test Fiscal Year 2015", + "year_end_date": "2015-12-31", "year_start_date": "2015-01-01" - }, + }, { - "doctype": "Fiscal Year", - "year": "_Test Fiscal Year 2016", - "year_end_date": "2016-12-31", + "doctype": "Fiscal Year", + "year": "_Test Fiscal Year 2016", + "year_end_date": "2016-12-31", "year_start_date": "2016-01-01" + }, + { + "doctype": "Fiscal Year", + "year": "_Test Fiscal Year 2017", + "year_end_date": "2017-12-31", + "year_start_date": "2017-01-01" } -] \ No newline at end of file +] From 71f23acc2b043df507405f02a4a877f3c8778219 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 2 Oct 2015 13:13:27 +0600 Subject: [PATCH 6/6] bumped to version 6.4.3 --- erpnext/__version__.py | 2 +- erpnext/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/__version__.py b/erpnext/__version__.py index bc305ffd2c..ac1c3f2790 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1,2 +1,2 @@ from __future__ import unicode_literals -__version__ = '6.4.2' +__version__ = '6.4.3' diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 8c2797f141..4855fc6514 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -29,7 +29,7 @@ blogs. """ app_icon = "icon-th" app_color = "#e74c3c" -app_version = "6.4.2" +app_version = "6.4.3" github_link = "https://github.com/frappe/erpnext" error_report_email = "support@erpnext.com" diff --git a/setup.py b/setup.py index 355a404472..339d864d98 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = "6.4.2" +version = "6.4.3" with open("requirements.txt", "r") as f: install_requires = f.readlines()