From 91a9ee51797adf3717be4419c3e511c7cca6f931 Mon Sep 17 00:00:00 2001 From: Shreya Shah Date: Sat, 28 Jul 2018 10:26:11 +0530 Subject: [PATCH 1/4] Merge accounts functionality (#14993) * Add dialog to merge accounts * Add conditions and merge functionality * Fix travis * Add test case * Add more test scenarios --- erpnext/accounts/doctype/account/account.js | 44 +++++++++++++ erpnext/accounts/doctype/account/account.py | 20 ++++++ .../accounts/doctype/account/test_account.py | 64 ++++++++++++++++++- 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/account/account.js b/erpnext/accounts/doctype/account/account.js index 79e11e3539..079454ef55 100644 --- a/erpnext/accounts/doctype/account/account.js +++ b/erpnext/accounts/doctype/account/account.js @@ -53,6 +53,12 @@ frappe.ui.form.on('Account', { frm.trigger("update_account_number"); }); } + + if(!frm.doc.__islocal) { + frm.add_custom_button(__('Merge Account'), function () { + frm.trigger("merge_account"); + }); + } }, account_type: function (frm) { if (frm.doc.is_group == 0) { @@ -98,6 +104,44 @@ frappe.ui.form.on('Account', { } }, + merge_account: function(frm) { + var d = new frappe.ui.Dialog({ + title: __('Merge with Existing Account'), + fields: [ + { + "label" : "Name", + "fieldname": "name", + "fieldtype": "Data", + "reqd": 1, + "default": frm.doc.name + } + ], + primary_action: function() { + var data = d.get_values(); + frappe.call({ + method: "erpnext.accounts.doctype.account.account.merge_account", + args: { + old: frm.doc.name, + new: data.name, + is_group: frm.doc.is_group, + root_type: frm.doc.root_type, + company: frm.doc.company + }, + callback: function(r) { + if(!r.exc) { + if(r.message) { + frappe.set_route("Form", "Account", r.message); + } + d.hide(); + } + } + }); + }, + primary_action_label: __('Merge') + }); + d.show(); + }, + update_account_number: function(frm) { var d = new frappe.ui.Dialog({ title: __('Update Account Number / Name'), diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index 35974e527e..cc33c547ea 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -217,3 +217,23 @@ def update_account_number(name, account_name, account_number=None): if name != new_name: frappe.rename_doc("Account", name, new_name, ignore_permissions=1) return new_name + +@frappe.whitelist() +def merge_account(old, new, is_group, root_type, company): + # Validate properties before merging + if not frappe.db.exists("Account", new): + throw(_("Account {0} does not exist").format(new)) + + val = list(frappe.db.get_value("Account", new, + ["is_group", "root_type", "company"])) + + if val != [cint(is_group), root_type, company]: + throw(_("""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company""")) + + if is_group and frappe.db.get_value("Account", new, "parent_account") == old: + frappe.db.set_value("Account", new, "parent_account", + frappe.db.get_value("Account", old, "parent_account")) + + frappe.rename_doc("Account", old, new, merge=1, ignore_permissions=1) + + return new diff --git a/erpnext/accounts/doctype/account/test_account.py b/erpnext/accounts/doctype/account/test_account.py index 2d9931b8c4..9bf29c13fc 100644 --- a/erpnext/accounts/doctype/account/test_account.py +++ b/erpnext/accounts/doctype/account/test_account.py @@ -6,6 +6,7 @@ import unittest import frappe from erpnext.stock import get_warehouse_account, get_company_default_inventory_account from erpnext.accounts.doctype.account.account import update_account_number +from erpnext.accounts.doctype.account.account import merge_account class TestAccount(unittest.TestCase): def test_rename_account(self): @@ -25,7 +26,7 @@ class TestAccount(unittest.TestCase): new_account_number = "1211-11-4 - 6 - " new_account_name = "Debtors 1 - Test - " - update_account_number("1210 - Debtors - _TC", new_account_number, new_account_name) + update_account_number("1210 - Debtors - _TC", new_account_name, new_account_number) new_acc = frappe.db.get_value("Account", "1211-11-4 - 6 - - Debtors 1 - Test - - _TC", ["account_name", "account_number"], as_dict=1) @@ -35,6 +36,67 @@ class TestAccount(unittest.TestCase): frappe.delete_doc("Account", "1211-11-4 - 6 - Debtors 1 - Test - - _TC") + def test_merge_account(self): + if not frappe.db.exists("Account", "Current Assets - _TC"): + acc = frappe.new_doc("Account") + acc.account_name = "Current Assets" + acc.is_group = 1 + acc.parent_account = "Application of Funds (Assets) - _TC" + acc.company = "_Test Company" + acc.insert() + if not frappe.db.exists("Account", "Securities and Deposits - _TC"): + acc = frappe.new_doc("Account") + acc.account_name = "Securities and Deposits" + acc.parent_account = "Current Assets - _TC" + acc.is_group = 1 + acc.company = "_Test Company" + acc.insert() + if not frappe.db.exists("Account", "Earnest Money - _TC"): + acc = frappe.new_doc("Account") + acc.account_name = "Earnest Money" + acc.parent_account = "Securities and Deposits - _TC" + acc.company = "_Test Company" + acc.insert() + if not frappe.db.exists("Account", "Cash In Hand - _TC"): + acc = frappe.new_doc("Account") + acc.account_name = "Cash In Hand" + acc.is_group = 1 + acc.parent_account = "Current Assets - _TC" + acc.company = "_Test Company" + acc.insert() + if not frappe.db.exists("Account", "Accumulated Depreciation - _TC"): + acc = frappe.new_doc("Account") + acc.account_name = "Accumulated Depreciation" + acc.parent_account = "Fixed Assets - _TC" + acc.company = "_Test Company" + acc.insert() + + doc = frappe.get_doc("Account", "Securities and Deposits - _TC") + parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account") + + self.assertEqual(parent, "Securities and Deposits - _TC") + + merge_account("Securities and Deposits - _TC", "Cash In Hand - _TC", doc.is_group, doc.root_type, doc.company) + parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account") + + # Parent account of the child account changes after merging + self.assertEqual(parent, "Cash In Hand - _TC") + + # Old account doesn't exist after merging + self.assertFalse(frappe.db.exists("Account", "Securities and Deposits - _TC")) + + doc = frappe.get_doc("Account", "Current Assets - _TC") + + # Raise error as is_group property doesn't match + self.assertRaises(frappe.ValidationError, merge_account, "Current Assets - _TC",\ + "Accumulated Depreciation - _TC", doc.is_group, doc.root_type, doc.company) + + doc = frappe.get_doc("Account", "Capital Stock - _TC") + + # Raise error as root_type property doesn't match + self.assertRaises(frappe.ValidationError, merge_account, "Capital Stock - _TC",\ + "Softwares - _TC", doc.is_group, doc.root_type, doc.company) + def _make_test_records(verbose): from frappe.test_runner import make_test_objects From 91d2ace9bbbe31a3fbe0622a970e93857a0c27d5 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Mon, 30 Jul 2018 10:38:51 +0530 Subject: [PATCH 2/4] Account no + account name in trial balance and financial statements reports (#15038) --- erpnext/accounts/report/financial_statements.py | 7 ++++--- erpnext/accounts/report/trial_balance/trial_balance.py | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index b0c49dfbd8..1be3d74185 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -185,14 +185,15 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency): has_value = False total = 0 row = frappe._dict({ - "account_name": _(d.account_name), "account": _(d.name), "parent_account": _(d.parent_account), "indent": flt(d.indent), "year_start_date": year_start_date, "year_end_date": year_end_date, "currency": company_currency, - "opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1) + "opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1), + "account_name": ('{} - {}'.format(_(d.account_number), _(d.account_name)) + if d.account_number else _(d.account_name)) }) for period in period_list: if d.get(period.key) and balance_must_be=="Credit": @@ -253,7 +254,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency out.append({}) def get_accounts(company, root_type): - return frappe.db.sql("""select name, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount` + return frappe.db.sql("""select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount` where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True) def filter_accounts(accounts, depth=10): diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py index 93ffe0279f..513ae148a1 100644 --- a/erpnext/accounts/report/trial_balance/trial_balance.py +++ b/erpnext/accounts/report/trial_balance/trial_balance.py @@ -51,7 +51,7 @@ def validate_filters(filters): filters.to_date = filters.year_end_date def get_data(filters): - accounts = frappe.db.sql("""select name, parent_account, account_name, root_type, report_type, lft, rgt + accounts = frappe.db.sql("""select name, account_number, parent_account, account_name, root_type, report_type, lft, rgt from `tabAccount` where company=%s order by lft""", filters.company, as_dict=True) company_currency = erpnext.get_company_currency(filters.company) @@ -179,13 +179,14 @@ def prepare_data(accounts, filters, total_row, parent_children_map, company_curr for d in accounts: has_value = False row = { - "account_name": d.account_name, "account": d.name, "parent_account": d.parent_account, "indent": d.indent, "from_date": filters.from_date, "to_date": filters.to_date, - "currency": company_currency + "currency": company_currency, + "account_name": ('{} - {}'.format(d.account_number, d.account_name) + if d.account_number else d.account_name) } prepare_opening_and_closing(d) From 086da451caaf89b0c6d9bdf8fbee822bf19f6cfc Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Mon, 30 Jul 2018 19:11:14 +0530 Subject: [PATCH 3/4] Removed academic term from validation to check duplicate program enrollement (#15046) --- .../education/doctype/program_enrollment/program_enrollment.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.py b/erpnext/education/doctype/program_enrollment/program_enrollment.py index 455ad9cfd7..320a58a924 100644 --- a/erpnext/education/doctype/program_enrollment/program_enrollment.py +++ b/erpnext/education/doctype/program_enrollment/program_enrollment.py @@ -26,7 +26,6 @@ class ProgramEnrollment(Document): "student": self.student, "program": self.program, "academic_year": self.academic_year, - "academic_term": self.academic_term, "docstatus": ("<", 2), "name": ("!=", self.name) }) From e9afbfde7666d392393a314c23d96abc2438d93c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 31 Jul 2018 12:48:22 +0600 Subject: [PATCH 4/4] bumped to version 10.1.45 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 3d5ceadd1b..862ac94ba9 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.1.44' +__version__ = '10.1.45' def get_default_company(user=None): '''Get default company for user'''