Merge pull request #27872 from 18alantom/fix-make-billing-address-not-read-only

fix: remove readonly from billing address
diff --git a/.github/helper/.flake8_strict b/.github/helper/.flake8_strict
index 4c7f5f8..c8337a9 100644
--- a/.github/helper/.flake8_strict
+++ b/.github/helper/.flake8_strict
@@ -65,6 +65,11 @@
     E713,
     E712,
 
+enable-extensions =
+    M90
+
+select =
+    M511
 
 max-line-length = 200
 exclude=.github/helper/semgrep_rules,test_*.py
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 2b3a471..e411f11 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -20,7 +20,10 @@
     rev: 3.9.2
     hooks:
       - id: flake8
-        args: ['--config', '.github/helper/.flake8_strict']
+        additional_dependencies: [
+          'flake8-mutable',
+        ]
+        args: ['--select=M511', '--config', '.github/helper/.flake8_strict']
         exclude: ".*setup.py$"
 
   - repo: https://github.com/timothycrosley/isort
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
index b1f3e6f..412833b 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
@@ -52,21 +52,35 @@
 
 	refresh() {
 		this.frm.disable_save();
+		this.frm.set_df_property('invoices', 'cannot_delete_rows', true);
+		this.frm.set_df_property('payments', 'cannot_delete_rows', true);
+		this.frm.set_df_property('allocation', 'cannot_delete_rows', true);
+
+		this.frm.set_df_property('invoices', 'cannot_add_rows', true);
+		this.frm.set_df_property('payments', 'cannot_add_rows', true);
+		this.frm.set_df_property('allocation', 'cannot_add_rows', true);
+
 
 		if (this.frm.doc.receivable_payable_account) {
 			this.frm.add_custom_button(__('Get Unreconciled Entries'), () =>
 				this.frm.trigger("get_unreconciled_entries")
 			);
+			this.frm.change_custom_button_type('Get Unreconciled Entries', null, 'primary');
 		}
 		if (this.frm.doc.invoices.length && this.frm.doc.payments.length) {
 			this.frm.add_custom_button(__('Allocate'), () =>
 				this.frm.trigger("allocate")
 			);
+			this.frm.change_custom_button_type('Allocate', null, 'primary');
+			this.frm.change_custom_button_type('Get Unreconciled Entries', null, 'default');
 		}
 		if (this.frm.doc.allocation.length) {
 			this.frm.add_custom_button(__('Reconcile'), () =>
 				this.frm.trigger("reconcile")
 			);
+			this.frm.change_custom_button_type('Reconcile', null, 'primary');
+			this.frm.change_custom_button_type('Get Unreconciled Entries', null, 'default');
+			this.frm.change_custom_button_type('Allocate', null, 'default');
 		}
 	}
 
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
index 9023b36..eb0c20f 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
@@ -12,15 +12,16 @@
   "receivable_payable_account",
   "col_break1",
   "from_invoice_date",
-  "to_invoice_date",
-  "minimum_invoice_amount",
-  "maximum_invoice_amount",
-  "invoice_limit",
-  "column_break_13",
   "from_payment_date",
-  "to_payment_date",
+  "minimum_invoice_amount",
   "minimum_payment_amount",
+  "column_break_11",
+  "to_invoice_date",
+  "to_payment_date",
+  "maximum_invoice_amount",
   "maximum_payment_amount",
+  "column_break_13",
+  "invoice_limit",
   "payment_limit",
   "bank_cash_account",
   "sec_break1",
@@ -79,6 +80,7 @@
   },
   {
    "depends_on": "eval:(doc.payments).length || (doc.invoices).length",
+   "description": "If you need to reconcile particular transactions against each other, then please select accordingly. If not, all the transactions will be allocated in FIFO order.",
    "fieldname": "sec_break1",
    "fieldtype": "Section Break",
    "label": "Unreconciled Entries"
@@ -163,6 +165,7 @@
    "label": "Maximum Payment Amount"
   },
   {
+   "description": "System will fetch all the entries if limit value is zero.",
    "fieldname": "payment_limit",
    "fieldtype": "Int",
    "label": "Payment Limit"
@@ -171,13 +174,17 @@
    "fieldname": "maximum_invoice_amount",
    "fieldtype": "Currency",
    "label": "Maximum Invoice Amount"
+  },
+  {
+   "fieldname": "column_break_11",
+   "fieldtype": "Column Break"
   }
  ],
  "hide_toolbar": 1,
  "icon": "icon-resize-horizontal",
  "issingle": 1,
  "links": [],
- "modified": "2021-08-30 13:05:51.977861",
+ "modified": "2021-10-04 20:27:11.114194",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation",
diff --git a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
index b8c65ee..6a21692 100644
--- a/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
+++ b/erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
@@ -14,8 +14,8 @@
   "section_break_6",
   "allocated_amount",
   "unreconciled_amount",
-  "amount",
   "column_break_8",
+  "amount",
   "is_advance",
   "section_break_5",
   "difference_amount",
@@ -127,12 +127,13 @@
    "fieldname": "reference_row",
    "fieldtype": "Data",
    "hidden": 1,
