Merge branch 'version-13' into develop
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index a988d72..6775398 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
 from erpnext.hooks import regional_overrides
 from frappe.utils import getdate
 
-__version__ = '13.2.0'
+__version__ = '13.2.1'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 0606823..1be2fbf 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -13,7 +13,7 @@
 class Account(NestedSet):
 	nsm_parent_field = 'parent_account'
 	def on_update(self):
-		if frappe.local.flags.ignore_on_update:
+		if frappe.local.flags.ignore_update_nsm:
 			return
 		else:
 			super(Account, self).on_update()
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
index 0e3b24c..927adc7 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
@@ -57,10 +57,10 @@
 
 		# Rebuild NestedSet HSM tree for Account Doctype
 		# after all accounts are already inserted.
-		frappe.local.flags.ignore_on_update = True
+		frappe.local.flags.ignore_update_nsm = True
 		_import_accounts(chart, None, None, root_account=True)
 		rebuild_tree("Account", "parent_account")
-		frappe.local.flags.ignore_on_update = False
+		frappe.local.flags.ignore_update_nsm = False
 
 def add_suffix_if_duplicate(account_name, account_number, accounts):
 	if account_number:
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
index 5593466..4d33880 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
@@ -30,5 +30,5 @@
 	def enable_payment_schedule_in_print(self):
 		show_in_print = cint(self.show_payment_schedule_in_print)
 		for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"):
-			make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check")
-			make_property_setter(doctype, "payment_schedule", "print_hide",  0 if show_in_print else 1, "Check")
+			make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check", validate_fields_for_doctype=False)
+			make_property_setter(doctype, "payment_schedule", "print_hide",  0 if show_in_print else 1, "Check", validate_fields_for_doctype=False)
diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js
index 9ea616f..aa0c53e 100644
--- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js
+++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.js
@@ -22,7 +22,43 @@
 		});
 		
 		if (frm.doc.docstatus === 0 && !frm.doc.amended_from) frm.set_value("period_end_date", frappe.datetime.now_datetime());
-		if (frm.doc.docstatus === 1) set_html_data(frm);
+		
+		frappe.realtime.on('closing_process_complete', async function(data) {
+			await frm.reload_doc();
+			if (frm.doc.status == 'Failed' && frm.doc.error_message && data.user == frappe.session.user) {
+				frappe.msgprint({
+					title: __('POS Closing Failed'),
+					message: frm.doc.error_message,
+					indicator: 'orange',
+					clear: true
+				});
+			}
+		});
+
+		set_html_data(frm);
+	},
+
+	refresh: function(frm) {
+		if (frm.doc.docstatus == 1 && frm.doc.status == 'Failed') {
+			const issue = '<a id="jump_to_error" style="text-decoration: underline;">issue</a>';
+			frm.dashboard.set_headline(
+				__('POS Closing failed while running in a background process. You can resolve the {0} and retry the process again.', [issue]));
+			
+			$('#jump_to_error').on('click', (e) => {
+				e.preventDefault();
+				frappe.utils.scroll_to(
+					cur_frm.get_field("error_message").$wrapper,
+					true,
+					30
+				);
+			});
+
+			frm.add_custom_button(__('Retry'), function () {
+				frm.call('retry', {}, () => {
+					frm.reload_doc();
+				});
+			});
+		}
 	},
 
 	pos_opening_entry(frm) {
@@ -61,44 +97,24 @@
 				refresh_fields(frm);
 				set_html_data(frm);
 			}
-		})
+		});
+	},
+
+	before_save: function(frm) {
+		for (let row of frm.doc.pos_transactions) {
+			frappe.db.get_doc("POS Invoice", row.pos_invoice).then(doc => {
+				cur_frm.doc.grand_total -= flt(doc.grand_total);
+				cur_frm.doc.net_total -= flt(doc.net_total);
+				cur_frm.doc.total_quantity -= flt(doc.total_qty);
+				refresh_payments(doc, cur_frm, 1);
+				refresh_taxes(doc, cur_frm, 1);
+				refresh_fields(cur_frm);
+				set_html_data(cur_frm);
+			});
+		}
 	}
 });
 
