diff --git a/erpnext/accounts/doctype/account/account.js b/erpnext/accounts/doctype/account/account.js
index 7a1d735948..320e1cab7c 100644
--- a/erpnext/accounts/doctype/account/account.js
+++ b/erpnext/accounts/doctype/account/account.js
@@ -43,12 +43,12 @@ frappe.ui.form.on('Account', {
frm.trigger('add_toolbar_buttons');
}
if (frm.has_perm('write')) {
- frm.add_custom_button(__('Update Account Name / Number'), function () {
- frm.trigger("update_account_number");
- });
frm.add_custom_button(__('Merge Account'), function () {
frm.trigger("merge_account");
- });
+ }, __('Actions'));
+ frm.add_custom_button(__('Update Account Name / Number'), function () {
+ frm.trigger("update_account_number");
+ }, __('Actions'));
}
}
},
@@ -59,11 +59,12 @@ frappe.ui.form.on('Account', {
}
},
add_toolbar_buttons: function(frm) {
- frm.add_custom_button(__('Chart of Accounts'),
- function () { frappe.set_route("Tree", "Account"); });
+ frm.add_custom_button(__('Chart of Accounts'), () => {
+ frappe.set_route("Tree", "Account");
+ }, __('View'));
if (frm.doc.is_group == 1) {
- frm.add_custom_button(__('Group to Non-Group'), function () {
+ frm.add_custom_button(__('Convert to Non-Group'), function () {
return frappe.call({
doc: frm.doc,
method: 'convert_group_to_ledger',
@@ -71,10 +72,11 @@ frappe.ui.form.on('Account', {
frm.refresh();
}
});
- });
+ }, __('Actions'));
+
} else if (cint(frm.doc.is_group) == 0
&& frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {
- frm.add_custom_button(__('Ledger'), function () {
+ frm.add_custom_button(__('General Ledger'), function () {
frappe.route_options = {
"account": frm.doc.name,
"from_date": frappe.sys_defaults.year_start_date,
@@ -82,9 +84,9 @@ frappe.ui.form.on('Account', {
"company": frm.doc.company
};
frappe.set_route("query-report", "General Ledger");
- });
+ }, __('View'));
- frm.add_custom_button(__('Non-Group to Group'), function () {
+ frm.add_custom_button(__('Convert to Group'), function () {
return frappe.call({
doc: frm.doc,
method: 'convert_ledger_to_group',
@@ -92,7 +94,7 @@ frappe.ui.form.on('Account', {
frm.refresh();
}
});
- });
+ }, __('Actions'));
}
},
diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json
index bc9241802d..daee8f8c1a 100644
--- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json
+++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json
@@ -75,7 +75,7 @@
],
"hide_toolbar": 1,
"issingle": 1,
- "modified": "2019-07-25 14:57:33.187689",
+ "modified": "2022-01-04 15:25:06.053187",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Opening Invoice Creation Tool",
diff --git a/erpnext/regional/doctype/uae_vat_settings/uae_vat_settings.js b/erpnext/regional/doctype/uae_vat_settings/uae_vat_settings.js
index 07a93010b5..66531412fa 100644
--- a/erpnext/regional/doctype/uae_vat_settings/uae_vat_settings.js
+++ b/erpnext/regional/doctype/uae_vat_settings/uae_vat_settings.js
@@ -2,7 +2,13 @@
// For license information, please see license.txt
frappe.ui.form.on('UAE VAT Settings', {
- // refresh: function(frm) {
-
- // }
+ onload: function(frm) {
+ frm.set_query('account', 'uae_vat_accounts', function() {
+ return {
+ filters: {
+ 'company': frm.doc.company
+ }
+ };
+ });
+ }
});
diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js
index e61a634aae..ce74f6d0a5 100644
--- a/erpnext/selling/page/point_of_sale/pos_controller.js
+++ b/erpnext/selling/page/point_of_sale/pos_controller.js
@@ -643,7 +643,7 @@ erpnext.PointOfSale.Controller = class {
message: __('Item Code: {0} is not available under warehouse {1}.', [bold_item_code, bold_warehouse])
})
} else if (available_qty < qty_needed) {
- frappe.show_alert({
+ frappe.throw({
message: __('Stock quantity not enough for Item Code: {0} under warehouse {1}. Available quantity {2}.', [bold_item_code, bold_warehouse, bold_available_qty]),
indicator: 'orange'
});
diff --git a/erpnext/selling/page/point_of_sale/pos_item_selector.js b/erpnext/selling/page/point_of_sale/pos_item_selector.js
index 496385248c..a30bcd7cf6 100644
--- a/erpnext/selling/page/point_of_sale/pos_item_selector.js
+++ b/erpnext/selling/page/point_of_sale/pos_item_selector.js
@@ -113,7 +113,7 @@ erpnext.PointOfSale.ItemSelector = class {
`
${get_item_image_html()}
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 91f60fbd4e..45e8dccc31 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -79,14 +79,11 @@ frappe.ui.form.on("Company", {
},
refresh: function(frm) {
- if(!frm.doc.__islocal) {
- frm.doc.abbr && frm.set_df_property("abbr", "read_only", 1);
- frm.set_df_property("parent_company", "read_only", 1);
- disbale_coa_fields(frm);
- }
+ frm.toggle_display('address_html', !frm.is_new());
- frm.toggle_display('address_html', !frm.doc.__islocal);
- if(!frm.doc.__islocal) {
+ if (!frm.is_new()) {
+ frm.doc.abbr && frm.set_df_property("abbr", "read_only", 1);
+ disbale_coa_fields(frm);
frappe.contacts.render_address_and_contact(frm);
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Company'}
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index e739739458..0a02bcd6cd 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -47,6 +47,7 @@ class Company(NestedSet):
self.validate_perpetual_inventory()
self.validate_perpetual_inventory_for_non_stock_items()
self.check_country_change()
+ self.check_parent_changed()
self.set_chart_of_accounts()
self.validate_parent_company()
@@ -130,6 +131,10 @@ class Company(NestedSet):
self.name in frappe.local.enable_perpetual_inventory:
frappe.local.enable_perpetual_inventory[self.name] = self.enable_perpetual_inventory
+ if frappe.flags.parent_company_changed:
+ from frappe.utils.nestedset import rebuild_tree
+ rebuild_tree("Company", "parent_company")
+
frappe.clear_cache()
def create_default_warehouses(self):
@@ -191,7 +196,7 @@ class Company(NestedSet):
def check_country_change(self):
frappe.flags.country_change = False
- if not self.get('__islocal') and \
+ if not self.is_new() and \
self.country != frappe.get_cached_value('Company', self.name, 'country'):
frappe.flags.country_change = True
@@ -396,6 +401,13 @@ class Company(NestedSet):
if not frappe.db.get_value('GL Entry', {'company': self.name}):
frappe.db.sql("delete from `tabProcess Deferred Accounting` where company=%s", self.name)
+ def check_parent_changed(self):
+ frappe.flags.parent_company_changed = False
+
+ if not self.is_new() and \
+ self.parent_company != frappe.db.get_value("Company", self.name, "parent_company"):
+ frappe.flags.parent_company_changed = True
+
def get_name_with_abbr(name, company):
company_abbr = frappe.get_cached_value('Company', company, "abbr")
parts = name.split(" - ")
diff --git a/erpnext/setup/doctype/company/test_company.py b/erpnext/setup/doctype/company/test_company.py
index 4ee9492738..e175c5435a 100644
--- a/erpnext/setup/doctype/company/test_company.py
+++ b/erpnext/setup/doctype/company/test_company.py
@@ -93,6 +93,61 @@ class TestCompany(unittest.TestCase):
frappe.db.sql(""" delete from `tabMode of Payment Account`
where company =%s """, (company))
+ def test_basic_tree(self, records=None):
+ min_lft = 1
+ max_rgt = frappe.db.sql("select max(rgt) from `tabCompany`")[0][0]
+
+ if not records:
+ records = test_records[2:]
+
+ for company in records:
+ lft, rgt, parent_company = frappe.db.get_value("Company", company["company_name"],
+ ["lft", "rgt", "parent_company"])
+
+ if parent_company:
+ parent_lft, parent_rgt = frappe.db.get_value("Company", parent_company,
+ ["lft", "rgt"])
+ else:
+ # root
+ parent_lft = min_lft - 1
+ parent_rgt = max_rgt + 1
+
+ self.assertTrue(lft)
+ self.assertTrue(rgt)
+ self.assertTrue(lft < rgt)
+ self.assertTrue(parent_lft < parent_rgt)
+ self.assertTrue(lft > parent_lft)
+ self.assertTrue(rgt < parent_rgt)
+ self.assertTrue(lft >= min_lft)
+ self.assertTrue(rgt <= max_rgt)
+
+ def get_no_of_children(self, company):
+ def get_no_of_children(companies, no_of_children):
+ children = []
+ for company in companies:
+ children += frappe.db.sql_list("""select name from `tabCompany`
+ where ifnull(parent_company, '')=%s""", company or '')
+
+ if len(children):
+ return get_no_of_children(children, no_of_children + len(children))
+ else:
+ return no_of_children
+
+ return get_no_of_children([company], 0)
+
+ def test_change_parent_company(self):
+ child_company = frappe.get_doc("Company", "_Test Company 5")
+
+ # changing parent of company
+ child_company.parent_company = "_Test Company 3"
+ child_company.save()
+ self.test_basic_tree()
+
+ # move it back
+ child_company.parent_company = "_Test Company 4"
+ child_company.save()
+ self.test_basic_tree()
+
def create_company_communication(doctype, docname):
comm = frappe.get_doc({
"doctype": "Communication",