-   "label": "Reference Row"
+   "label": "Reference Row",
+   "read_only": 1
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2021-09-20 17:23:09.455803",
+ "modified": "2021-10-06 11:48:59.616562",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Reconciliation Allocation",
diff --git a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
index 83ecfb4..7c53f4a 100644
--- a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
+++ b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
@@ -33,7 +33,9 @@
 
 		frappe.db.sql("delete from `tabPOS Profile`")
 
-def get_customers_list(pos_profile={}):
+def get_customers_list(pos_profile=None):
+	if pos_profile is None:
+		pos_profile = {}
 	cond = "1=1"
 	customer_groups = []
 	if pos_profile.get('customer_groups'):
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 12b486e..0637fda 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -398,7 +398,9 @@
 				pricing_rules[0].apply_rule_on_other_items = items
 				return pricing_rules
 
-def get_qty_amount_data_for_cumulative(pr_doc, doc, items=[]):
+def get_qty_amount_data_for_cumulative(pr_doc, doc, items=None):
+	if items is None:
+		items = []
 	sum_qty, sum_amt = [0, 0]
 	doctype = doc.get('parenttype') or doc.doctype
 
diff --git a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py
index d09f7dc..f5391ca 100644
--- a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py
+++ b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.py
@@ -69,7 +69,9 @@
 			{'promotional_scheme': self.name}):
 			frappe.delete_doc('Pricing Rule', rule.name)
 
-def get_pricing_rules(doc, rules = {}):
+def get_pricing_rules(doc, rules=None):
+	if rules is None:
+		rules = {}
 	new_doc = []
 	for child_doc, fields in {'price_discount_slabs': price_discount_fields,
 		'product_discount_slabs': product_discount_fields}.items():
@@ -78,7 +80,9 @@
 
 	return new_doc
 
-def _get_pricing_rules(doc, child_doc, discount_fields, rules = {}):
+def _get_pricing_rules(doc, child_doc, discount_fields, rules=None):
+	if rules is None:
+		rules = {}
 	new_doc = []
 	args = get_args_for_pricing_rule(doc)
 	applicable_for = frappe.scrub(doc.get('applicable_for'))
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py
index d527188..bb8138b 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.py
+++ b/erpnext/accounts/report/cash_flow/cash_flow.py
@@ -139,9 +139,9 @@
 	data["total"] = total
 	return data
 
-def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters={}):
+def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters=None):
 	cond = ""
-	filters = frappe._dict(filters)
+	filters = frappe._dict(filters or {})
 
 	if filters.include_default_book_entries:
 		company_fb = frappe.db.get_value("Company", company, 'default_finance_book')
diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py
index ae498ba..be4ee56 100644
--- a/erpnext/education/doctype/student/student.py
+++ b/erpnext/education/doctype/student/student.py
@@ -138,7 +138,9 @@
 			enrollment.submit()
 			return enrollment
 