-cur_frm.cscript.before_pos_transactions_remove = function(doc, cdt, cdn) {
-	const removed_row = locals[cdt][cdn];
-
-	if (!removed_row.pos_invoice) return;
-
-	frappe.db.get_doc("POS Invoice", removed_row.pos_invoice).then(doc => {
-		cur_frm.doc.grand_total -= flt(doc.grand_total);
-		cur_frm.doc.net_total -= flt(doc.net_total);
-		cur_frm.doc.total_quantity -= flt(doc.total_qty);
-		refresh_payments(doc, cur_frm, 1);
-		refresh_taxes(doc, cur_frm, 1);
-		refresh_fields(cur_frm);
-		set_html_data(cur_frm);
-	});
-}
-
-frappe.ui.form.on('POS Invoice Reference', {
-	pos_invoice(frm, cdt, cdn) {
-		const added_row = locals[cdt][cdn];
-
-		if (!added_row.pos_invoice) return;
-
-		frappe.db.get_doc("POS Invoice", added_row.pos_invoice).then(doc => {
-			frm.doc.grand_total += flt(doc.grand_total);
-			frm.doc.net_total += flt(doc.net_total);
-			frm.doc.total_quantity += flt(doc.total_qty);
-			refresh_payments(doc, frm);
-			refresh_taxes(doc, frm);
-			refresh_fields(frm);
-			set_html_data(frm);
-		});
-	}
-})
-
 frappe.ui.form.on('POS Closing Entry Detail', {
 	closing_amount: (frm, cdt, cdn) => {
 		const row = locals[cdt][cdn];
@@ -177,11 +193,13 @@
 }
 
 function set_html_data(frm) {
-	frappe.call({
-		method: "get_payment_reconciliation_details",
-		doc: frm.doc,
-		callback: (r) => {
-			frm.get_field("payment_reconciliation_details").$wrapper.html(r.message);
-		}
-	})
+	if (frm.doc.docstatus === 1 && frm.doc.status == 'Submitted') {
+		frappe.call({
+			method: "get_payment_reconciliation_details",
+			doc: frm.doc,
+			callback: (r) => {
+				frm.get_field("payment_reconciliation_details").$wrapper.html(r.message);
+			}
+		});
+	}
 }
diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.json b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.json
index a9b91e0..4d6e4a2 100644
--- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.json
+++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.json
@@ -30,6 +30,8 @@
   "total_quantity",
   "column_break_16",
   "taxes",
+  "failure_description_section",
+  "error_message",
   "section_break_14",
   "amended_from"
  ],
@@ -195,7 +197,7 @@
    "fieldtype": "Select",
    "hidden": 1,
    "label": "Status",
-   "options": "Draft\nSubmitted\nQueued\nCancelled",
+   "options": "Draft\nSubmitted\nQueued\nFailed\nCancelled",
    "print_hide": 1,
    "read_only": 1
   },
@@ -203,6 +205,21 @@
    "fieldname": "period_details_section",
    "fieldtype": "Section Break",
    "label": "Period Details"
+  },
+  {
+   "collapsible": 1,
+   "collapsible_depends_on": "error_message",
+   "depends_on": "error_message",
+   "fieldname": "failure_description_section",
+   "fieldtype": "Section Break",
+   "label": "Failure Description"
+  },
+  {
+   "depends_on": "error_message",
+   "fieldname": "error_message",
+   "fieldtype": "Small Text",
+   "label": "Error",
+   "read_only": 1
   }
  ],
  "is_submittable": 1,
@@ -212,7 +229,7 @@
    "link_fieldname": "pos_closing_entry"
   }
  ],
- "modified": "2021-02-01 13:47:20.722104",
+ "modified": "2021-05-05 16:59:49.723261",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "POS Closing Entry",
diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py
index 1065168..8252872 100644
--- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py
+++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py
@@ -60,6 +60,10 @@
 	def on_cancel(self):
 		unconsolidate_pos_invoices(closing_entry=self)
 
+	@frappe.whitelist()
+	def retry(self):
+		consolidate_pos_invoices(closing_entry=self)
+
 	def update_opening_entry(self, for_cancel=False):
 		opening_entry = frappe.get_doc("POS Opening Entry", self.pos_opening_entry)
 		opening_entry.pos_closing_entry = self.name if not for_cancel else None
diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry_list.js b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry_list.js
index 20fd610..cffeb4d 100644
--- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry_list.js
+++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry_list.js
@@ -8,6 +8,7 @@
 			"Draft": "red",
 			"Submitted": "blue",
 			"Queued": "orange",
+			"Failed": "red",
 			"Cancelled": "red"
 
 		};
diff --git a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
index 4d5472d..bc78743 100644
--- a/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
+++ b/erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
@@ -13,8 +13,7 @@
 from frappe.utils.scheduler import is_scheduler_inactive
 from frappe.core.page.background_jobs.background_jobs import get_info
 import json