-	def enroll_in_course(self, course_name, program_enrollment, enrollment_date=frappe.utils.datetime.datetime.now()):
+	def enroll_in_course(self, course_name, program_enrollment, enrollment_date=None):
+		if enrollment_date is None:
+			enrollment_date = frappe.utils.datetime.datetime.now()
 		try:
 			enrollment = frappe.get_doc({
 					"doctype": "Course Enrollment",
diff --git a/erpnext/hr/doctype/holiday_list/holiday_list.py b/erpnext/hr/doctype/holiday_list/holiday_list.py
index f46f14d..7d1b991 100644
--- a/erpnext/hr/doctype/holiday_list/holiday_list.py
+++ b/erpnext/hr/doctype/holiday_list/holiday_list.py
@@ -1,4 +1,3 @@
-
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
@@ -94,9 +93,11 @@
 		update={"allDay": 1})
 
 
-def is_holiday(holiday_list, date=today()):
+def is_holiday(holiday_list, date=None):
 	"""Returns true if the given date is a holiday in the given holiday list
 	"""
+	if date is None:
+		date = today()
 	if holiday_list:
 		return bool(frappe.get_all('Holiday List',
 			dict(name=holiday_list, holiday_date=date)))
diff --git a/erpnext/hr/doctype/shift_assignment/shift_assignment.py b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
index 69af5c5..05b74a0 100644
--- a/erpnext/hr/doctype/shift_assignment/shift_assignment.py
+++ b/erpnext/hr/doctype/shift_assignment/shift_assignment.py
@@ -139,7 +139,7 @@
 	return shift_timing_map
 
 
-def get_employee_shift(employee, for_date=nowdate(), consider_default_shift=False, next_shift_direction=None):
+def get_employee_shift(employee, for_date=None, consider_default_shift=False, next_shift_direction=None):
 	"""Returns a Shift Type for the given employee on the given date. (excluding the holidays)
 
 	:param employee: Employee for which shift is required.
@@ -147,6 +147,8 @@
 	:param consider_default_shift: If set to true, default shift is taken when no shift assignment is found.
 	:param next_shift_direction: One of: None, 'forward', 'reverse'. Direction to look for next shift if shift not found on given date.
 	"""
+	if for_date is None:
+		for_date = nowdate()
 	default_shift = frappe.db.get_value('Employee', employee, 'default_shift')
 	shift_type_name = None
 	shift_assignment_details = frappe.db.get_value('Shift Assignment', {'employee':employee, 'start_date':('<=', for_date), 'docstatus': '1', 'status': "Active"}, ['shift_type', 'end_date'])
@@ -200,9 +202,11 @@
 	return get_shift_details(shift_type_name, for_date)
 
 
-def get_employee_shift_timings(employee, for_timestamp=now_datetime(), consider_default_shift=False):
+def get_employee_shift_timings(employee, for_timestamp=None, consider_default_shift=False):
 	"""Returns previous shift, current/upcoming shift, next_shift for the given timestamp and employee
 	"""
+	if for_timestamp is None:
+		for_timestamp = now_datetime()
 	# write and verify a test case for midnight shift.
 	prev_shift = curr_shift = next_shift = None
 	curr_shift = get_employee_shift(employee, for_timestamp.date(), consider_default_shift, 'forward')
@@ -220,7 +224,7 @@
 	return prev_shift, curr_shift, next_shift
 
 
-def get_shift_details(shift_type_name, for_date=nowdate()):
+def get_shift_details(shift_type_name, for_date=None):
 	"""Returns Shift Details which contain some additional information as described below.
 	'shift_details' contains the following keys:
 		'shift_type' - Object of DocType Shift Type,
@@ -234,6 +238,8 @@
 	"""
 	if not shift_type_name:
 		return None
+	if not for_date:
+		for_date = nowdate()
 	shift_type = frappe.get_doc('Shift Type', shift_type_name)
 	start_datetime = datetime.combine(for_date, datetime.min.time()) + shift_type.start_time
 	for_date = for_date + timedelta(days=1) if shift_type.start_time > shift_type.end_time else for_date
diff --git a/erpnext/hr/doctype/staffing_plan/staffing_plan.py b/erpnext/hr/doctype/staffing_plan/staffing_plan.py
index 57a92b0..93cd4e1 100644
--- a/erpnext/hr/doctype/staffing_plan/staffing_plan.py
+++ b/erpnext/hr/doctype/staffing_plan/staffing_plan.py
@@ -155,7 +155,11 @@
 	return employee_counts
 
 @frappe.whitelist()
-def get_active_staffing_plan_details(company, designation, from_date=getdate(nowdate()), to_date=getdate(nowdate())):
+def get_active_staffing_plan_details(company, designation, from_date=None, to_date=None):
+	if from_date is None:
+		from_date = getdate(nowdate())
+	if to_date is None:
+		to_date = getdate(nowdate())
 	if not company or not designation:
 		frappe.throw(_("Please select Company and Designation"))
 
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.json b/erpnext/payroll/doctype/salary_slip/salary_slip.json
index 1974403..7a80e69 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.json
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.json
@@ -329,7 +329,7 @@
   {
    "fieldname": "earning_deduction",
    "fieldtype": "Section Break",
-   "label": "Earning & Deduction",
+   "label": "Earnings & Deductions",
    "oldfieldtype": "Section Break"
   },
   {
@@ -380,7 +380,7 @@
    "depends_on": "total_loan_repayment",
    "fieldname": "loan_repayment",
    "fieldtype": "Section Break",
-   "label": "Loan repayment"
+   "label": "Loan Repayment"
   },
   {
    "fieldname": "loans",
@@ -425,7 +425,7 @@
   {
    "fieldname": "net_pay_info",
    "fieldtype": "Section Break",
-   "label": "net pay info"
+   "label": "Net Pay Info"
   },
   {
    "fieldname": "net_pay",
@@ -647,7 +647,7 @@
  "idx": 9,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-09-01 10:35:52.374549",
+ "modified": "2021-10-08 11:47:47.098248",
  "modified_by": "Administrator",
  "module": "Payroll",
  "name": "Salary Slip",
diff --git a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
index 9ed6686..178cd5c 100644
--- a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
@@ -141,7 +141,6 @@
 			create_salary_structure_assignment,
 		)
 
-		no_of_days = self.get_no_of_days()
 		# Payroll based on attendance
 		frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Attendance")
 
@@ -168,9 +167,6 @@
 		ss = make_salary_slip_for_payment_days_dependency_test("test_payment_days_based_component@salary.com", salary_structure.name)
 		self.assertEqual(ss.absent_days, 1)
 
-		days_in_month = no_of_days[0]
-		no_of_holidays = no_of_days[1]
-
 		ss.reload()
 		payment_days_based_comp_amount = 0
 		for component in ss.earnings:
@@ -992,13 +988,14 @@
 	return salary_structure_doc
 
 def make_salary_slip_for_payment_days_dependency_test(employee, salary_structure):
-	employee = frappe.db.get_value("Employee", {
-			"user_id": employee
-		},
+	employee = frappe.db.get_value(
+		"Employee",
+		{"user_id": employee},
 		["name", "company", "employee_name"],
-		as_dict=True)
+		as_dict=True
+	)
 
-	salary_slip_name = frappe.db.get_value("Salary Slip", {"employee": frappe.db.get_value("Employee", {"user_id": employee})})
+	salary_slip_name = frappe.db.get_value("Salary Slip", {"employee": employee.name})
 
 	if not salary_slip_name:
 		salary_slip = make_salary_slip(salary_structure, employee=employee.name)
@@ -1009,4 +1006,4 @@
 	else:
 		salary_slip = frappe.get_doc("Salary Slip", salary_slip_name)
 
-	return salary_slip
\ No newline at end of file
+	return salary_slip
diff --git a/erpnext/public/js/help_links.js b/erpnext/public/js/help_links.js
index d0c935f..b643cca 100644
--- a/erpnext/public/js/help_links.js
+++ b/erpnext/public/js/help_links.js
@@ -5,7 +5,7 @@
 frappe.help.help_links["Form/Rename Tool"] = [
 	{
 		label: "Bulk Rename",
-		url: docsUrl + "user/manual/en/setting-up/data/bulk-rename",
+		url: docsUrl + "user/manual/en/using-erpnext/articles/bulk-rename",
 	},
 ];
 
@@ -59,10 +59,23 @@
 	},
 ];
 
-frappe.help.help_links["data-import-tool"] = [
+frappe.help.help_links["Form/Data Import"] = [
 	{
 		label: "Importing and Exporting Data",
-		url: docsUrl + "user/manual/en/setting-up/data/data-import-tool",
+		url: docsUrl + "user/manual/en/setting-up/data/data-import",
+	},
+	{
+		label: "Overwriting Data from Data Import Tool",
+		url:
+			docsUrl +
+			"user/manual/en/setting-up/articles/overwriting-data-from-data-import-tool",
+	},
+];
+
+frappe.help.help_links["List/Data Import"] = [
+	{
+		label: "Importing and Exporting Data",
+		url: docsUrl + "user/manual/en/setting-up/data/data-import",
 	},
 	{
 		label: "Overwriting Data from Data Import Tool",
@@ -101,14 +114,14 @@
 	},
 ];
 
-frappe.help.help_links["Form/Email Digest"] = [
+frappe.help.help_links["List/Print Heading"] = [
 	{
-		label: "Email Digest",
-		url: docsUrl + "user/manual/en/setting-up/email/email-digest",
+		label: "Print Heading",
+		url: docsUrl + "user/manual/en/setting-up/print/print-headings",
 	},
 ];
 
-frappe.help.help_links["List/Print Heading"] = [
+frappe.help.help_links["Form/Print Heading"] = [
 	{
 		label: "Print Heading",
 		url: docsUrl + "user/manual/en/setting-up/print/print-headings",
@@ -153,18 +166,25 @@
 frappe.help.help_links["List/Notification"] = [
 	{
 		label: "Notification",
-		url: docsUrl + "user/manual/en/setting-up/email/notifications",
+		url: docsUrl + "user/manual/en/setting-up/notifications",
 	},
 ];
 
 frappe.help.help_links["Form/Notification"] = [
 	{
 		label: "Notification",
-		url: docsUrl + "user/manual/en/setting-up/email/notifications",
+		url: docsUrl + "user/manual/en/setting-up/notifications",
 	},
 ];
 
-frappe.help.help_links["List/Email Digest"] = [
+frappe.help.help_links["Form/Email Digest"] = [
+	{
+		label: "Email Digest",
+		url: docsUrl + "user/manual/en/setting-up/email/email-digest",
+	},
+];
+
+frappe.help.help_links["Form/Email Digest"] = [
 	{
 		label: "Email Digest",
 		url: docsUrl + "user/manual/en/setting-up/email/email-digest",
@@ -174,7 +194,7 @@
 frappe.help.help_links["List/Auto Email Report"] = [
 	{
 		label: "Auto Email Reports",
-		url: docsUrl + "user/manual/en/setting-up/email/email-reports",
+		url: docsUrl + "user/manual/en/setting-up/email/auto-email-reports",
 	},
 ];
 
@@ -188,14 +208,7 @@
 frappe.help.help_links["print-format-builder"] = [
 	{
 		label: "Print Format Builder",
-		url: docsUrl + "user/manual/en/setting-up/print/print-settings",
-	},
-];
-
-frappe.help.help_links["List/Print Heading"] = [
-	{
-		label: "Print Heading",
-		url: docsUrl + "user/manual/en/setting-up/print/print-headings",
+		url: docsUrl + "user/manual/en/setting-up/print/print-format-builder",
 	},
 ];
 
@@ -300,7 +313,7 @@
 	},
 	{
 		label: "Recurring Sales Order",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 	{
 		label: "Applying Discount",
@@ -315,7 +328,7 @@
 	},
 	{
 		label: "Recurring Sales Order",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 	{
 		label: "Applying Discount",
@@ -344,14 +357,14 @@
 frappe.help.help_links["Form/Product Bundle"] = [
 	{
 		label: "Product Bundle",
-		url: docsUrl + "user/manual/en/selling/setup/product-bundle",
+		url: docsUrl + "user/manual/en/selling/product-bundle",
 	},
 ];
 
 frappe.help.help_links["Form/Selling Settings"] = [
 	{
 		label: "Selling Settings",
-		url: docsUrl + "user/manual/en/selling/setup/selling-settings",
+		url: docsUrl + "user/manual/en/selling/selling-settings",
 	},
 ];
 
@@ -397,7 +410,7 @@
 	},
 	{
 		label: "Recurring Purchase Order",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 ];
 
@@ -420,7 +433,7 @@
 	},
 	{
 		label: "Recurring Purchase Order",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 	{
 		label: "Subcontracting",
@@ -435,24 +448,17 @@
 	},
 ];
 
-frappe.help.help_links["List/POS Profile"] = [
-	{
-		label: "POS Profile",
-		url: docsUrl + "user/manual/en/setting-up/pos-setting",
-	},
-];
-
 frappe.help.help_links["List/Price List"] = [
 	{
 		label: "Price List",
-		url: docsUrl + "user/manual/en/setting-up/price-lists",
+		url: docsUrl + "user/manual/en/stock/price-lists",
 	},
 ];
 
 frappe.help.help_links["List/Authorization Rule"] = [
 	{
 		label: "Authorization Rule",
-		url: docsUrl + "user/manual/en/setting-up/authorization-rule",
+		url: docsUrl + "user/manual/en/customize-erpnext/authorization-rule",
 	},
 ];
 
@@ -468,27 +474,14 @@
 		label: "Stock Reconciliation",
 		url:
 			docsUrl +
-			"user/manual/en/setting-up/stock-reconciliation-for-non-serialized-item",
+			"user/manual/en/stock/stock-reconciliation",
 	},
 ];
 
 frappe.help.help_links["Tree/Territory"] = [
 	{
 		label: "Territory",
-		url: docsUrl + "user/manual/en/setting-up/territory",
-	},
-];
-
-frappe.help.help_links["Form/Dropbox Backup"] = [
-	{
-		label: "Dropbox Backup",
-		url: docsUrl + "user/manual/en/setting-up/third-party-backups",
-	},
-	{
-		label: "Setting Up Dropbox Backup",
-		url:
-			docsUrl +
-			"user/manual/en/setting-up/articles/setting-up-dropbox-backups",
+		url: docsUrl + "user/manual/en/selling/territory",
 	},
 ];
 
@@ -502,12 +495,6 @@
 		url: docsUrl + "user/manual/en/setting-up/company-setup",
 	},
 	{
-		label: "Managing Multiple Companies",
-		url:
-			docsUrl +
-			"user/manual/en/setting-up/articles/managing-multiple-companies",
-	},
-	{
 		label: "Delete All Related Transactions for a Company",
 		url:
 			docsUrl +
@@ -517,21 +504,6 @@
 
 //Accounts
 
-frappe.help.help_links["modules/Accounts"] = [
-	{
-		label: "Introduction to Accounts",
-		url: docsUrl + "user/manual/en/accounts/",
-	},
-	{
-		label: "Chart of Accounts",
-		url: docsUrl + "user/manual/en/accounts/chart-of-accounts.html",
-	},
-	{
-		label: "Multi Currency Accounting",
-		url: docsUrl + "user/manual/en/accounts/multi-currency-accounting",
-	},
-];
-
 frappe.help.help_links["Tree/Account"] = [
 	{
 		label: "Chart of Accounts",
@@ -552,7 +524,7 @@
 	},
 	{
 		label: "Accounts Opening Balance",
-		url: docsUrl + "user/manual/en/accounts/opening-accounts",
+		url: docsUrl + "user/manual/en/accounts/opening-balance",
 	},
 	{
 		label: "Sales Return",
@@ -560,7 +532,7 @@
 	},
 	{
 		label: "Recurring Sales Invoice",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 ];
 
@@ -571,7 +543,7 @@
 	},
 	{
 		label: "Accounts Opening Balance",
-		url: docsUrl + "user/manual/en/accounts/opening-accounts",
+		url: docsUrl + "user/manual/en/accounts/opening-balances",
 	},
 	{
 		label: "Sales Return",
@@ -579,21 +551,28 @@
 	},
 	{
 		label: "Recurring Sales Invoice",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 ];
 
-frappe.help.help_links["pos"] = [
+frappe.help.help_links["point-of-sale"] = [
 	{
 		label: "Point of Sale Invoice",
-		url: docsUrl + "user/manual/en/accounts/point-of-sale-pos-invoice",
+		url: docsUrl + "user/manual/en/accounts/point-of-sales",
 	},
 ];
 
 frappe.help.help_links["List/POS Profile"] = [
 	{
 		label: "Point of Sale Profile",
-		url: docsUrl + "user/manual/en/setting-up/pos-setting",
+		url: docsUrl + "user/manual/en/accounts/pos-profile",
+	},
+];
+
+frappe.help.help_links["Form/POS Profile"] = [
+	{
+		label: "POS Profile",
+		url: docsUrl + "user/manual/en/accounts/pos-profile",
 	},
 ];
 
@@ -604,11 +583,11 @@
 	},
 	{
 		label: "Accounts Opening Balance",
-		url: docsUrl + "user/manual/en/accounts/opening-accounts",
+		url: docsUrl + "user/manual/en/accounts/opening-balance",
 	},
 	{
 		label: "Recurring Purchase Invoice",
-		url: docsUrl + "user/manual/en/accounts/recurring-orders-and-invoices",
+		url: docsUrl + "user/manual/en/accounts/articles/recurring-orders-and-invoices",
 	},
 ];
 
@@ -623,7 +602,7 @@
 	},
 	{
 		label: "Accounts Opening Balance",
-		url: docsUrl + "user/manual/en/accounts/opening-accounts",
+		url: docsUrl + "user/manual/en/accounts/opening-balance",
 	},
 ];
 
@@ -644,7 +623,7 @@
 frappe.help.help_links["List/Asset"] = [
 	{
 		label: "Managing Fixed Assets",
-		url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
+		url: docsUrl + "user/manual/en/asset",
 	},
 ];
 
@@ -659,6 +638,8 @@
 	{ label: "Budgeting", url: docsUrl + "user/manual/en/accounts/budgeting" },
 ];
 
+//Stock
+
 frappe.help.help_links["List/Item"] = [
 	{ label: "Item", url: docsUrl + "user/manual/en/stock/item" },
 	{
@@ -676,7 +657,7 @@
 	},
 	{
 		label: "Managing Fixed Assets",
-		url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
+		url: docsUrl + "user/manual/en/asset",
 	},
 	{
 		label: "Item Codification",
@@ -711,7 +692,7 @@
 	},
 	{
 		label: "Managing Fixed Assets",
-		url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
+		url: docsUrl + "user/manual/en/asset",
 	},
 	{
 		label: "Item Codification",
@@ -771,10 +752,6 @@
 		url:
 			docsUrl + "user/manual/en/stock/articles/track-items-using-barcode",
 	},
-	{
-		label: "Subcontracting",
-		url: docsUrl + "user/manual/en/manufacturing/subcontracting",
-	},
 ];
 
 frappe.help.help_links["List/Installation Note"] = [
@@ -784,21 +761,10 @@
 	},
 ];
 
-frappe.help.help_links["Tree"] = [
-	{
-		label: "Managing Tree Structure Masters",
-		url:
-			docsUrl +
-			"user/manual/en/setting-up/articles/managing-tree-structure-masters",
-	},
-];
-
 frappe.help.help_links["List/Budget"] = [
 	{ label: "Budgeting", url: docsUrl + "user/manual/en/accounts/budgeting" },
 ];
 
-//Stock
-
 frappe.help.help_links["List/Material Request"] = [
 	{
 		label: "Material Request",
@@ -861,6 +827,10 @@
 	{ label: "Serial No", url: docsUrl + "user/manual/en/stock/serial-no" },
 ];
 
+frappe.help.help_links["List/Batch"] = [
+	{ label: "Batch", url: docsUrl + "user/manual/en/stock/batch" },
+];
+
 frappe.help.help_links["Form/Batch"] = [
 	{ label: "Batch", url: docsUrl + "user/manual/en/stock/batch" },
 ];
@@ -868,35 +838,35 @@
 frappe.help.help_links["Form/Packing Slip"] = [
 	{
 		label: "Packing Slip",
-		url: docsUrl + "user/manual/en/stock/tools/packing-slip",
+		url: docsUrl + "user/manual/en/stock/packing-slip",
 	},
 ];
 
 frappe.help.help_links["Form/Quality Inspection"] = [
 	{
 		label: "Quality Inspection",
-		url: docsUrl + "user/manual/en/stock/tools/quality-inspection",
+		url: docsUrl + "user/manual/en/stock/quality-inspection",
 	},
 ];
 
 frappe.help.help_links["Form/Landed Cost Voucher"] = [
 	{
 		label: "Landed Cost Voucher",
-		url: docsUrl + "user/manual/en/stock/tools/landed-cost-voucher",
+		url: docsUrl + "user/manual/en/stock/landed-cost-voucher",
 	},
 ];
 
 frappe.help.help_links["Tree/Item Group"] = [
 	{
 		label: "Item Group",
-		url: docsUrl + "user/manual/en/stock/setup/item-group",
+		url: docsUrl + "user/manual/en/stock/item-group",
 	},
 ];
 
 frappe.help.help_links["Form/Item Attribute"] = [
 	{
 		label: "Item Attribute",
-		url: docsUrl + "user/manual/en/stock/setup/item-attribute",
+		url: docsUrl + "user/manual/en/stock/item-attribute",
 	},
 ];
 
@@ -911,7 +881,7 @@
 frappe.help.help_links["Form/Stock Reconciliation"] = [
 	{
 		label: "Opening Stock Entry",
-		url: docsUrl + "user/manual/en/stock/opening-stock",
+		url: docsUrl + "user/manual/en/stock/stock-reconciliation",
 	},
 ];
 
@@ -938,13 +908,13 @@
 ];
 
 frappe.help.help_links["Form/Campaign"] = [
-	{ label: "Campaign", url: docsUrl + "user/manual/en/CRM/setup/campaign" },
+	{ label: "Campaign", url: docsUrl + "user/manual/en/CRM/campaign" },
 ];
 
 frappe.help.help_links["Tree/Sales Person"] = [
 	{
 		label: "Sales Person",
-		url: docsUrl + "user/manual/en/CRM/setup/sales-person",
+		url: docsUrl + "user/manual/en/CRM/sales-person",
 	},
 ];
 
@@ -953,30 +923,13 @@
 		label: "Sales Person Target",
 		url:
 			docsUrl +
-			"user/manual/en/selling/setup/sales-person-target-allocation",
+			"user/manual/en/selling/sales-person-target-allocation",
 	},