-
-from six import iteritems
+import six
 
 class POSInvoiceMergeLog(Document):
 	def validate(self):
@@ -239,7 +238,7 @@
 	invoices = pos_invoices or (closing_entry and closing_entry.get('pos_transactions')) or get_all_unconsolidated_invoices()
 	invoice_by_customer = get_invoice_customer_map(invoices)
 
-	if len(invoices) >= 1 and closing_entry:
+	if len(invoices) >= 10 and closing_entry:
 		closing_entry.set_status(update=True, status='Queued')
 		enqueue_job(create_merge_logs, invoice_by_customer=invoice_by_customer, closing_entry=closing_entry)
 	else:
@@ -252,36 +251,68 @@
 		pluck='name'
 	)
 
-	if len(merge_logs) >= 1:
+	if len(merge_logs) >= 10:
 		closing_entry.set_status(update=True, status='Queued')
 		enqueue_job(cancel_merge_logs, merge_logs=merge_logs, closing_entry=closing_entry)
 	else:
 		cancel_merge_logs(merge_logs, closing_entry)
 
 def create_merge_logs(invoice_by_customer, closing_entry=None):
-	for customer, invoices in iteritems(invoice_by_customer):
-		merge_log = frappe.new_doc('POS Invoice Merge Log')
-		merge_log.posting_date = getdate(closing_entry.get('posting_date')) if closing_entry else nowdate()
-		merge_log.customer = customer
-		merge_log.pos_closing_entry = closing_entry.get('name') if closing_entry else None
+	try:
+		for customer, invoices in six.iteritems(invoice_by_customer):
+			merge_log = frappe.new_doc('POS Invoice Merge Log')
+			merge_log.posting_date = getdate(closing_entry.get('posting_date')) if closing_entry else nowdate()
+			merge_log.customer = customer
+			merge_log.pos_closing_entry = closing_entry.get('name') if closing_entry else None
 
-		merge_log.set('pos_invoices', invoices)
-		merge_log.save(ignore_permissions=True)
-		merge_log.submit()
+			merge_log.set('pos_invoices', invoices)
+			merge_log.save(ignore_permissions=True)
+			merge_log.submit()
 
-	if closing_entry:
-		closing_entry.set_status(update=True, status='Submitted')
-		closing_entry.update_opening_entry()
+		if closing_entry:
+			closing_entry.set_status(update=True, status='Submitted')
+			closing_entry.db_set('error_message', '')
+			closing_entry.update_opening_entry()
+
+	except Exception:
+		frappe.db.rollback()
+		message_log = frappe.message_log.pop()
+		error_message = safe_load_json(message_log)
+
+		if closing_entry:
+			closing_entry.set_status(update=True, status='Failed')
+			closing_entry.db_set('error_message', error_message)
+		raise
+
+	finally:
+		frappe.db.commit()
+		frappe.publish_realtime('closing_process_complete', {'user': frappe.session.user})
 
 def cancel_merge_logs(merge_logs, closing_entry=None):
-	for log in merge_logs:
-		merge_log = frappe.get_doc('POS Invoice Merge Log', log)
-		merge_log.flags.ignore_permissions = True
-		merge_log.cancel()
+	try:
+		for log in merge_logs:
+			merge_log = frappe.get_doc('POS Invoice Merge Log', log)
+			merge_log.flags.ignore_permissions = True
+			merge_log.cancel()
 
-	if closing_entry:
-		closing_entry.set_status(update=True, status='Cancelled')
-		closing_entry.update_opening_entry(for_cancel=True)
+		if closing_entry:
+			closing_entry.set_status(update=True, status='Cancelled')
+			closing_entry.db_set('error_message', '')
+			closing_entry.update_opening_entry(for_cancel=True)
+
+	except Exception:
+		frappe.db.rollback()
+		message_log = frappe.message_log.pop()
+		error_message = safe_load_json(message_log)
+
+		if closing_entry:
+			closing_entry.set_status(update=True, status='Submitted')
+			closing_entry.db_set('error_message', error_message)
+		raise
+
+	finally:
+		frappe.db.commit()
+		frappe.publish_realtime('closing_process_complete', {'user': frappe.session.user})
 
 def enqueue_job(job, **kwargs):
 	check_scheduler_status()
@@ -314,4 +345,14 @@
 def job_already_enqueued(job_name):
 	enqueued_jobs = [d.get("job_name") for d in get_info()]
 	if job_name in enqueued_jobs:
-		return True
\ No newline at end of file
+		return True
+
+def safe_load_json(message):
+	JSONDecodeError = ValueError if six.PY2 else json.JSONDecodeError
+
+	try:
+		json_message = json.loads(message).get('message')
+	except JSONDecodeError:
+		json_message = message
+
+	return json_message
\ No newline at end of file
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 5276da9..4bb6138 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -98,6 +98,7 @@
 		["Draft", None],
 		["Submitted", "eval:self.docstatus == 1"],
 		["Queued", "eval:self.status == 'Queued'"],
+		["Failed", "eval:self.status == 'Failed'"],
 		["Cancelled", "eval:self.docstatus == 2"],
 	]
 }
diff --git a/erpnext/education/doctype/education_settings/education_settings.py b/erpnext/education/doctype/education_settings/education_settings.py
index a85d3e7..658380e 100644
--- a/erpnext/education/doctype/education_settings/education_settings.py
+++ b/erpnext/education/doctype/education_settings/education_settings.py
@@ -31,9 +31,9 @@
 	def validate(self):
 		from frappe.custom.doctype.property_setter.property_setter import make_property_setter
 		if self.get('instructor_created_by')=='Naming Series':
-			make_property_setter('Instructor', "naming_series", "hidden", 0, "Check")
+			make_property_setter('Instructor', "naming_series", "hidden", 0, "Check", validate_fields_for_doctype=False)
 		else:
-			make_property_setter('Instructor', "naming_series", "hidden", 1, "Check")
+			make_property_setter('Instructor', "naming_series", "hidden", 1, "Check", validate_fields_for_doctype=False)
 
 def update_website_context(context):
 	context["lms_enabled"] = frappe.get_doc("Education Settings").enable_lms
\ No newline at end of file
diff --git a/erpnext/hr/doctype/department/department.py b/erpnext/hr/doctype/department/department.py
index 2cef509..539a360 100644
--- a/erpnext/hr/doctype/department/department.py
+++ b/erpnext/hr/doctype/department/department.py
@@ -31,7 +31,8 @@
 		return new
 
 	def on_update(self):
-		NestedSet.on_update(self)
+		if not frappe.local.flags.ignore_update_nsm:
+			super(Department, self).on_update()
 
 	def on_trash(self):
 		super(Department, self).on_trash()
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index de9f6e3..9ef949c 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -774,3 +774,4 @@
 erpnext.patches.v13_0.make_non_standard_user_type #13-04-2021
 erpnext.patches.v13_0.update_shipment_status
 erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting
+erpnext.patches.v13_0.set_pos_closing_as_failed
diff --git a/erpnext/patches/v13_0/set_pos_closing_as_failed.py b/erpnext/patches/v13_0/set_pos_closing_as_failed.py
new file mode 100644
index 0000000..1c576db
--- /dev/null
+++ b/erpnext/patches/v13_0/set_pos_closing_as_failed.py
@@ -0,0 +1,7 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+    frappe.reload_doc('accounts', 'doctype', 'pos_closing_entry')
+
+    frappe.db.sql("update `tabPOS Closing Entry` set `status` = 'Failed' where `status` = 'Queued'")
\ No newline at end of file
diff --git a/erpnext/payroll/doctype/payroll_settings/payroll_settings.py b/erpnext/payroll/doctype/payroll_settings/payroll_settings.py
index 5efa41d..459b7ea 100644
--- a/erpnext/payroll/doctype/payroll_settings/payroll_settings.py
+++ b/erpnext/payroll/doctype/payroll_settings/payroll_settings.py
@@ -28,5 +28,5 @@
 
 	def toggle_rounded_total(self):
 		self.disable_rounded_total = cint(self.disable_rounded_total)