-];
-
-//Support
-
-frappe.help.help_links["List/Feedback Trigger"] = [
 	{
-		label: "Feedback Trigger",
-		url: docsUrl + "user/manual/en/setting-up/feedback/setting-up-feedback",
-	},
-];
-
-frappe.help.help_links["List/Feedback Request"] = [
-	{
-		label: "Feedback Request",
-		url: docsUrl + "user/manual/en/setting-up/feedback/submit-feedback",
-	},
-];
-
-frappe.help.help_links["List/Feedback Request"] = [
-	{
-		label: "Feedback Request",
-		url: docsUrl + "user/manual/en/setting-up/feedback/submit-feedback",
+		label: "Sales Person in Transactions",
+		url:
+			docsUrl +
+			"user/manual/en/selling/articles/sales-persons-in-the-sales-transactions",
 	},
 ];
 
@@ -1019,7 +972,7 @@
 frappe.help.help_links["Form/BOM Update Tool"] = [
 	{
 		label: "BOM Update Tool",
-		url: docsUrl + "user/manual/en/manufacturing/tools/bom-update-tool",
+		url: docsUrl + "user/manual/en/manufacturing/bom-update-tool",
 	},
 ];
 
@@ -1036,7 +989,7 @@
 	},
 ];
 
-frappe.help.help_links["Form/Custom Field"] = [
+frappe.help.help_links["List/Custom Field"] = [
 	{
 		label: "Custom Field",
 		url: docsUrl + "user/manual/en/customize-erpnext/custom-field",
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 7f39b99..0323a42 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -712,6 +712,7 @@
 			allow_child_item_selection: opts.allow_child_item_selection,
 			child_fieldname: opts.child_fielname,
 			child_columns: opts.child_columns,
+			size: opts.size,
 			action: function(selections, args) {
 				let values = selections;
 				if (values.length === 0) {
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 9367609..dcf478b 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -110,7 +110,7 @@
 		if self.order_type == 'Sales' and not self.skip_delivery_note:
 			delivery_date_list = [d.delivery_date for d in self.get("items") if d.delivery_date]
 			max_delivery_date = max(delivery_date_list) if delivery_date_list else None
-			if not self.delivery_date:
+			if (max_delivery_date and not self.delivery_date) or (max_delivery_date and getdate(self.delivery_date) != getdate(max_delivery_date)):
 				self.delivery_date = max_delivery_date
 			if self.delivery_date:
 				for d in self.get("items"):
@@ -119,8 +119,6 @@
 					if getdate(self.transaction_date) > getdate(d.delivery_date):
 						frappe.msgprint(_("Expected Delivery Date should be after Sales Order Date"),
 							indicator='orange', title=_('Warning'))
-				if getdate(self.delivery_date) != getdate(max_delivery_date):
-					self.delivery_date = max_delivery_date
 			else:
 				frappe.throw(_("Please enter Delivery Date"))
 
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 8403193..95ca386 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -46,43 +46,6 @@
 		});
 	},
 
-	change_abbreviation(frm) {
-		var dialog = new frappe.ui.Dialog({
-			title: "Replace Abbr",
-			fields: [
-				{"fieldtype": "Data", "label": "New Abbreviation", "fieldname": "new_abbr",
-					"reqd": 1 },
-				{"fieldtype": "Button", "label": "Update", "fieldname": "update"},
-			]
-		});
-
-		dialog.fields_dict.update.$input.click(function() {
-			var args = dialog.get_values();
-			if (!args) return;
-			frappe.show_alert(__("Update in progress. It might take a while."));
-			return frappe.call({
-				method: "erpnext.setup.doctype.company.company.enqueue_replace_abbr",
-				args: {
-					"company": frm.doc.name,
-					"old": frm.doc.abbr,
-					"new": args.new_abbr
-				},
-				callback: function(r) {
-					if (r.exc) {
-						frappe.msgprint(__("There were errors."));
-						return;
-					} else {
-						frm.set_value("abbr", args.new_abbr);
-					}
-					dialog.hide();
-					frm.refresh();
-				},
-				btn: this
-			});
-		});
-		dialog.show();
-	},
-
 	company_name: function(frm) {
 		if(frm.doc.__islocal) {
 			// add missing " " arg in split method
@@ -164,10 +127,6 @@
 					}, __('Manage'));
 				}
 			}