-		make_property_setter("Salary Slip", "rounded_total", "hidden", self.disable_rounded_total, "Check")
-		make_property_setter("Salary Slip", "rounded_total", "print_hide", self.disable_rounded_total, "Check")
+		make_property_setter("Salary Slip", "rounded_total", "hidden", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
+		make_property_setter("Salary Slip", "rounded_total", "print_hide", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index f91b432..0af8da7 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1379,12 +1379,12 @@
 
 	update_payment_schedule_grid_labels: function(company_currency) {
 		const me = this;
-		if (this.frm.fields_dict["payment_schedule"]) {
+		if (this.frm.doc.payment_schedule && this.frm.doc.payment_schedule.length > 0) {
 			this.frm.set_currency_labels(["base_payment_amount", "base_outstanding", "base_paid_amount"],
 				company_currency, "payment_schedule");
 			this.frm.set_currency_labels(["payment_amount", "outstanding", "paid_amount"],
 				this.frm.doc.currency, "payment_schedule");
-			
+
 			var schedule_grid = this.frm.fields_dict["payment_schedule"].grid;
 			$.each(["base_payment_amount", "base_outstanding", "base_paid_amount"], function(i, fname) {
 				if (frappe.meta.get_docfield(schedule_grid.doctype, fname))
@@ -2034,7 +2034,7 @@
 					if(r.message && !r.exc) {
 						me.frm.set_value("payment_schedule", r.message);
 						const company_currency = me.get_company_currency();
-						this.update_payment_schedule_grid_labels(company_currency);
+						me.update_payment_schedule_grid_labels(company_currency);
 					}
 				}
 			})
diff --git a/erpnext/selling/doctype/selling_settings/selling_settings.py b/erpnext/selling/doctype/selling_settings/selling_settings.py
index d297883..b219e7e 100644
--- a/erpnext/selling/doctype/selling_settings/selling_settings.py
+++ b/erpnext/selling/doctype/selling_settings/selling_settings.py
@@ -30,8 +30,8 @@
 
 		# Make property setters to hide tax_id fields
 		for doctype in ("Sales Order", "Sales Invoice", "Delivery Note"):
-			make_property_setter(doctype, "tax_id", "hidden", self.hide_tax_id, "Check")
-			make_property_setter(doctype, "tax_id", "print_hide", self.hide_tax_id, "Check")
+			make_property_setter(doctype, "tax_id", "hidden", self.hide_tax_id, "Check", validate_fields_for_doctype=False)
+			make_property_setter(doctype, "tax_id", "print_hide", self.hide_tax_id, "Check", validate_fields_for_doctype=False)
 
 	def set_default_customer_group_and_territory(self):
 		if not self.customer_group:
diff --git a/erpnext/setup/doctype/global_defaults/global_defaults.py b/erpnext/setup/doctype/global_defaults/global_defaults.py
index 76a8450..e587217 100644
--- a/erpnext/setup/doctype/global_defaults/global_defaults.py
+++ b/erpnext/setup/doctype/global_defaults/global_defaults.py
@@ -60,11 +60,11 @@
 		# Make property setters to hide rounded total fields
 		for doctype in ("Quotation", "Sales Order", "Sales Invoice", "Delivery Note",
 			"Supplier Quotation", "Purchase Order", "Purchase Invoice"):
-			make_property_setter(doctype, "base_rounded_total", "hidden", self.disable_rounded_total, "Check")
-			make_property_setter(doctype, "base_rounded_total", "print_hide", 1, "Check")
+			make_property_setter(doctype, "base_rounded_total", "hidden", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
+			make_property_setter(doctype, "base_rounded_total", "print_hide", 1, "Check", validate_fields_for_doctype=False)
 
-			make_property_setter(doctype, "rounded_total", "hidden", self.disable_rounded_total, "Check")
-			make_property_setter(doctype, "rounded_total", "print_hide", self.disable_rounded_total, "Check")
+			make_property_setter(doctype, "rounded_total", "hidden", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
+			make_property_setter(doctype, "rounded_total", "print_hide", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
 
 	def toggle_in_words(self):
 		self.disable_in_words = cint(self.disable_in_words)
@@ -72,5 +72,5 @@
 		# Make property setters to hide in words fields
 		for doctype in ("Quotation", "Sales Order", "Sales Invoice", "Delivery Note",
 				"Supplier Quotation", "Purchase Order", "Purchase Invoice", "Purchase Receipt"):
-			make_property_setter(doctype, "in_words", "hidden", self.disable_in_words, "Check")
-			make_property_setter(doctype, "in_words", "print_hide", self.disable_in_words, "Check")
+			make_property_setter(doctype, "in_words", "hidden", self.disable_in_words, "Check", validate_fields_for_doctype=False)
+			make_property_setter(doctype, "in_words", "print_hide", self.disable_in_words, "Check", validate_fields_for_doctype=False)
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 373b0a5..c1f9433 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -183,8 +183,8 @@
 def set_by_naming_series(doctype, fieldname, naming_series, hide_name_field=True):
 	from frappe.custom.doctype.property_setter.property_setter import make_property_setter
 	if naming_series:
-		make_property_setter(doctype, "naming_series", "hidden", 0, "Check")
-		make_property_setter(doctype, "naming_series", "reqd", 1, "Check")
+		make_property_setter(doctype, "naming_series", "hidden", 0, "Check", validate_fields_for_doctype=False)
+		make_property_setter(doctype, "naming_series", "reqd", 1, "Check", validate_fields_for_doctype=False)
 
 		# set values for mandatory
 		try:
@@ -195,15 +195,15 @@
 			pass
 
 		if hide_name_field:
-			make_property_setter(doctype, fieldname, "reqd", 0, "Check")
-			make_property_setter(doctype, fieldname, "hidden", 1, "Check")
+			make_property_setter(doctype, fieldname, "reqd", 0, "Check", validate_fields_for_doctype=False)
+			make_property_setter(doctype, fieldname, "hidden", 1, "Check", validate_fields_for_doctype=False)
 	else:
-		make_property_setter(doctype, "naming_series", "reqd", 0, "Check")
-		make_property_setter(doctype, "naming_series", "hidden", 1, "Check")
+		make_property_setter(doctype, "naming_series", "reqd", 0, "Check", validate_fields_for_doctype=False)
+		make_property_setter(doctype, "naming_series", "hidden", 1, "Check", validate_fields_for_doctype=False)
 
 		if hide_name_field:
-			make_property_setter(doctype, fieldname, "hidden", 0, "Check")
-			make_property_setter(doctype, fieldname, "reqd", 1, "Check")
+			make_property_setter(doctype, fieldname, "hidden", 0, "Check", validate_fields_for_doctype=False)
+			make_property_setter(doctype, fieldname, "reqd", 1, "Check", validate_fields_for_doctype=False)
 
 			# set values for mandatory
 			frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=`name` where
diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py
index 5053c6a..f21d55f 100644
--- a/erpnext/setup/setup_wizard/operations/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py
@@ -12,6 +12,7 @@
 
 from erpnext.accounts.doctype.account.account import RootNotEditable
 from erpnext.regional.address_template.setup import set_up_address_templates
+from frappe.utils.nestedset import rebuild_tree
 
 default_lead_sources = ["Existing Customer", "Reference", "Advertisement",
 	"Cold Calling", "Exhibition", "Supplier Reference", "Mass Mailing",
@@ -280,13 +281,15 @@
 	set_more_defaults()
 	update_global_search_doctypes()
 
-	# path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(country))
-	# if os.path.exists(path.encode("utf-8")):
-	# 	frappe.get_attr("erpnext.regional.{0}.setup.setup_company_independent_fixtures".format(frappe.scrub(country)))()
-
-
 def set_more_defaults():
 	# Do more setup stuff that can be done here with no dependencies
+	update_selling_defaults()
+	update_buying_defaults()
+	update_hr_defaults()
+	add_uom_data()
+	update_item_variant_settings()
+
+def update_selling_defaults():
 	selling_settings = frappe.get_doc("Selling Settings")
 	selling_settings.set_default_customer_group_and_territory()
 	selling_settings.cust_master_name = "Customer Name"
@@ -296,13 +299,7 @@
 	selling_settings.sales_update_frequency = "Each Transaction"
 	selling_settings.save()
 
-	add_uom_data()
-
-	# set no copy fields of an item doctype to item variant settings
-	doc = frappe.get_doc('Item Variant Settings')
-	doc.set_default_fields()
-	doc.save()
-
+def update_buying_defaults():
 	buying_settings = frappe.get_doc("Buying Settings")
 	buying_settings.supp_master_name = "Supplier Name"
 	buying_settings.po_required = "No"
@@ -311,12 +308,19 @@
 	buying_settings.allow_multiple_items = 1
 	buying_settings.save()
 
+def update_hr_defaults():
 	hr_settings = frappe.get_doc("HR Settings")
 	hr_settings.emp_created_by = "Naming Series"
 	hr_settings.leave_approval_notification_template = _("Leave Approval Notification")
 	hr_settings.leave_status_notification_template = _("Leave Status Notification")
 	hr_settings.save()
 
+def update_item_variant_settings():
+	# set no copy fields of an item doctype to item variant settings
+	doc = frappe.get_doc('Item Variant Settings')
+	doc.set_default_fields()
+	doc.save()
+
 def add_uom_data():
 	# add UOMs
 	uoms = json.loads(open(frappe.get_app_path("erpnext", "setup", "setup_wizard", "data", "uom_data.json")).read())
@@ -327,7 +331,7 @@
 				"uom_name": _(d.get("uom_name")),
 				"name": _(d.get("uom_name")),
 				"must_be_whole_number": d.get("must_be_whole_number")
-			}).insert(ignore_permissions=True)
+			}).db_insert()
 
 	# bootstrap uom conversion factors
 	uom_conversions = json.loads(open(frappe.get_app_path("erpnext", "setup", "setup_wizard", "data", "uom_conversion_data.json")).read())
@@ -336,7 +340,7 @@
 			frappe.get_doc({
 				"doctype": "UOM Category",
 				"category_name": _(d.get("category"))
-			}).insert(ignore_permissions=True)
+			}).db_insert()
 
 		if not frappe.db.exists("UOM Conversion Factor", {"from_uom": _(d.get("from_uom")), "to_uom": _(d.get("to_uom"))}):
 			uom_conversion = frappe.get_doc({
@@ -369,8 +373,8 @@
 		{"doctype": "Sales Stage", "stage_name": _("Proposal/Price Quote")},
 		{"doctype": "Sales Stage", "stage_name": _("Negotiation/Review")}
 	]
-
-	make_records(records)
+	for sales_stage in records:
+		frappe.get_doc(sales_stage).db_insert()
 
 def install_company(args):
 	records = [
@@ -418,7 +422,14 @@
 		{'doctype': 'Department', 'department_name': _('Legal'), 'parent_department': _('All Departments'), 'company': args.company_name},
 	]
 
-	make_records(records)
+	# Make root department with NSM updation
+	make_records(records[:1])
+
+	frappe.local.flags.ignore_update_nsm = True
+	make_records(records[1:])
+	frappe.local.flags.ignore_update_nsm = False
+	
+	rebuild_tree("Department", "parent_department")
 
 
 def install_defaults(args=None):
@@ -432,7 +443,15 @@
 
 	# enable default currency
 	frappe.db.set_value("Currency", args.get("currency"), "enabled", 1)
+	frappe.db.set_value("Stock Settings", None, "email_footer_address", args.get("company_name"))
 
+	set_global_defaults(args)
+	set_active_domains(args)
+	update_stock_settings()
+	update_shopping_cart_settings(args)
+	create_bank_account(args)
+
+def set_global_defaults(args):
 	global_defaults = frappe.get_doc("Global Defaults", "Global Defaults")
 	current_fiscal_year = frappe.get_all("Fiscal Year")[0]
 
@@ -445,13 +464,10 @@
 
 	global_defaults.save()
 
-	system_settings = frappe.get_doc("System Settings")
-	system_settings.email_footer_address = args.get("company_name")
-	system_settings.save()
+def set_active_domains(args):
+	frappe.get_single('Domain Settings').set_active_domains(args.get('domains'))
 
-	domain_settings = frappe.get_single('Domain Settings')
-	domain_settings.set_active_domains(args.get('domains'))
-
+def update_stock_settings():
 	stock_settings = frappe.get_doc("Stock Settings")
 	stock_settings.item_naming_by = "Item Code"
 	stock_settings.valuation_method = "FIFO"
@@ -463,48 +479,44 @@
 	stock_settings.set_qty_in_transactions_based_on_serial_no_input = 1
 	stock_settings.save()
 
-	if args.bank_account:
-		company_name = args.company_name
-		bank_account_group =  frappe.db.get_value("Account",
-			{"account_type": "Bank", "is_group": 1, "root_type": "Asset",
-				"company": company_name})
-		if bank_account_group:
-			bank_account = frappe.get_doc({
-				"doctype": "Account",
-				'account_name': args.bank_account,
-				'parent_account': bank_account_group,
-				'is_group':0,
-				'company': company_name,
-				"account_type": "Bank",
-			})
-			try:
-				doc = bank_account.insert()
+def create_bank_account(args):
+	if not args.bank_account:
+		return
 
-				frappe.db.set_value("Company", args.company_name, "default_bank_account", bank_account.name, update_modified=False)
+	company_name = args.company_name
+	bank_account_group =  frappe.db.get_value("Account",
+		{"account_type": "Bank", "is_group": 1, "root_type": "Asset",
+			"company": company_name})
+	if bank_account_group:
+		bank_account = frappe.get_doc({
+			"doctype": "Account",
+			'account_name': args.bank_account,
+			'parent_account': bank_account_group,
+			'is_group':0,
+			'company': company_name,
+			"account_type": "Bank",
+		})
+		try:
+			doc = bank_account.insert()
 
-			except RootNotEditable:
-				frappe.throw(_("Bank account cannot be named as {0}").format(args.bank_account))
-			except frappe.DuplicateEntryError:
-				# bank account same as a CoA entry
-				pass
+			frappe.db.set_value("Company", args.company_name, "default_bank_account", bank_account.name, update_modified=False)
 
-	# Now, with fixtures out of the way, onto concrete stuff
-	records = [
+		except RootNotEditable:
+			frappe.throw(_("Bank account cannot be named as {0}").format(args.bank_account))
+		except frappe.DuplicateEntryError:
+			# bank account same as a CoA entry
+			pass
 
-		# Shopping cart: needs price lists
-		{
-			"doctype": "Shopping Cart Settings",
-			"enabled": 1,
-			'company': args.company_name,
-			# uh oh
-			'price_list': frappe.db.get_value("Price List", {"selling": 1}),
-			'default_customer_group': _("Individual"),
-			'quotation_series': "QTN-",
-		},
-	]
-
-	make_records(records)
-
+def update_shopping_cart_settings(args):
+	shopping_cart = frappe.get_doc("Shopping Cart Settings")
+	shopping_cart.update({
+		"enabled": 1,
+		'company': args.company_name,
+		'price_list': frappe.db.get_value("Price List", {"selling": 1}),
+		'default_customer_group': _("Individual"),
+		'quotation_series': "QTN-",
+	})
+	shopping_cart.update_single(shopping_cart.get_valid_dict())
 
 def get_fy_details(fy_start_date, fy_end_date):
 	start_year = getdate(fy_start_date).year
diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py
index e74d837..f63d269 100644
--- a/erpnext/setup/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/setup_wizard/setup_wizard.py
@@ -52,11 +52,6 @@
 				'fail_msg': 'Failed to set defaults',
 				'tasks': [
 					{
-						'fn': setup_post_company_fixtures,
-						'args': args,
-						'fail_msg': _("Failed to setup post company fixtures")
-					},
-					{
 						'fn': setup_defaults,
 						'args': args,
 						'fail_msg': _("Failed to setup defaults")
@@ -94,9 +89,6 @@
 def setup_company(args):
 	fixtures.install_company(args)
 
-def setup_post_company_fixtures(args):
-	fixtures.install_post_company_fixtures(args)
-
 def setup_defaults(args):
 	fixtures.install_defaults(frappe._dict(args))
 
@@ -129,7 +121,6 @@
 def setup_complete(args=None):
 	stage_fixtures(args)
 	setup_company(args)
-	setup_post_company_fixtures(args)
 	setup_defaults(args)
 	stage_four(args)
 	fin(args)
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.py b/erpnext/stock/doctype/stock_settings/stock_settings.py
index 3b9608b..2dd7c6f 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.py
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.py
@@ -30,7 +30,7 @@
 		# show/hide barcode field
 		for name in ["barcode", "barcodes", "scan_barcode"]:
 			frappe.make_property_setter({'fieldname': name, 'property': 'hidden',
-				'value': 0 if self.show_barcode_field else 1})
+				'value': 0 if self.show_barcode_field else 1}, validate_fields_for_doctype=False)
 
 		self.validate_warehouses()
 		self.cant_change_valuation_method()
@@ -67,10 +67,10 @@
 		self.toggle_warehouse_field_for_inter_warehouse_transfer()
 
 	def toggle_warehouse_field_for_inter_warehouse_transfer(self):
-		make_property_setter("Sales Invoice Item", "target_warehouse", "hidden", 1 - cint(self.allow_from_dn), "Check")
-		make_property_setter("Delivery Note Item", "target_warehouse", "hidden", 1 - cint(self.allow_from_dn), "Check")
-		make_property_setter("Purchase Invoice Item", "from_warehouse", "hidden", 1 - cint(self.allow_from_pr), "Check")
-		make_property_setter("Purchase Receipt Item", "from_warehouse", "hidden", 1 - cint(self.allow_from_pr), "Check")
+		make_property_setter("Sales Invoice Item", "target_warehouse", "hidden", 1 - cint(self.allow_from_dn), "Check", validate_fields_for_doctype=False)
+		make_property_setter("Delivery Note Item", "target_warehouse", "hidden", 1 - cint(self.allow_from_dn), "Check", validate_fields_for_doctype=False)
+		make_property_setter("Purchase Invoice Item", "from_warehouse", "hidden", 1 - cint(self.allow_from_pr), "Check", validate_fields_for_doctype=False)
+		make_property_setter("Purchase Receipt Item", "from_warehouse", "hidden", 1 - cint(self.allow_from_pr), "Check", validate_fields_for_doctype=False)
 
 
 def clean_all_descriptions():