-
-			frm.add_custom_button(__('Change Abbreviation'), () => {
-				frm.trigger('change_abbreviation');
-			}, __('Manage'));
 		}
 
 		erpnext.company.set_chart_of_accounts_options(frm.doc);
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 58cb52c..63d96bf 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -125,7 +125,8 @@
    "label": "Abbr",
    "oldfieldname": "abbr",
    "oldfieldtype": "Data",
-   "reqd": 1
+   "reqd": 1,
+   "set_only_once": 1
   },
   {
    "bold": 1,
@@ -747,10 +748,11 @@
  "image_field": "company_logo",
  "is_tree": 1,
  "links": [],
- "modified": "2021-07-12 11:27:06.353860",
+ "modified": "2021-10-04 12:09:25.833133",
  "modified_by": "Administrator",
  "module": "Setup",
  "name": "Company",
+ "naming_rule": "By fieldname",
  "nsm_parent_field": "parent_company",
  "owner": "Administrator",
  "permissions": [
@@ -808,4 +810,4 @@
  "sort_field": "modified",
  "sort_order": "ASC",
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 87d67a5..0b1b4a1 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -399,44 +399,6 @@
 		if not frappe.db.get_value('GL Entry', {'company': self.name}):
 			frappe.db.sql("delete from `tabProcess Deferred Accounting` where company=%s", self.name)
 
-@frappe.whitelist()
-def enqueue_replace_abbr(company, old, new):
-	kwargs = dict(queue="long", company=company, old=old, new=new)
-	frappe.enqueue('erpnext.setup.doctype.company.company.replace_abbr', **kwargs)
-
-
-@frappe.whitelist()
-def replace_abbr(company, old, new):
-	new = new.strip()
-	if not new:
-		frappe.throw(_("Abbr can not be blank or space"))
-
-	frappe.only_for("System Manager")
-
-	def _rename_record(doc):
-		parts = doc[0].rsplit(" - ", 1)
-		if len(parts) == 1 or parts[1].lower() == old.lower():
-			frappe.rename_doc(dt, doc[0], parts[0] + " - " + new, force=True)
-
-	def _rename_records(dt):
-		# rename is expensive so let's be economical with memory usage
-		doc = (d for d in frappe.db.sql("select name from `tab%s` where company=%s" % (dt, '%s'), company))
-		for d in doc:
-			_rename_record(d)
-	try:
-		frappe.db.auto_commit_on_many_writes = 1
-		for dt in ["Warehouse", "Account", "Cost Center", "Department",
-				"Sales Taxes and Charges Template", "Purchase Taxes and Charges Template"]:
-			_rename_records(dt)
-			frappe.db.commit()
-		frappe.db.set_value("Company", company, "abbr", new)
-
-	except Exception:
-		frappe.log_error(title=_('Abbreviation Rename Error'))
-	finally:
-		frappe.db.auto_commit_on_many_writes = 0
-
-
 def get_name_with_abbr(name, company):
 	company_abbr = frappe.get_cached_value('Company',  company,  "abbr")
 	parts = name.split(" - ")
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index cf98b19..17df977 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -296,7 +296,7 @@
 
 		return d.ordered_qty < d.stock_qty and child_filter
 
-	doclist = get_mapped_doc("Material Request", source_name, 	{
+	doclist = get_mapped_doc("Material Request", source_name, {
 		"Material Request": {
 			"doctype": "Purchase Order",
 			"validation": {
@@ -323,7 +323,7 @@
 
 @frappe.whitelist()
 def make_request_for_quotation(source_name, target_doc=None):
-	doclist = get_mapped_doc("Material Request", source_name, 	{
+	doclist = get_mapped_doc("Material Request", source_name, {
 		"Material Request": {
 			"doctype": "Request for Quotation",
 			"validation": {
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 82d8aae..a9254fb 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -611,7 +611,9 @@
 
 	return reserved_sr_nos
 
-def fetch_serial_numbers(filters, qty, do_not_include=[]):
+def fetch_serial_numbers(filters, qty, do_not_include=None):
+	if do_not_include is None:
+		do_not_include = []
 	batch_join_selection = ""
 	batch_no_condition = ""
 	batch_nos = filters.get("batch_no")
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 19597c3..cbff214 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -382,7 +382,7 @@
 
 	return out
 
-def get_item_warehouse(item, args, overwrite_warehouse, defaults={}):
+def get_item_warehouse(item, args, overwrite_warehouse, defaults=None):
 	if not defaults:
 		defaults = frappe._dict({
 			'item_defaults' : get_item_defaults(item.name, args.company),
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index 3cd4cd2..7c6fbfd 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -4,6 +4,7 @@
 from __future__ import unicode_literals
 
 import json
+from math import ceil
 
 import frappe
 from frappe import _
@@ -149,11 +150,16 @@
 							conversion_factor = frappe.db.get_value("UOM Conversion Detail",
 								{'parent': item.name, 'uom': uom}, 'conversion_factor') or 1.0
 
+					must_be_whole_number = frappe.db.get_value("UOM", uom, "must_be_whole_number", cache=True)
+					qty = d.reorder_qty / conversion_factor
+					if must_be_whole_number:
+						qty = ceil(qty)
+
 					mr.append("items", {
 						"doctype": "Material Request Item",
 						"item_code": d.item_code,
 						"schedule_date": add_days(nowdate(),cint(item.lead_time_days)),
-						"qty": d.reorder_qty / conversion_factor,
+						"qty": qty,
 						"uom": uom,
 						"stock_uom": item.stock_uom,
 						"warehouse": d.warehouse,