Merge branch 'develop' into sa-vat-report
diff --git a/.github/helper/semgrep_rules/frappe_correctness.yml b/.github/helper/semgrep_rules/frappe_correctness.yml
index faab334..d9603e8 100644
--- a/.github/helper/semgrep_rules/frappe_correctness.yml
+++ b/.github/helper/semgrep_rules/frappe_correctness.yml
@@ -98,8 +98,6 @@
   languages: [python]
   severity: WARNING
   paths:
-      exclude:
-        - test_*.py
       include:
         - "*/**/doctype/*"
 
diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml
index 389524e..e27b406 100644
--- a/.github/workflows/semgrep.yml
+++ b/.github/workflows/semgrep.yml
@@ -1,34 +1,18 @@
 name: Semgrep
 
 on:
-  pull_request:
-    branches:
-      - develop
-      - version-13-hotfix
-      - version-13-pre-release
+  pull_request: { }
+
 jobs:
   semgrep:
     name: Frappe Linter
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v2
-    - name: Setup python3
-      uses: actions/setup-python@v2
-      with:
-        python-version: 3.8
-
-    - name: Setup semgrep
-      run: |
-        python -m pip install -q semgrep
-        git fetch origin $GITHUB_BASE_REF:$GITHUB_BASE_REF -q
-
-    - name: Semgrep errors
-      run: |
-        files=$(git diff --name-only --diff-filter=d $GITHUB_BASE_REF)
-        [[ -d .github/helper/semgrep_rules ]] && semgrep --severity ERROR --config=.github/helper/semgrep_rules --quiet --error $files
-        semgrep --config="r/python.lang.correctness" --quiet --error $files
-
-    - name: Semgrep warnings
-      run: |
-        files=$(git diff --name-only --diff-filter=d $GITHUB_BASE_REF)
-        [[ -d .github/helper/semgrep_rules ]] && semgrep --severity WARNING --severity INFO --config=.github/helper/semgrep_rules --quiet $files
+      - uses: actions/checkout@v2
+      - uses: returntocorp/semgrep-action@v1
+        env:
+            SEMGREP_TIMEOUT: 120
+        with:
+            config: >-
+              r/python.lang.correctness
+              .github/helper/semgrep_rules
diff --git a/CODEOWNERS b/CODEOWNERS
index 7cf65a7..219b6bb 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -3,16 +3,33 @@
 # These owners will be the default owners for everything in
 # the repo. Unless a later match takes precedence,
 
-manufacturing/          @rohitwaghchaure @marination
-accounts/               @deepeshgarg007 @nextchamp-saqib
-loan_management/        @deepeshgarg007 @rohitwaghchaure
-pos*                    @nextchamp-saqib @rohitwaghchaure
-assets/                 @nextchamp-saqib @deepeshgarg007
-stock/                  @marination @rohitwaghchaure
-buying/                 @marination @deepeshgarg007
-hr/                     @Anurag810 @rohitwaghchaure
-projects/               @hrwX @nextchamp-saqib
-support/                @hrwX @marination
-healthcare/             @ruchamahabal @marination
-erpnext_integrations/   @Mangesh-Khairnar @nextchamp-saqib
-requirements.txt        @gavindsouza
+erpnext/accounts/               @nextchamp-saqib @deepeshgarg007
+erpnext/assets/                 @nextchamp-saqib @deepeshgarg007
+erpnext/erpnext_integrations/   @nextchamp-saqib
+erpnext/loan_management/        @nextchamp-saqib @deepeshgarg007
+erpnext/regional                @nextchamp-saqib @deepeshgarg007
+erpnext/selling                 @nextchamp-saqib @deepeshgarg007
+erpnext/support/                @nextchamp-saqib @deepeshgarg007
+pos*                            @nextchamp-saqib
+
+erpnext/buying/                 @marination @rohitwaghchaure @ankush
+erpnext/e_commerce/             @marination
+erpnext/maintenance/            @marination @rohitwaghchaure
+erpnext/manufacturing/          @marination @rohitwaghchaure @ankush
+erpnext/portal/                 @marination
+erpnext/quality_management/     @marination @rohitwaghchaure
+erpnext/shopping_cart/          @marination
+erpnext/stock/                  @marination @rohitwaghchaure @ankush
+
+erpnext/crm/                    @ruchamahabal
+erpnext/education/              @ruchamahabal
+erpnext/healthcare/             @ruchamahabal
+erpnext/hr/                     @ruchamahabal
+erpnext/non_profit/             @ruchamahabal
+erpnext/payroll                 @ruchamahabal
+erpnext/projects/               @ruchamahabal
+
+erpnext/controllers             @deepeshgarg007 @nextchamp-saqib @rohitwaghchaure @marination
+
+.github/                        @surajshetty3416 @ankush
+requirements.txt                @gavindsouza
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 0c96d32..1166549 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.6.0'
+__version__ = '13.7.0'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
index cb1f2df..4fd8413 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
@@ -16,7 +16,6 @@
 	def validate(self):
 		validate_accounts(self.import_file)
 
-
 @frappe.whitelist()
 def validate_company(company):
 	parent_company, allow_account_creation_against_child_company = frappe.db.get_value('Company',
@@ -304,9 +303,8 @@
 			accounts_dict[account["parent_account"]]["is_group"] = 1
 
 	validate_root(accounts_dict)
-	
+
 	validate_account_types(accounts_dict)
-	
 
 	return [True, len(accounts)]
 
diff --git a/erpnext/accounts/doctype/dunning/test_dunning.py b/erpnext/accounts/doctype/dunning/test_dunning.py
index 31cb078..7fc2e4b 100644
--- a/erpnext/accounts/doctype/dunning/test_dunning.py
+++ b/erpnext/accounts/doctype/dunning/test_dunning.py
@@ -139,8 +139,8 @@
 	dunning_type.append(
 		"dunning_letter_text", {
 			'language': 'en',
-			'body_text': 'We have still not received payment for our invoice ',
+			'body_text': 'We have still not received payment for our invoice ',
 			'closing_text': 'We kindly request that you pay the outstanding amount immediately, and late fees.'
 		}
 	)
-	dunning_type.save()
\ No newline at end of file
+	dunning_type.save() 
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
index 51f18a5..6f362c1 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.json
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -667,6 +667,7 @@
   {
    "fieldname": "base_paid_amount_after_tax",
    "fieldtype": "Currency",
+   "hidden": 1,
    "label": "Paid Amount After Tax (Company Currency)",
    "options": "Company:company:default_currency",
    "read_only": 1
@@ -693,21 +694,25 @@
    "depends_on": "eval:doc.received_amount && doc.payment_type != 'Internal Transfer'",
    "fieldname": "received_amount_after_tax",
    "fieldtype": "Currency",
+   "hidden": 1,
    "label": "Received Amount After Tax",
-   "options": "paid_to_account_currency"
+   "options": "paid_to_account_currency",
+   "read_only": 1
   },
   {
    "depends_on": "doc.received_amount",
    "fieldname": "base_received_amount_after_tax",
    "fieldtype": "Currency",
+   "hidden": 1,
    "label": "Received Amount After Tax (Company Currency)",
-   "options": "Company:company:default_currency"
+   "options": "Company:company:default_currency",
+   "read_only": 1
   }
  ],
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-06-22 20:37:06.154206",
+ "modified": "2021-07-09 08:58:15.008761",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Entry",
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index ff00fde..46904f7 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -411,9 +411,15 @@
 		if not self.advance_tax_account:
 			frappe.throw(_("Advance TDS account is mandatory for advance TDS deduction"))
 
-		reference_doclist = []
 		net_total = self.paid_amount
-		included_in_paid_amount = 0
+
+		for reference in self.get("references"):
+			net_total_for_tds = 0
+			if reference.reference_doctype == 'Purchase Order':
+				net_total_for_tds += flt(frappe.db.get_value('Purchase Order', reference.reference_name, 'net_total'))
+		
+			if net_total_for_tds:
+				net_total = net_total_for_tds
 
 		# Adding args as purchase invoice to get TDS amount
 		args = frappe._dict({
@@ -430,7 +436,7 @@
 			return
 
 		tax_withholding_details.update({
-			'included_in_paid_amount': included_in_paid_amount,
+			'add_deduct_tax': 'Add',
 			'cost_center': self.cost_center or erpnext.get_default_cost_center(self.company)
 		})
 
@@ -519,16 +525,19 @@
 		self.unallocated_amount = 0
 		if self.party:
 			total_deductions = sum(flt(d.amount) for d in self.get("deductions"))
+			included_taxes = self.get_included_taxes()
 			if self.payment_type == "Receive" \
-				and self.base_total_allocated_amount < self.base_received_amount_after_tax + total_deductions \
-				and self.total_allocated_amount < self.paid_amount_after_tax + (total_deductions / self.source_exchange_rate):
-				self.unallocated_amount = (self.received_amount_after_tax + total_deductions -
+				and self.base_total_allocated_amount < self.base_received_amount + total_deductions \
+				and self.total_allocated_amount < self.paid_amount + (total_deductions / self.source_exchange_rate):
+				self.unallocated_amount = (self.received_amount + total_deductions -
 					self.base_total_allocated_amount) / self.source_exchange_rate
+				self.unallocated_amount -= included_taxes
 			elif self.payment_type == "Pay" \
-				and self.base_total_allocated_amount < (self.base_paid_amount_after_tax - total_deductions) \
-				and self.total_allocated_amount < self.received_amount_after_tax + (total_deductions / self.target_exchange_rate):
-				self.unallocated_amount = (self.base_paid_amount_after_tax - (total_deductions +
+				and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions) \
+				and self.total_allocated_amount < self.received_amount + (total_deductions / self.target_exchange_rate):
+				self.unallocated_amount = (self.base_paid_amount - (total_deductions +
 					self.base_total_allocated_amount)) / self.target_exchange_rate
+				self.unallocated_amount -= included_taxes
 
 	def set_difference_amount(self):
 		base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
@@ -537,17 +546,29 @@
 		base_party_amount = flt(self.base_total_allocated_amount) + flt(base_unallocated_amount)
 
 		if self.payment_type == "Receive":
-			self.difference_amount = base_party_amount - self.base_received_amount_after_tax
+			self.difference_amount = base_party_amount - self.base_received_amount
 		elif self.payment_type == "Pay":
-			self.difference_amount = self.base_paid_amount_after_tax - base_party_amount
+			self.difference_amount = self.base_paid_amount - base_party_amount
 		else:
-			self.difference_amount = self.base_paid_amount_after_tax - flt(self.base_received_amount_after_tax)
+			self.difference_amount = self.base_paid_amount - flt(self.base_received_amount)
 
 		total_deductions = sum(flt(d.amount) for d in self.get("deductions"))
+		included_taxes = self.get_included_taxes()
 
-		self.difference_amount = flt(self.difference_amount - total_deductions,
+		self.difference_amount = flt(self.difference_amount - total_deductions - included_taxes,
 			self.precision("difference_amount"))
 
+	def get_included_taxes(self):
+		included_taxes = 0
+		for tax in self.get('taxes'):
+			if tax.included_in_paid_amount:
+				if tax.add_deduct_tax == 'Add':
+					included_taxes += tax.base_tax_amount
+				else:
+					included_taxes -= tax.base_tax_amount
+
+		return included_taxes
+
 	# Paid amount is auto allocated in the reference document by default.
 	# Clear the reference document which doesn't have allocated amount on validate so that form can be loaded fast
 	def clear_unallocated_reference_document_rows(self):
@@ -690,8 +711,8 @@
 					"account": self.paid_from,
 					"account_currency": self.paid_from_account_currency,
 					"against": self.party if self.payment_type=="Pay" else self.paid_to,
-					"credit_in_account_currency": self.paid_amount_after_tax,
-					"credit": self.base_paid_amount_after_tax,
+					"credit_in_account_currency": self.paid_amount,
+					"credit": self.base_paid_amount,
 					"cost_center": self.cost_center
 				}, item=self)
 			)
@@ -701,8 +722,8 @@
 					"account": self.paid_to,
 					"account_currency": self.paid_to_account_currency,
 					"against": self.party if self.payment_type=="Receive" else self.paid_from,
-					"debit_in_account_currency": self.received_amount_after_tax,
-					"debit": self.base_received_amount_after_tax,
+					"debit_in_account_currency": self.received_amount,
+					"debit": self.base_received_amount,
 					"cost_center": self.cost_center
 				}, item=self)
 			)
@@ -715,35 +736,42 @@
 
 			if self.payment_type in ('Pay', 'Internal Transfer'):
 				dr_or_cr = "debit" if d.add_deduct_tax == "Add" else "credit"
+				against = self.party or self.paid_from
 			elif self.payment_type == 'Receive':
 				dr_or_cr = "credit" if d.add_deduct_tax == "Add" else "debit"
+				against = self.party or self.paid_to
 
 			payment_or_advance_account = self.get_party_account_for_taxes()
+			tax_amount = d.tax_amount
+			base_tax_amount = d.base_tax_amount
+
+			if self.advance_tax_account:
+				tax_amount = -1 * tax_amount
+				base_tax_amount = -1 * base_tax_amount
 
 			gl_entries.append(
 				self.get_gl_dict({
 					"account": d.account_head,
-					"against": self.party if self.payment_type=="Receive" else self.paid_from,
-					dr_or_cr: d.base_tax_amount,
-					dr_or_cr + "_in_account_currency": d.base_tax_amount
+					"against": against,
+					dr_or_cr: tax_amount,
+					dr_or_cr + "_in_account_currency": base_tax_amount
 					if account_currency==self.company_currency
 					else d.tax_amount,
 					"cost_center": d.cost_center
 				}, account_currency, item=d))
 
 			#Intentionally use -1 to get net values in party account
-			gl_entries.append(
-				self.get_gl_dict({
-					"account": payment_or_advance_account,
-					"against": self.party if self.payment_type=="Receive" else self.paid_from,
-					dr_or_cr: -1 * d.base_tax_amount,
-					dr_or_cr + "_in_account_currency": -1*d.base_tax_amount
-					if account_currency==self.company_currency
-					else d.tax_amount,
-					"cost_center": self.cost_center,
-					"party_type": self.party_type,
-					"party": self.party
-				}, account_currency, item=d))
+			if not d.included_in_paid_amount or self.advance_tax_account:
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": payment_or_advance_account,
+						"against": against,
+						dr_or_cr: -1 * tax_amount,
+						dr_or_cr + "_in_account_currency": -1 * base_tax_amount
+						if account_currency==self.company_currency
+						else d.tax_amount,
+						"cost_center": self.cost_center,
+					}, account_currency, item=d))
 
 	def add_deductions_gl_entries(self, gl_entries):
 		for d in self.get("deductions"):
@@ -767,9 +795,9 @@
 		if self.advance_tax_account:
 			return self.advance_tax_account
 		elif self.payment_type == 'Receive':
-			return self.paid_from
-		elif self.payment_type in ('Pay', 'Internal Transfer'):
 			return self.paid_to
+		elif self.payment_type in ('Pay', 'Internal Transfer'):
+			return self.paid_from
 
 	def update_advance_paid(self):
 		if self.payment_type in ("Receive", "Pay") and self.party:
@@ -1648,12 +1676,6 @@
 			if dt == "Employee Advance":
 				paid_amount = received_amount * doc.get('exchange_rate', 1)
 
-	if dt == "Purchase Order" and doc.apply_tds:
-		if party_account_currency == bank.account_currency:
-			paid_amount = received_amount = doc.base_net_total
-		else:
-			paid_amount = received_amount = doc.base_net_total * doc.get('exchange_rate', 1)
-
 	return paid_amount, received_amount
 
 def apply_early_payment_discount(paid_amount, received_amount, doc):
diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.js b/erpnext/accounts/doctype/tax_rule/tax_rule.js
index 370890e..bc49716 100644
--- a/erpnext/accounts/doctype/tax_rule/tax_rule.js
+++ b/erpnext/accounts/doctype/tax_rule/tax_rule.js
@@ -1,24 +1,6 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-cur_frm.add_fetch("customer", "customer_group", "customer_group" );
-cur_frm.add_fetch("supplier", "supplier_group_name", "supplier_group" );
-
-frappe.ui.form.on("Tax Rule", "tax_type", function(frm) {
-	frm.toggle_reqd("sales_tax_template", frm.doc.tax_type=="Sales");
-	frm.toggle_reqd("purchase_tax_template", frm.doc.tax_type=="Purchase");
-})
-
-frappe.ui.form.on("Tax Rule", "onload", function(frm) {
-	if(frm.doc.__islocal) {
-		frm.set_value("use_for_shopping_cart", 1);
-	}
-})
-
-frappe.ui.form.on("Tax Rule", "refresh", function(frm) {
-	frappe.ui.form.trigger("Tax Rule", "tax_type");
-})
-
 frappe.ui.form.on("Tax Rule", "customer", function(frm) {
 	if(frm.doc.customer) {
 		frappe.call({
diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.json b/erpnext/accounts/doctype/tax_rule/tax_rule.json
index ef15538..2746748 100644
--- a/erpnext/accounts/doctype/tax_rule/tax_rule.json
+++ b/erpnext/accounts/doctype/tax_rule/tax_rule.json
@@ -1,1103 +1,250 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 0, 
- "autoname": "ACC-TAX-RULE-.YYYY.-.#####", 
- "beta": 0, 
- "creation": "2015-08-07 02:33:52.670866", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Setup", 
- "editable_grid": 0, 
+ "actions": [],
+ "allow_import": 1,
+ "autoname": "ACC-TAX-RULE-.YYYY.-.#####",
+ "creation": "2015-08-07 02:33:52.670866",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "engine": "InnoDB",
+ "field_order": [
+  "tax_type",
+  "use_for_shopping_cart",
+  "column_break_1",
+  "sales_tax_template",
+  "purchase_tax_template",
+  "filters",
+  "customer",
+  "supplier",
+  "item",
+  "billing_city",
+  "billing_county",
+  "billing_state",
+  "billing_zipcode",
+  "billing_country",
+  "tax_category",
+  "column_break_2",
+  "customer_group",
+  "supplier_group",
+  "item_group",
+  "shipping_city",
+  "shipping_county",
+  "shipping_state",
+  "shipping_zipcode",
+  "shipping_country",
+  "section_break_4",
+  "from_date",
+  "column_break_7",
+  "to_date",
+  "section_break_6",
+  "priority",
+  "column_break_20",
+  "company"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "Sales", 
-   "fieldname": "tax_type", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 1, 
-   "label": "Tax Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Sales\nPurchase", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "default": "Sales",
+   "fieldname": "tax_type",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Tax Type",
+   "options": "Sales\nPurchase"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "use_for_shopping_cart", 
-   "fieldtype": "Check", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Use for Shopping Cart", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "default": "1",
+   "fieldname": "use_for_shopping_cart",
+   "fieldtype": "Check",
+   "label": "Use for Shopping Cart"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_1", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_1",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.tax_type==\"Sales\"", 
-   "fieldname": "sales_tax_template", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Sales Tax Template", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Sales Taxes and Charges Template", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.tax_type==\"Sales\"",
+   "fieldname": "sales_tax_template",
+   "fieldtype": "Link",
+   "label": "Sales Tax Template",
+   "options": "Sales Taxes and Charges Template"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.tax_type==\"Purchase\"", 
-   "fieldname": "purchase_tax_template", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Purchase Tax Template", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Purchase Taxes and Charges Template", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.tax_type==\"Purchase\"",
+   "fieldname": "purchase_tax_template",
+   "fieldtype": "Link",
+   "label": "Purchase Tax Template",
+   "options": "Purchase Taxes and Charges Template"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "filters", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Filters", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "filters",
+   "fieldtype": "Section Break",
+   "label": "Filters"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.tax_type==\"Sales\"", 
-   "fieldname": "customer", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Customer", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Customer", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.tax_type==\"Sales\"",
+   "fieldname": "customer",
+   "fieldtype": "Link",
+   "label": "Customer",
+   "options": "Customer"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.tax_type==\"Purchase\"", 
-   "fieldname": "supplier", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Supplier", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Supplier", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.tax_type==\"Purchase\"",
+   "fieldname": "supplier",
+   "fieldtype": "Link",
+   "label": "Supplier",
+   "options": "Supplier"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "item", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Item", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Item", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "item",
+   "fieldtype": "Link",
+   "label": "Item",
+   "options": "Item"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "billing_city", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Billing City", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "billing_city",
+   "fieldtype": "Data",
+   "label": "Billing City"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "billing_county", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Billing County", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "billing_county",
+   "fieldtype": "Data",
+   "label": "Billing County"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "billing_state", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Billing State", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "billing_state",
+   "fieldtype": "Data",
+   "label": "Billing State"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "billing_zipcode", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Billing Zipcode", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "billing_zipcode",
+   "fieldtype": "Data",
+   "label": "Billing Zipcode"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "billing_country", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Billing Country", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Country", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "billing_country",
+   "fieldtype": "Link",
+   "label": "Billing Country",
+   "options": "Country"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "tax_category", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Tax Category", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Tax Category", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "tax_category",
+   "fieldtype": "Link",
+   "label": "Tax Category",
+   "options": "Tax Category"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_2", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_2",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.tax_type==\"Sales\"", 
-   "fieldname": "customer_group", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Customer Group", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Customer Group", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.tax_type==\"Sales\"",
+   "fetch_from": "customer.customer_group",
+   "fieldname": "customer_group",
+   "fieldtype": "Link",
+   "label": "Customer Group",
+   "options": "Customer Group"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.tax_type==\"Purchase\"", 
-   "fieldname": "supplier_group", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Supplier Group", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Supplier Group", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.tax_type==\"Purchase\"",
+   "fetch_from": "supplier.supplier_group",
+   "fieldname": "supplier_group",
+   "fieldtype": "Link",
+   "label": "Supplier Group",
+   "options": "Supplier Group"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "item_group", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Item Group", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Item Group", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "item_group",
+   "fieldtype": "Link",
+   "label": "Item Group",
+   "options": "Item Group"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "shipping_city", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Shipping City", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "shipping_city",
+   "fieldtype": "Data",
+   "label": "Shipping City"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "shipping_county", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Shipping County", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "shipping_county",
+   "fieldtype": "Data",
+   "label": "Shipping County"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "shipping_state", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Shipping State", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "shipping_state",
+   "fieldtype": "Data",
+   "label": "Shipping State"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "shipping_zipcode", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Shipping Zipcode", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "shipping_zipcode",
+   "fieldtype": "Data",
+   "label": "Shipping Zipcode"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "shipping_country", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Shipping Country", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Country", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "shipping_country",
+   "fieldtype": "Link",
+   "label": "Shipping Country",
+   "options": "Country"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_4", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Validity", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_4",
+   "fieldtype": "Section Break",
+   "label": "Validity"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "from_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "From Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "from_date",
+   "fieldtype": "Date",
+   "label": "From Date"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_7", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_7",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "to_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "To Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "to_date",
+   "fieldtype": "Date",
+   "label": "To Date"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_6", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_6",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "1", 
-   "fieldname": "priority", 
-   "fieldtype": "Int", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Priority", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "default": "1",
+   "fieldname": "priority",
+   "fieldtype": "Int",
+   "label": "Priority"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_20", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_20",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "company", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Company", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "label": "Company",
+   "options": "Company",
+   "remember_last_selected_value": 1
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-12-27 01:22:17.721636", 
- "modified_by": "Administrator", 
- "module": "Accounts", 
- "name": "Tax Rule", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "links": [],
+ "modified": "2021-06-04 23:14:27.186879",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Tax Rule",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Accounts Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts Manager",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 1, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 0, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC"
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/tax_rule/test_tax_rule.py b/erpnext/accounts/doctype/tax_rule/test_tax_rule.py
index ac1ffd9..cf72268 100644
--- a/erpnext/accounts/doctype/tax_rule/test_tax_rule.py
+++ b/erpnext/accounts/doctype/tax_rule/test_tax_rule.py
@@ -50,7 +50,7 @@
 		tax_rule1 = make_tax_rule(customer_group= "All Customer Groups",
 			sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-01")
 		tax_rule1.save()
-		self.assertEqual(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}),
+		self.assertEqual(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":1}),
 			"_Test Sales Taxes and Charges Template - _TC")
 
 	def test_conflict_with_overlapping_dates(self):
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index 1dbd7c6..132dd17 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -97,6 +97,9 @@
   "is_fixed_asset",
   "item_tax_rate",
   "section_break_72",
+  "production_plan",
+  "production_plan_item",
+  "production_plan_sub_assembly_item",
   "page_break"
  ],
  "fields": [
@@ -803,13 +806,37 @@
    "options": "Company:company:default_currency",
    "print_hide": 1,
    "read_only": 1
+  },
+  {
+   "fieldname": "production_plan",
+   "fieldtype": "Link",
+   "label": "Production Plan",
+   "options": "Production Plan",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "production_plan_item",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Production Plan Item",
+   "no_copy": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "production_plan_sub_assembly_item",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Production Plan Sub Assembly Item",
+   "no_copy": 1,
+   "read_only": 1
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-03-22 11:46:12.357435",
+ "modified": "2021-06-28 19:22:22.715365",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order Item",
diff --git a/erpnext/change_log/v13/v13_7_0.md b/erpnext/change_log/v13/v13_7_0.md
new file mode 100644
index 0000000..589f610
--- /dev/null
+++ b/erpnext/change_log/v13/v13_7_0.md
@@ -0,0 +1,69 @@
+# Version 13.7.0 Release Notes
+
+### Features & Enhancements
+- Optionally allow rejected quality inspection on submission ([#26133](https://github.com/frappe/erpnext/pull/26133))
+- Bootstrapped GST Setup for India ([#25415](https://github.com/frappe/erpnext/pull/25415))
+- Fetching details from supplier/customer groups ([#26454](https://github.com/frappe/erpnext/pull/26454))
+- Provision to make subcontracted purchase order from the production plan ([#26240](https://github.com/frappe/erpnext/pull/26240))
+- Optimized code for reposting item valuation ([#26432](https://github.com/frappe/erpnext/pull/26432))
+
+### Fixes
+- Auto process deferred accounting for multi-company setup ([#26277](https://github.com/frappe/erpnext/pull/26277))
+- Error while fetching item taxes ([#26218](https://github.com/frappe/erpnext/pull/26218))
+- Validation check for batch for stock reconciliation type in stock entry(bp #26370 ) ([#26488](https://github.com/frappe/erpnext/pull/26488))
+- Error popup for COA errors ([#26358](https://github.com/frappe/erpnext/pull/26358))
+- Precision for expected values in payment entry test ([#26394](https://github.com/frappe/erpnext/pull/26394))
+- Bank statement import ([#26287](https://github.com/frappe/erpnext/pull/26287))
+- LMS progress issue ([#26253](https://github.com/frappe/erpnext/pull/26253))
+- Paging buttons not working on item group portal page ([#26497](https://github.com/frappe/erpnext/pull/26497))
+- Omit item discount amount for e-invoicing ([#26353](https://github.com/frappe/erpnext/pull/26353))
+- Validate LCV for Invoices without Update Stock ([#26333](https://github.com/frappe/erpnext/pull/26333))
+- Remove cancelled entries in consolidated financial statements ([#26331](https://github.com/frappe/erpnext/pull/26331))
+- Fetching employee in payroll entry ([#26271](https://github.com/frappe/erpnext/pull/26271))
+- To fetch the correct field in Tax Rule ([#25927](https://github.com/frappe/erpnext/pull/25927))
+- Order and time of operations in multilevel BOM work order ([#25886](https://github.com/frappe/erpnext/pull/25886))
+- Fixed Budget Variance Graph color from all black to default ([#26368](https://github.com/frappe/erpnext/pull/26368))
+- TDS computation summary shows cancelled invoices (#26456) ([#26486](https://github.com/frappe/erpnext/pull/26486))
+- Do not consider cancelled entries in party dashboard ([#26231](https://github.com/frappe/erpnext/pull/26231))
+- Add validation for 'for_qty' else throws errors ([#25829](https://github.com/frappe/erpnext/pull/25829))
+- Move the rename abbreviation job to long queue (#26434) ([#26462](https://github.com/frappe/erpnext/pull/26462))
+- Query for Training Event ([#26388](https://github.com/frappe/erpnext/pull/26388))
+- Item group portal issues (backport) ([#26493](https://github.com/frappe/erpnext/pull/26493))
+- When lead is created with mobile_no, mobile_no value gets lost ([#26298](https://github.com/frappe/erpnext/pull/26298))
+- WIP needs to be set before submit on skip_transfer (bp #26499) ([#26507](https://github.com/frappe/erpnext/pull/26507))
+- Incorrect valuation rate in stock reconciliation ([#26259](https://github.com/frappe/erpnext/pull/26259))
+- Precision rate for packed items in internal transfers ([#26046](https://github.com/frappe/erpnext/pull/26046))
+- Changed profitability analysis report width ([#26165](https://github.com/frappe/erpnext/pull/26165))
+- Unable to download GSTR-1 json ([#26468](https://github.com/frappe/erpnext/pull/26468))
+- Unallocated amount in Payment Entry after taxes ([#26472](https://github.com/frappe/erpnext/pull/26472))
+- Include Stock Reco logic in `update_qty_in_future_sle` ([#26158](https://github.com/frappe/erpnext/pull/26158))
+- Update cost not working in the draft BOM ([#26279](https://github.com/frappe/erpnext/pull/26279))
+- Cancellation of Loan Security Pledges ([#26252](https://github.com/frappe/erpnext/pull/26252))
+- fix(e-invoicing): allow export invoice even if no taxes applied (#26363) ([#26405](https://github.com/frappe/erpnext/pull/26405))
+- Delete accounts (an empty file) ([#25323](https://github.com/frappe/erpnext/pull/25323))
+- Errors on parallel requests creation of company for India  ([#26470](https://github.com/frappe/erpnext/pull/26470))
+- Incorrect bom no added for non-variant items on variant boms ([#26320](https://github.com/frappe/erpnext/pull/26320))
+- Incorrect discount amount on amended document ([#26466](https://github.com/frappe/erpnext/pull/26466))
+- Added a message to enable appointment booking if disabled ([#26334](https://github.com/frappe/erpnext/pull/26334))
+- fix(pos): taxes amount in pos item cart ([#26411](https://github.com/frappe/erpnext/pull/26411))
+- Track changes on batch ([#26382](https://github.com/frappe/erpnext/pull/26382))
+- Stock entry with putaway rule not working ([#26350](https://github.com/frappe/erpnext/pull/26350))
+- Only "Tax" type accounts should be shown for selection in GST Settings ([#26300](https://github.com/frappe/erpnext/pull/26300))
+- Added permission for employee to book appointment ([#26255](https://github.com/frappe/erpnext/pull/26255))
+- Allow to make job card without employee ([#26312](https://github.com/frappe/erpnext/pull/26312))
+- Project Portal Enhancements ([#26290](https://github.com/frappe/erpnext/pull/26290))
+- BOM stock report not working ([#26332](https://github.com/frappe/erpnext/pull/26332))
+- Order Items by weightage in the web items query ([#26284](https://github.com/frappe/erpnext/pull/26284))
+- Removed values out of sync validation from stock transactions ([#26226](https://github.com/frappe/erpnext/pull/26226))
+- Payroll-entry minor fix ([#26349](https://github.com/frappe/erpnext/pull/26349))
+- Allow user to change the To Date in the blanket order even after submit of order ([#26241](https://github.com/frappe/erpnext/pull/26241))
+- Value fetching for custom field in POS ([#26367](https://github.com/frappe/erpnext/pull/26367))
+- Iteration through accounts only when accounts exist ([#26391](https://github.com/frappe/erpnext/pull/26391))
+- Employee Inactive status implications ([#26244](https://github.com/frappe/erpnext/pull/26244))
+- Multi-currency issue ([#26458](https://github.com/frappe/erpnext/pull/26458))
+- FG item not fetched in manufacture entry ([#26509](https://github.com/frappe/erpnext/pull/26509))
+- Set query for training events ([#26303](https://github.com/frappe/erpnext/pull/26303))
+- Fetch batch items in stock reconciliation ([#26213](https://github.com/frappe/erpnext/pull/26213))
+- Employee selection not working in payroll entry ([#26278](https://github.com/frappe/erpnext/pull/26278))
+- POS item cart dom updates (#26459) ([#26461](https://github.com/frappe/erpnext/pull/26461))
+- dunning calculation of grand total when rate of interest is 0% ([#26285](https://github.com/frappe/erpnext/pull/26285))
\ No newline at end of file
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index a9860ed..4c313c4 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -818,11 +818,11 @@
 					account_currency = get_account_currency(tax.account_head)
 
 					if self.doctype == "Purchase Invoice":
-						dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
-						rev_dr_cr = "debit" if tax.add_deduct_tax == "Add" else "credit"
-					else:
 						dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit"
 						rev_dr_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
+					else:
+						dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
+						rev_dr_cr = "debit" if tax.add_deduct_tax == "Add" else "credit"
 
 					party = self.supplier if self.doctype == "Purchase Invoice" else self.customer
 					unallocated_amount = tax.tax_amount - tax.allocated_amount
diff --git a/erpnext/crm/doctype/appointment/appointment.json b/erpnext/crm/doctype/appointment/appointment.json
index 016b8ec..fe7b4e1 100644
--- a/erpnext/crm/doctype/appointment/appointment.json
+++ b/erpnext/crm/doctype/appointment/appointment.json
@@ -102,7 +102,7 @@
   }
  ],
  "links": [],
- "modified": "2021-06-30 12:09:14.228756",
+ "modified": "2021-06-30 13:09:14.228756",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Appointment",
diff --git a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.json b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.json
index 18bd4ae..68bac8e 100644
--- a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.json
+++ b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.json
@@ -35,7 +35,9 @@
    "no_copy": 1,
    "options": "Loan Security Pledge",
    "print_hide": 1,
-   "read_only": 1
+   "read_only": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fetch_from": "loan_application.applicant",
@@ -45,47 +47,63 @@
    "in_standard_filter": 1,
    "label": "Applicant",
    "options": "applicant_type",
-   "reqd": 1
+   "reqd": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "loan_security_details_section",
    "fieldtype": "Section Break",
-   "label": "Loan Security Details"
+   "label": "Loan Security Details",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "column_break_3",
-   "fieldtype": "Column Break"
+   "fieldtype": "Column Break",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "loan",
    "fieldtype": "Link",
    "label": "Loan",
-   "options": "Loan"
+   "options": "Loan",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "loan_application",
    "fieldtype": "Link",
    "label": "Loan Application",
-   "options": "Loan Application"
+   "options": "Loan Application",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "total_security_value",
    "fieldtype": "Currency",
    "label": "Total Security Value",
    "options": "Company:company:default_currency",
-   "read_only": 1
+   "read_only": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "maximum_loan_value",
    "fieldtype": "Currency",
    "label": "Maximum Loan Value",
    "options": "Company:company:default_currency",
-   "read_only": 1
+   "read_only": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "loan_details_section",
    "fieldtype": "Section Break",
-   "label": "Loan  Details"
+   "label": "Loan  Details",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "default": "Requested",
@@ -94,37 +112,49 @@
    "in_list_view": 1,
    "in_standard_filter": 1,
    "label": "Status",
-   "options": "Requested\nUnpledged\nPledged\nPartially Pledged",
-   "read_only": 1
+   "options": "Requested\nUnpledged\nPledged\nPartially Pledged\nCancelled",
+   "read_only": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "pledge_time",
    "fieldtype": "Datetime",
    "label": "Pledge Time",
-   "read_only": 1
+   "read_only": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "securities",
    "fieldtype": "Table",
    "label": "Securities",
    "options": "Pledge",
-   "reqd": 1
+   "reqd": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "column_break_11",
-   "fieldtype": "Column Break"
+   "fieldtype": "Column Break",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "section_break_10",
    "fieldtype": "Section Break",
-   "label": "Totals"
+   "label": "Totals",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "company",
    "fieldtype": "Link",
    "label": "Company",
    "options": "Company",
-   "reqd": 1
+   "reqd": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fetch_from": "loan.applicant_type",
@@ -132,35 +162,45 @@
    "fieldtype": "Select",
    "label": "Applicant Type",
    "options": "Employee\nMember\nCustomer",
-   "reqd": 1
+   "reqd": 1,
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "collapsible": 1,
    "fieldname": "more_information_section",
    "fieldtype": "Section Break",
-   "label": "More Information"
+   "label": "More Information",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "allow_on_submit": 1,
    "fieldname": "reference_no",
    "fieldtype": "Data",
-   "label": "Reference No"
+   "label": "Reference No",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "fieldname": "column_break_18",
-   "fieldtype": "Column Break"
+   "fieldtype": "Column Break",
+   "show_days": 1,
+   "show_seconds": 1
   },
   {
    "allow_on_submit": 1,
    "fieldname": "description",
    "fieldtype": "Text",
-   "label": "Description"
+   "label": "Description",
+   "show_days": 1,
+   "show_seconds": 1
   }
  ],
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-04-19 18:23:16.953305",
+ "modified": "2021-06-29 17:15:16.082256",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Loan Security Pledge",
diff --git a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py
index cbc8376..c390b6c 100644
--- a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py
+++ b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py
@@ -23,6 +23,12 @@
 			update_shortfall_status(self.loan, self.total_security_value)
 			update_loan(self.loan, self.maximum_loan_value)
 
+	def on_cancel(self):
+		if self.loan:
+			self.db_set("status", "Cancelled")
+			self.db_set("pledge_time", None)
+			update_loan(self.loan, self.maximum_loan_value, cancel=1)
+
 	def validate_duplicate_securities(self):
 		security_list = []
 		for security in self.securities:
@@ -36,7 +42,7 @@
 		existing_pledge = ''
 
 		if self.loan:
-			existing_pledge = frappe.db.get_value('Loan Security Pledge', {'loan': self.loan}, ['name'])
+			existing_pledge = frappe.db.get_value('Loan Security Pledge', {'loan': self.loan, 'docstatus': 1}, ['name'])
 
 		if existing_pledge:
 			loan_security_type = frappe.db.get_value('Pledge', {'parent': existing_pledge}, ['loan_security_type'])
@@ -77,8 +83,12 @@
 		self.total_security_value = total_security_value
 		self.maximum_loan_value = maximum_loan_value
 
-def update_loan(loan, maximum_value_against_pledge):
+def update_loan(loan, maximum_value_against_pledge, cancel=0):
 	maximum_loan_value = frappe.db.get_value('Loan', {'name': loan}, ['maximum_loan_amount'])
 
-	frappe.db.sql(""" UPDATE `tabLoan` SET maximum_loan_amount=%s, is_secured_loan=1
-		WHERE name=%s""", (maximum_loan_value + maximum_value_against_pledge, loan))
+	if cancel:
+		frappe.db.sql(""" UPDATE `tabLoan` SET maximum_loan_amount=%s
+			WHERE name=%s""", (maximum_loan_value - maximum_value_against_pledge, loan))
+	else:
+		frappe.db.sql(""" UPDATE `tabLoan` SET maximum_loan_amount=%s, is_secured_loan=1
+			WHERE name=%s""", (maximum_loan_value + maximum_value_against_pledge, loan))
diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.js b/erpnext/manufacturing/doctype/blanket_order/blanket_order.js
index 4c31bd0..f19a1b0 100644
--- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.js
+++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.js
@@ -13,7 +13,7 @@
 
 	refresh: function(frm) {
 		erpnext.hide_company();
-		if (frm.doc.customer && frm.doc.docstatus === 1) {
+		if (frm.doc.customer && frm.doc.docstatus === 1 && frm.doc.to_date > frappe.datetime.get_today()) {
 			frm.add_custom_button(__("Sales Order"), function() {
 				frappe.model.open_mapped_doc({
 					method: "erpnext.manufacturing.doctype.blanket_order.blanket_order.make_order",
diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.json b/erpnext/manufacturing/doctype/blanket_order/blanket_order.json
index 0330e5c..a63fc4d 100644
--- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.json
+++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "autoname": "naming_series:",
  "creation": "2018-05-24 07:18:08.256060",
  "doctype": "DocType",
@@ -79,6 +80,7 @@
    "reqd": 1
   },
   {
+   "allow_on_submit": 1,
    "fieldname": "to_date",
    "fieldtype": "Date",
    "label": "To Date",
@@ -129,8 +131,10 @@
    "label": "Terms and Conditions Details"
   }
  ],
+ "index_web_pages_for_search": 1,
  "is_submittable": 1,
- "modified": "2019-11-18 19:37:37.151686",
+ "links": [],
+ "modified": "2021-06-29 00:30:30.621636",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Blanket Order",
diff --git a/erpnext/manufacturing/doctype/bom/bom.json b/erpnext/manufacturing/doctype/bom/bom.json
index f38d1b9..7e53918 100644
--- a/erpnext/manufacturing/doctype/bom/bom.json
+++ b/erpnext/manufacturing/doctype/bom/bom.json
@@ -36,6 +36,9 @@
   "materials_section",
   "inspection_required",
   "quality_inspection_template",
+  "column_break_31",
+  "bom_level",
+  "section_break_33",
   "items",
   "scrap_section",
   "scrap_items",
@@ -513,6 +516,22 @@
    "no_copy": 1,
    "print_hide": 1,
    "read_only": 1
+  },
+  {
+   "fieldname": "column_break_31",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "fieldname": "bom_level",
+   "fieldtype": "Int",
+   "label": "BOM Level",
+   "read_only": 1
+  },
+  {
+   "fieldname": "section_break_33",
+   "fieldtype": "Section Break",
+   "hide_border": 1
   }
  ],
  "icon": "fa fa-sitemap",
@@ -520,7 +539,7 @@
  "image_field": "image",
  "is_submittable": 1,
  "links": [],
- "modified": "2021-03-16 12:25:09.081968",
+ "modified": "2021-05-16 12:25:09.081968",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "BOM",
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 3bd1fe6..9da461f 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -154,6 +154,7 @@
 		self.calculate_cost()
 		self.update_stock_qty()
 		self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate = False, save=False)
+		self.set_bom_level()
 
 	def get_context(self, context):
 		context.parents = [{'name': 'boms', 'title': _('All BOMs') }]
@@ -676,6 +677,19 @@
 		"""Get a complete tree representation preserving order of child items."""
 		return BOMTree(self.name)
 
+	def set_bom_level(self, update=False):
+		levels = []
+
+		self.bom_level = 0
+		for row in self.items:
+			if row.bom_no:
+				levels.append(frappe.get_cached_value("BOM", row.bom_no, "bom_level") or 0)
+
+		if levels:
+			self.bom_level = max(levels) + 1
+
+		if update:
+			self.db_set("bom_level", self.bom_level)
 
 def get_bom_item_rate(args, bom_doc):
 	if bom_doc.rm_cost_as_per == 'Valuation Rate':
@@ -699,7 +713,8 @@
 			"conversion_rate": 1, # Passed conversion rate as 1 purposefully, as conversion rate is applied at the end of the function
 			"conversion_factor": args.get("conversion_factor") or 1,
 			"plc_conversion_rate": 1,
-			"ignore_party": True
+			"ignore_party": True,
+			"ignore_conversion_rate": True
 		})
 		item_doc = frappe.get_cached_doc("Item", args.get("item_code"))
 		out = frappe._dict()
@@ -860,7 +875,7 @@
 		frappe.form_dict.parent = parent
 
 	if frappe.form_dict.parent:
-		bom_doc = frappe.get_doc("BOM", frappe.form_dict.parent)
+		bom_doc = frappe.get_cached_doc("BOM", frappe.form_dict.parent)
 		frappe.has_permission("BOM", doc=bom_doc, throw=True)
 
 		bom_items = frappe.get_all('BOM Item',
@@ -871,7 +886,7 @@
 		item_names = tuple(d.get('item_code') for d in bom_items)
 
 		items = frappe.get_list('Item',
-			fields=['image', 'description', 'name', 'stock_uom', 'item_name'],
+			fields=['image', 'description', 'name', 'stock_uom', 'item_name', 'is_sub_contracted_item'],
 			filters=[['name', 'in', item_names]]) # to get only required item dicts
 
 		for bom_item in bom_items:
@@ -884,6 +899,7 @@
 
 			bom_item.parent_bom_qty = bom_doc.quantity
 			bom_item.expandable = 0 if bom_item.value in ('', None)  else 1
+			bom_item.image = frappe.db.escape(bom_item.image)
 
 		return bom_items
 
diff --git a/erpnext/manufacturing/doctype/bom/bom_item_preview.html b/erpnext/manufacturing/doctype/bom/bom_item_preview.html
index 6cd5f8c..6088e46 100644
--- a/erpnext/manufacturing/doctype/bom/bom_item_preview.html
+++ b/erpnext/manufacturing/doctype/bom/bom_item_preview.html
@@ -1,13 +1,31 @@
 <div style="padding: 15px;">
-	{% if data.image %}
-	<img class="responsive" src={{ data.image }}>
-	<hr style="margin: 15px -15px;">
-	{% endif %}
-	<h4>
-		{{ __("Description") }}
-	</h4>
-	<div style="padding-top: 10px;">
-		{{ data.description }}
+	<div class="row mb-5">
+		<div class="col-md-5" style="max-height: 500px">
+			{% if data.image %}
+				<div class="border image-field " style="overflow: hidden;border-color:#e6e6e6">
+					<img class="responsive" src={{ data.image }}>
+				</div>
+			{% endif %}
+		</div>
+		<div class="col-md-7 h-500">
+			<h4>
+				{{ __("Description") }}
+			</h4>
+			<div style="padding-top: 10px;">
+				{{ data.description }}
+			</div>
+			<hr style="margin: 15px -15px;">
+			<p>
+				{% if data.value %}
+				<a style="margin-right: 7px; margin-bottom: 7px" class="btn btn-default btn-xs" href="#Form/BOM/{{ data.value }}">
+					{{ __("Open BOM {0}", [data.value.bold()]) }}</a>
+				{% endif %}
+				{% if data.item_code %}
+				<a class="btn btn-default btn-xs" href="#Form/Item/{{ data.item_code }}">
+					{{ __("Open Item {0}", [data.item_code.bold()]) }}</a>
+				{% endif %}
+			</p>
+		</div>
 	</div>
 	<hr style="margin: 15px -15px;">
 	<p>
diff --git a/erpnext/manufacturing/doctype/bom/bom_tree.js b/erpnext/manufacturing/doctype/bom/bom_tree.js
index 185b9ed..60fb377 100644
--- a/erpnext/manufacturing/doctype/bom/bom_tree.js
+++ b/erpnext/manufacturing/doctype/bom/bom_tree.js
@@ -64,7 +64,7 @@
 		if(node.is_root && node.data.value!="BOM") {
 			frappe.model.with_doc("BOM", node.data.value, function() {
 				var bom = frappe.model.get_doc("BOM", node.data.value);
-				node.data.image = bom.image || "";
+				node.data.image = escape(bom.image) || "";
 				node.data.description = bom.description || "";
 			});
 		}
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index 7f8f2ef..420bb00 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -192,15 +192,20 @@
 						"completed_qty": args.get("completed_qty") or 0.0
 					})
 		elif args.get("start_time"):
-			for name in employees:
-				self.append("time_logs", {
-					"from_time": get_datetime(args.get("start_time")),
-					"employee": name.get('employee'),
-					"operation": args.get("sub_operation"),
-					"completed_qty": 0.0
-				})
+			new_args = {
+				"from_time": get_datetime(args.get("start_time")),
+				"operation": args.get("sub_operation"),
+				"completed_qty": 0.0
+			}
 
-		if not self.employee:
+			if employees:
+				for name in employees:
+					new_args.employee = name.get('employee')
+					self.add_start_time_log(new_args)
+			else:
+				self.add_start_time_log(new_args)
+
+		if not self.employee and employees:
 			self.set_employees(employees)
 
 		if self.status == "On Hold":
@@ -208,6 +213,9 @@
 
 		self.save()
 
+	def add_start_time_log(self, args):
+		self.append("time_logs", args)
+
 	def set_employees(self, employees):
 		for name in employees:
 			self.append('employee', {
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js
index 450aa04..d198a69 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.js
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js
@@ -4,7 +4,7 @@
 frappe.ui.form.on('Production Plan', {
 	setup: function(frm) {
 		frm.custom_make_buttons = {
-			'Work Order': 'Work Order',
+			'Work Order': 'Work Order / Subcontract PO',
 			'Material Request': 'Material Request',
 		};
 
@@ -68,17 +68,13 @@
 			frm.trigger("show_progress");
 
 			if (frm.doc.status !== "Completed") {
-				if (frm.doc.po_items && frm.doc.status !== "Closed") {
-					frm.add_custom_button(__("Work Order"), ()=> {
-						frm.trigger("make_work_order");
-					}, __('Create'));
-				}
+				frm.add_custom_button(__("Work Order Tree"), ()=> {
+					frappe.set_route('Tree', 'Work Order', {production_plan: frm.doc.name});
+				}, __('View'));
 
-				if (frm.doc.mr_items && !in_list(['Material Requested', 'Closed'], frm.doc.status)) {
-					frm.add_custom_button(__("Material Request"), ()=> {
-						frm.trigger("make_material_request");
-					}, __('Create'));
-				}
+				frm.add_custom_button(__("Production Plan Summary"), ()=> {
+					frappe.set_route('query-report', 'Production Plan Summary', {production_plan: frm.doc.name});
+				}, __('View'));
 
 				if  (frm.doc.status === "Closed") {
 					frm.add_custom_button(__("Re-open"), function() {
@@ -89,6 +85,18 @@
 						frm.events.close_open_production_plan(frm, true);
 					}, __("Status"));
 				}
+
+				if (frm.doc.po_items && frm.doc.status !== "Closed") {
+					frm.add_custom_button(__("Work Order / Subcontract PO"), ()=> {
+						frm.trigger("make_work_order");
+					}, __('Create'));
+				}
+
+				if (frm.doc.mr_items && !in_list(['Material Requested', 'Closed'], frm.doc.status)) {
+					frm.add_custom_button(__("Material Request"), ()=> {
+						frm.trigger("make_material_request");
+					}, __('Create'));
+				}
 			}
 		}
 
@@ -233,6 +241,17 @@
 		});
 	},
 
+	get_sub_assembly_items: function(frm) {
+		frappe.call({
+			method: "get_sub_assembly_items",
+			freeze: true,
+			doc: frm.doc,
+			callback: function() {
+				refresh_field("sub_assembly_items");
+			}
+		});
+	},
+
 	get_items_for_mr: function(frm) {
 		if (!frm.doc.for_warehouse) {
 			frappe.throw(__("Select warehouse for material requests"));
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.json b/erpnext/manufacturing/doctype/production_plan/production_plan.json
index 1c0dde2..8437895 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.json
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.json
@@ -32,6 +32,9 @@
   "po_items",
   "section_break_25",
   "prod_plan_references",
+  "section_break_24",
+  "get_sub_assembly_items",
+  "sub_assembly_items",
   "material_request_planning",
   "include_non_stock_items",
   "include_subcontracted_items",
@@ -187,7 +190,7 @@
    "depends_on": "get_items_from",
    "fieldname": "get_items",
    "fieldtype": "Button",
-   "label": "Get Items For Work Order"
+   "label": "Get Finished Goods for Manufacture"
   },
   {
    "fieldname": "po_items",
@@ -199,7 +202,7 @@
   {
    "fieldname": "material_request_planning",
    "fieldtype": "Section Break",
-   "label": "Material Request Planning"
+   "label": "Material Requirement Planning"
   },
   {
    "default": "1",
@@ -237,12 +240,13 @@
   },
   {
    "fieldname": "section_break_27",
-   "fieldtype": "Section Break"
+   "fieldtype": "Section Break",
+   "hide_border": 1
   },
   {
    "fieldname": "mr_items",
    "fieldtype": "Table",
-   "label": "Material Request Plan Item",
+   "label": "Raw Materials",
    "no_copy": 1,
    "options": "Material Request Plan Item"
   },
@@ -337,13 +341,30 @@
    "hidden": 1,
    "label": "Production Plan Item Reference",
    "options": "Production Plan Item Reference"
+  },
+  {
+   "fieldname": "section_break_24",
+   "fieldtype": "Section Break",
+   "hide_border": 1
+  },
+  {
+   "fieldname": "sub_assembly_items",
+   "fieldtype": "Table",
+   "label": "Sub Assembly Items",
+   "no_copy": 1,
+   "options": "Production Plan Sub Assembly Item"
+  },
+  {
+   "fieldname": "get_sub_assembly_items",
+   "fieldtype": "Button",
+   "label": "Get Sub Assembly Items"
   }
  ],
  "icon": "fa fa-calendar",
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-05-24 16:59:03.643211",
+ "modified": "2021-06-28 20:00:33.905114",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Production Plan",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 0ede1bd..38a0ee7 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -5,10 +5,11 @@
 from __future__ import unicode_literals
 import frappe, json, copy
 from frappe import msgprint, _
-from six import string_types, iteritems
+from six import iteritems
 
 from frappe.model.document import Document
-from frappe.utils import cstr, flt, cint, nowdate, add_days, comma_and, now_datetime, ceil
+from frappe.utils import (flt, cint, nowdate, add_days, comma_and, now_datetime,
+	ceil, get_link_to_form, getdate)
 from frappe.utils.csvutils import build_csv_response
 from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, get_children
 from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
@@ -349,49 +350,88 @@
 
 	@frappe.whitelist()
 	def make_work_order(self):
-		wo_list = []
+		wo_list, po_list = [], []
+		subcontracted_po = {}
+
 		self.validate_data()
+		self.make_work_order_for_finished_goods(wo_list)
+		self.make_work_order_for_subassembly_items(wo_list, subcontracted_po)
+		self.make_subcontracted_purchase_order(subcontracted_po, po_list)
+		self.show_list_created_message('Work Order', wo_list)
+		self.show_list_created_message('Purchase Order', po_list)
+
+	def make_work_order_for_finished_goods(self, wo_list):
 		items_data = self.get_production_items()
 
 		for key, item in items_data.items():
+			if self.sub_assembly_items:
+				item['use_multi_level_bom'] = 0
+
 			work_order = self.create_work_order(item)
 			if work_order:
 				wo_list.append(work_order)
 
-			if item.get("make_work_order_for_sub_assembly_items"):
-				work_orders = self.make_work_order_for_sub_assembly_items(item)
-				wo_list.extend(work_orders)
+	def make_work_order_for_subassembly_items(self, wo_list, subcontracted_po):
+		for row in self.sub_assembly_items:
+			if row.type_of_manufacturing == 'Subcontract':
+				subcontracted_po.setdefault(row.supplier, []).append(row)
+				continue
+
+			args = {}
+			self.prepare_args_for_sub_assembly_items(row, args)
+			work_order = self.create_work_order(args)
+			if work_order:
+				wo_list.append(work_order)
+
+	def make_subcontracted_purchase_order(self, subcontracted_po, purchase_orders):
+		if not subcontracted_po:
+			return
+
+		for supplier, po_list in subcontracted_po.items():
+			po = frappe.new_doc('Purchase Order')
+			po.supplier = supplier
+			po.schedule_date = getdate(po_list[0].schedule_date) if po_list[0].schedule_date else nowdate()
+			po.is_subcontracted_item = 'Yes'
+			for row in po_list:
+				args = {
+					'item_code': row.production_item,
+					'warehouse': row.fg_warehouse,
+					'production_plan_sub_assembly_item': row.name,
+					'bom': row.bom_no,
+					'production_plan': self.name
+				}
+
+				for field in ['schedule_date', 'qty', 'uom', 'stock_uom', 'item_name',
+					'description', 'production_plan_item']:
+					args[field] = row.get(field)
+
+				po.append('items', args)
+
+			po.set_missing_values()
+			po.flags.ignore_mandatory = True
+			po.flags.ignore_validate = True
+			po.insert()
+			purchase_orders.append(po.name)
+
+	def show_list_created_message(self, doctype, doc_list=None):
+		if not doc_list:
+			return
 
 		frappe.flags.mute_messages = False
+		if doc_list:
+			doc_list = [get_link_to_form(doctype, p) for p in doc_list]
+			msgprint(_("{0} created").format(comma_and(doc_list)))
 
-		if wo_list:
-			wo_list = ["""<a href="/app/Form/Work Order/%s" target="_blank">%s</a>""" % \
-				(p, p) for p in wo_list]
-			msgprint(_("{0} created").format(comma_and(wo_list)))
-		else :
-			msgprint(_("No Work Orders created"))
+	def prepare_args_for_sub_assembly_items(self, row, args):
+		for field in ["production_item", "item_name", "qty", "fg_warehouse",
+			"description", "bom_no", "stock_uom", "bom_level", "production_plan_item"]:
+			args[field] = row.get(field)
 
-	def make_work_order_for_sub_assembly_items(self, item):
-		work_orders = []
-		bom_data = {}
-
-		get_sub_assembly_items(item.get("bom_no"), bom_data, item.get("qty"))
-
-		for key, data in bom_data.items():
-			data.update({
-				'qty': data.get("stock_qty"),
-				'production_plan': self.name,
-				'use_multi_level_bom': item.get("use_multi_level_bom"),
-				'company': self.company,
-				'fg_warehouse': item.get("fg_warehouse"),
-				'update_consumed_material_cost_in_project': 0
-			})
-
-			work_order = self.create_work_order(data)
-			if work_order:
-				work_orders.append(work_order)
-
-		return work_orders
+		args.update({
+			"use_multi_level_bom": 0,
+			"production_plan": self.name,
+			"production_plan_sub_assembly_item": row.name
+		})
 
 	def create_work_order(self, item):
 		from erpnext.manufacturing.doctype.work_order.work_order import OverProductionError, get_default_warehouse
@@ -476,9 +516,32 @@
 		else :
 			msgprint(_("No material request created"))
 
+	@frappe.whitelist()
+	def get_sub_assembly_items(self, manufacturing_type=None):
+		self.sub_assembly_items = []
+		for row in self.po_items:
+			bom_data = []
+			get_sub_assembly_items(row.bom_no, bom_data, row.planned_qty)
+			self.set_sub_assembly_items_based_on_level(row, bom_data, manufacturing_type)
+
+		self.save()
+
+	def set_sub_assembly_items_based_on_level(self, row, bom_data, manufacturing_type=None):
+		bom_data = sorted(bom_data, key = lambda i: i.bom_level)
+
+		for data in bom_data:
+			data.qty = data.stock_qty
+			data.production_plan_item = row.name
+			data.fg_warehouse = row.warehouse
+			data.schedule_date = row.planned_start_date
+			data.type_of_manufacturing = manufacturing_type or ("Subcontract" if data.is_sub_contracted_item
+				else "In House")
+
+			self.append("sub_assembly_items", data)
+
 @frappe.whitelist()
 def download_raw_materials(doc, warehouses=None):
-	if isinstance(doc, string_types):
+	if isinstance(doc, str):
 		doc = frappe._dict(json.loads(doc))
 
 	item_list = [['Item Code', 'Description', 'Stock UOM', 'Warehouse', 'Required Qty as per BOM',
@@ -660,7 +723,7 @@
 
 @frappe.whitelist()
 def get_bin_details(row, company, for_warehouse=None, all_warehouse=False):
-	if isinstance(row, string_types):
+	if isinstance(row, str):
 		row = frappe._dict(json.loads(row))
 
 	company = frappe.db.escape(company)
@@ -684,8 +747,11 @@
 		group by item_code, warehouse
 	""".format(conditions=conditions), { "item_code": row['item_code'] }, as_dict=1)
 
-def get_warehouse_list(warehouses, warehouse_list=[]):
-	if isinstance(warehouses, string_types):
+def get_warehouse_list(warehouses, warehouse_list=None):
+	if not warehouse_list:
+		warehouse_list = []
+
+	if isinstance(warehouses, str):
 		warehouses = json.loads(warehouses)
 
 	for row in warehouses:
@@ -697,7 +763,7 @@
 
 @frappe.whitelist()
 def get_items_for_material_requests(doc, warehouses=None, get_parent_warehouse_data=None):
-	if isinstance(doc, string_types):
+	if isinstance(doc, str):
 		doc = frappe._dict(json.loads(doc))
 
 	warehouse_list = []
@@ -726,6 +792,9 @@
 
 	so_item_details = frappe._dict()
 	for data in po_items:
+		if not data.get("include_exploded_items") and doc.get("sub_assembly_items"):
+			data["include_exploded_items"] = 1
+
 		planned_qty = data.get('required_qty') or data.get('planned_qty')
 		ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty
 		warehouse = doc.get('for_warehouse')
@@ -857,23 +926,28 @@
 #		"description": item_details.get("description")
 	}
 
-def get_sub_assembly_items(bom_no, bom_data, to_produce_qty):
+def get_sub_assembly_items(bom_no, bom_data, to_produce_qty, indent=0):
 	data = get_children('BOM', parent = bom_no)
 	for d in data:
 		if d.expandable:
-			key = (d.name, d.value)
-			if key not in bom_data:
-				bom_data.setdefault(key, {
-					'stock_qty': 0,
-					'description': d.description,
-					'production_item': d.item_code,
-					'item_name': d.item_name,
-					'stock_uom': d.stock_uom,
-					'uom': d.stock_uom,
-					'bom_no': d.value
-				})
+			parent_item_code = frappe.get_cached_value("BOM", bom_no, "item")
+			bom_level = (frappe.get_cached_value("BOM", d.value, "bom_level")
+				if d.value else 0)
 
-			bom_item = bom_data.get(key)
-			bom_item["stock_qty"] += (d.stock_qty / d.parent_bom_qty) * flt(to_produce_qty)
+			stock_qty = (d.stock_qty / d.parent_bom_qty) * flt(to_produce_qty)
+			bom_data.append(frappe._dict({
+				'parent_item_code': parent_item_code,
+				'description': d.description,
+				'production_item': d.item_code,
+				'item_name': d.item_name,
+				'stock_uom': d.stock_uom,
+				'uom': d.stock_uom,
+				'bom_no': d.value,
+				'is_sub_contracted_item': d.is_sub_contracted_item,
+				'bom_level': bom_level,
+				'indent': indent,
+				'stock_qty': stock_qty
+			}))
 
-			get_sub_assembly_items(bom_item.get("bom_no"), bom_data, bom_item["stock_qty"])
+			if d.value:
+				get_sub_assembly_items(d.value, bom_data, stock_qty, indent=indent+1)
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py b/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py
index 09ec24a..ca597f6 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py
@@ -9,5 +9,9 @@
 				'label': _('Transactions'),
 				'items': ['Work Order', 'Material Request']
 			},
+			{
+				'label': _('Subcontract'),
+				'items': ['Purchase Order']
+			},
 		]
 	}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index 768f99e..cce1bb6 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -169,7 +169,7 @@
 		pln.get_items()
 		pln.submit()
 
-		self.assertTrue(pln.po_items[0].planned_qty, 3)	
+		self.assertTrue(pln.po_items[0].planned_qty, 3)
 
 		pln.make_work_order()
 		work_order = frappe.db.get_value('Work Order', {
@@ -193,10 +193,10 @@
 		for so_item in so_items:
 			so_wo_qty = frappe.db.get_value('Sales Order Item', so_item, 'work_order_qty')
 			self.assertEqual(so_wo_qty, 0.0)
-		
+
 		latest_plan = frappe.get_doc('Production Plan', pln.name)
 		latest_plan.cancel()
-	
+
 	def test_pp_to_mr_customer_provided(self):
 		#Material Request from Production Plan for Customer Provided
 		create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
@@ -236,10 +236,10 @@
 		pln.append("po_items", {
 			"item_code": item_code,
 			"bom_no": frappe.db.get_value('BOM', {'item': "Test BOM 1"}),
-			"planned_qty": 3,
-			"make_work_order_for_sub_assembly_items": 1
+			"planned_qty": 3
 		})
 
+		pln.get_sub_assembly_items('In House')
 		pln.submit()
 		pln.make_work_order()
 
diff --git a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
index 89ab7aa..f829d57 100644
--- a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
+++ b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
@@ -9,18 +9,17 @@
   "include_exploded_items",
   "item_code",
   "bom_no",
-  "planned_qty",
   "column_break_6",
-  "make_work_order_for_sub_assembly_items",
+  "planned_qty",
   "warehouse",
   "planned_start_date",
   "section_break_9",
   "pending_qty",
   "ordered_qty",
-  "produced_qty",
   "column_break_17",
   "description",
   "stock_uom",
+  "produced_qty",
   "reference_section",
   "sales_order",
   "sales_order_item",
@@ -32,11 +31,10 @@
  ],
  "fields": [
   {
-   "columns": 2,
-   "default": "0",
+   "columns": 1,
+   "default": "1",
    "fieldname": "include_exploded_items",
    "fieldtype": "Check",
-   "in_list_view": 1,
    "label": "Include Exploded Items"
   },
   {
@@ -81,13 +79,6 @@
    "fieldtype": "Column Break"
   },
   {
-   "default": "0",
-   "description": "If enabled, system will create the work order for the exploded items against which BOM is available.",
-   "fieldname": "make_work_order_for_sub_assembly_items",
-   "fieldtype": "Check",
-   "label": "Make Work Order for Sub Assembly Items"
-  },
-  {
    "fieldname": "warehouse",
    "fieldtype": "Link",
    "in_list_view": 1,
@@ -218,7 +209,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-04-28 19:14:57.772123",
+ "modified": "2021-06-28 18:31:06.822168",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Production Plan Item",
diff --git a/erpnext/accounts/accounts b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/__init__.py
similarity index 100%
copy from erpnext/accounts/accounts
copy to erpnext/manufacturing/doctype/production_plan_sub_assembly_item/__init__.py
diff --git a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
new file mode 100644
index 0000000..657ee35
--- /dev/null
+++ b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
@@ -0,0 +1,202 @@
+{
+ "actions": [],
+ "creation": "2020-12-27 16:08:36.127199",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "production_item",
+  "item_name",
+  "fg_warehouse",
+  "parent_item_code",
+  "schedule_date",
+  "column_break_3",
+  "qty",
+  "bom_no",
+  "bom_level",
+  "type_of_manufacturing",
+  "supplier",
+  "work_order_details_section",
+  "work_order",
+  "purchase_order",
+  "production_plan_item",
+  "column_break_7",
+  "produced_qty",
+  "received_qty",
+  "indent",
+  "section_break_19",
+  "uom",
+  "stock_uom",
+  "column_break_22",
+  "description"
+ ],
+ "fields": [
+  {
+   "fetch_from": "sub_assembly_item_code.item_name",
+   "fieldname": "item_name",
+   "fieldtype": "Data",
+   "label": "Item Name",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "depends_on": "eval:doc.type_of_manufacturing == \"In House\"",
+   "fieldname": "work_order_details_section",
+   "fieldtype": "Section Break",
+   "label": "Reference"
+  },
+  {
+   "fieldname": "work_order",
+   "fieldtype": "Link",
+   "label": "Work Order",
+   "options": "Work Order",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_7",
+   "fieldtype": "Column Break"
+  },
+  {
+   "columns": 1,
+   "fieldname": "qty",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Required Qty",
+   "read_only": 1
+  },
+  {
+   "fieldname": "purchase_order",
+   "fieldtype": "Link",
+   "label": "Purchase Order",
+   "options": "Purchase Order",
+   "read_only": 1
+  },
+  {
+   "fieldname": "received_qty",
+   "fieldtype": "Float",
+   "label": "Received Qty"
+  },
+  {
+   "fieldname": "bom_no",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Bom No",
+   "options": "BOM"
+  },
+  {
+   "fieldname": "production_plan_item",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Production Plan Item",
+   "read_only": 1
+  },
+  {
+   "fieldname": "parent_item_code",
+   "fieldtype": "Link",
+   "label": "Finished Good",
+   "options": "Item",
+   "read_only": 1
+  },
+  {
+   "columns": 1,
+   "fetch_from": "bom_no.bom_level",
+   "fieldname": "bom_level",
+   "fieldtype": "Int",
+   "in_list_view": 1,
+   "label": "Level (BOM)",
+   "read_only": 1
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "section_break_19",
+   "fieldtype": "Section Break",
+   "label": "Item Details"
+  },
+  {
+   "fieldname": "uom",
+   "fieldtype": "Link",
+   "label": "UOM",
+   "options": "UOM",
+   "read_only": 1
+  },
+  {
+   "fieldname": "stock_uom",
+   "fieldtype": "Link",
+   "label": "Stock UOM",
+   "options": "UOM",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_22",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "description",
+   "fieldtype": "Small Text",
+   "label": "description",
+   "read_only": 1
+  },
+  {
+   "fieldname": "production_item",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Sub Assembly Item Code",
+   "options": "Item",
+   "read_only": 1
+  },
+  {
+   "fieldname": "indent",
+   "fieldtype": "Int",
+   "label": "Indent"
+  },
+  {
+   "fieldname": "fg_warehouse",
+   "fieldtype": "Link",
+   "label": "Target Warehouse",
+   "options": "Warehouse"
+  },
+  {
+   "fieldname": "produced_qty",
+   "fieldtype": "Data",
+   "label": "Produced Quantity",
+   "read_only": 1
+  },
+  {
+   "default": "In House",
+   "fieldname": "type_of_manufacturing",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "label": "Manufacturing Type",
+   "options": "In House\nSubcontract"
+  },
+  {
+   "fieldname": "supplier",
+   "fieldtype": "Link",
+   "label": "Supplier",
+   "mandatory_depends_on": "eval:doc.type_of_manufacturing == 'Subcontract'",
+   "options": "Supplier"
+  },
+  {
+   "fieldname": "schedule_date",
+   "fieldtype": "Datetime",
+   "in_list_view": 1,
+   "label": "Schedule Date"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-06-28 20:10:56.296410",
+ "modified_by": "Administrator",
+ "module": "Manufacturing",
+ "name": "Production Plan Sub Assembly Item",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py
new file mode 100644
index 0000000..6850a2e
--- /dev/null
+++ b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ProductionPlanSubAssemblyItem(Document):
+	pass
diff --git a/erpnext/manufacturing/doctype/sub_operation/sub_operation.json b/erpnext/manufacturing/doctype/sub_operation/sub_operation.json
index f63d2b9..10cee32 100644
--- a/erpnext/manufacturing/doctype/sub_operation/sub_operation.json
+++ b/erpnext/manufacturing/doctype/sub_operation/sub_operation.json
@@ -19,6 +19,7 @@
    "options": "Operation"
   },
   {
+   "default": "0",
    "description": "Time in mins",
    "fieldname": "time_in_mins",
    "fieldtype": "Float",
@@ -38,7 +39,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-12-07 18:09:18.005578",
+ "modified": "2021-07-15 16:39:41.635362",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Sub Operation",
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 68de0b2..bf1ccb7 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -513,6 +513,60 @@
 		work_order1.save()
 		self.assertEqual(work_order1.operations[0].time_in_mins, 40.0)
 
+	def test_batch_size_for_fg_item(self):
+		fg_item = "Test Batch Size Item For BOM 3"
+		rm1 = "Test Batch Size Item RM 1 For BOM 3"
+
+		frappe.db.set_value('Manufacturing Settings', None, 'make_serial_no_batch_from_work_order', 0)
+		for item in ["Test Batch Size Item For BOM 3", "Test Batch Size Item RM 1 For BOM 3"]:
+			item_args = {
+				"include_item_in_manufacturing": 1,
+				"is_stock_item": 1
+			}
+
+			if item == fg_item:
+				item_args['has_batch_no'] = 1
+				item_args['create_new_batch'] = 1
+				item_args['batch_number_series'] = 'TBSI3.#####'
+
+			make_item(item, item_args)
+
+		bom_name = frappe.db.get_value("BOM",
+			{"item": fg_item, "is_active": 1, "with_operations": 1}, "name")
+
+		if not bom_name:
+			bom = make_bom(item=fg_item, rate=1000, raw_materials = [rm1], do_not_save=True)
+			bom.save()
+			bom.submit()
+			bom_name = bom.name
+
+		work_order = make_wo_order_test_record(item=fg_item, skip_transfer=True, planned_start_date=now(), qty=1)
+		ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 1))
+		for row in ste1.get('items'):
+			if row.is_finished_item:
+				self.assertEqual(row.item_code, fg_item)
+
+		work_order = make_wo_order_test_record(item=fg_item, skip_transfer=True, planned_start_date=now(), qty=1)
+		frappe.db.set_value('Manufacturing Settings', None, 'make_serial_no_batch_from_work_order', 1)
+		ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 1))
+		for row in ste1.get('items'):
+			if row.is_finished_item:
+				self.assertEqual(row.item_code, fg_item)
+
+		work_order = make_wo_order_test_record(item=fg_item, skip_transfer=True, planned_start_date=now(),
+			qty=30, do_not_save = True)
+		work_order.batch_size = 10
+		work_order.insert()
+		work_order.submit()
+		self.assertEqual(work_order.has_batch_no, 1)
+		ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 30))
+		for row in ste1.get('items'):
+			if row.is_finished_item:
+				self.assertEqual(row.item_code, fg_item)
+				self.assertEqual(row.qty, 10)
+
+		frappe.db.set_value('Manufacturing Settings', None, 'make_serial_no_batch_from_work_order', 0)
+
 	def test_partial_material_consumption(self):
 		frappe.db.set_value("Manufacturing Settings", None, "material_consumption", 1)
 		wo_order = make_wo_order_test_record(planned_start_date=now(), qty=4)
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index 44d76d2..3b56854 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -64,11 +64,16 @@
   "description",
   "stock_uom",
   "column_break2",
+  "references_section",
   "material_request",
   "material_request_item",
   "sales_order_item",
+  "column_break_61",
   "production_plan",
   "production_plan_item",
+  "production_plan_sub_assembly_item",
+  "parent_work_order",
+  "bom_level",
   "product_bundle_item",
   "amended_from"
  ],
@@ -546,17 +551,26 @@
    "no_copy": 1,
    "print_hide": 1,
    "read_only": 1
-  }
+  },
+  {
+    "fieldname": "production_plan_sub_assembly_item",
+    "fieldtype": "Data",
+    "label": "Production Plan Sub-assembly Item",
+    "no_copy": 1,
+    "print_hide": 1,
+    "read_only": 1
+   }
  ],
  "icon": "fa fa-cogs",
  "idx": 1,
  "image_field": "image",
  "is_submittable": 1,
  "links": [],
- "modified": "2021-06-20 15:19:14.902699",
+ "modified": "2021-06-28 16:19:14.902699",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Work Order",
+ "nsm_parent_field": "parent_work_order",
  "owner": "Administrator",
  "permissions": [
   {
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 180815d..0a8e532 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -239,7 +239,7 @@
 		self.create_serial_no_batch_no()
 
 	def on_submit(self):
-		if not self.wip_warehouse:
+		if not self.wip_warehouse and not self.skip_transfer:
 			frappe.throw(_("Work-in-Progress Warehouse is required before Submit"))
 		if not self.fg_warehouse:
 			frappe.throw(_("For Warehouse is required before Submit"))
@@ -483,7 +483,7 @@
 
 
 		self.set('operations', [])
-		if not self.bom_no:
+		if not self.bom_no or not frappe.get_cached_value('BOM', self.bom_no, 'with_operations'):
 			return
 
 		operations = []
@@ -590,6 +590,7 @@
 	def validate_operation_time(self):
 		for d in self.operations:
 			if not d.time_in_mins > 0:
+				print(self.bom_no, self.production_item)
 				frappe.throw(_("Operation Time must be greater than 0 for Operation {0}").format(d.operation))
 
 	def update_required_items(self):
diff --git a/erpnext/manufacturing/doctype/work_order/work_order_preview.html b/erpnext/manufacturing/doctype/work_order/work_order_preview.html
new file mode 100644
index 0000000..a4bf93e
--- /dev/null
+++ b/erpnext/manufacturing/doctype/work_order/work_order_preview.html
@@ -0,0 +1,33 @@
+<div style="padding: 15px;">
+	<div class="row mb-5">
+		<div class="col-md-5" style="max-height: 500px">
+			{% if data.image %}
+				<div class="border image-field " style="overflow: hidden;border-color:#e6e6e6">
+					<img class="responsive" src={{ data.image }}>
+				</div>
+			{% endif %}
+		</div>
+		<div class="col-md-7 h-500">
+			<div style="padding-top: 10px;">
+				<b> Status </b> {{ data.status }}
+			</div>
+			<div style="padding-top: 10px;">
+				<b> Qty to Produce </b> {{ data.qty }}
+			</div>
+			<div style="padding-top: 10px;">
+				<b> Produced Qty </b> {{ data.produced_qty }}
+			</div>
+			<hr style="margin: 15px -15px;">
+			<p>
+				{% if data.value %}
+				<a style="margin-right: 7px; margin-bottom: 7px" class="btn btn-default btn-xs" href="#Form/Work Order/{{ data.value }}">
+					{{ __("Open Work Order {0}", [data.value.bold()]) }}</a>
+				{% endif %}
+				{% if data.item_code %}
+				<a class="btn btn-default btn-xs" href="#Form/Item/{{ data.item_code }}">
+					{{ __("Open Item {0}", [data.item_code.bold()]) }}</a>
+				{% endif %}
+			</p>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/erpnext/manufacturing/report/bom_explorer/bom_explorer.py b/erpnext/manufacturing/report/bom_explorer/bom_explorer.py
index 48907ad..858b554 100644
--- a/erpnext/manufacturing/report/bom_explorer/bom_explorer.py
+++ b/erpnext/manufacturing/report/bom_explorer/bom_explorer.py
@@ -20,17 +20,20 @@
 		fields= ['qty','bom_no','qty','scrap','item_code','item_name','description','uom'])
 
 	for item in exploded_items:
+		print(item.bom_no, indent)
 		item["indent"] = indent
 		data.append({
 			'item_code': item.item_code,
 			'item_name': item.item_name,
 			'indent': indent,
+			'bom_level': (frappe.get_cached_value("BOM", item.bom_no, "bom_level")
+				if item.bom_no else ""),
 			'bom': item.bom_no,
 			'qty': item.qty * qty,
 			'uom': item.uom,
 			'description': item.description,
 			'scrap': item.scrap
-			})
+		})
 		if item.bom_no:
 			get_exploded_items(item.bom_no, data, indent=indent+1, qty=item.qty)
 
@@ -69,6 +72,12 @@
 			"width": 100
 		},
 		{
+			"label": "BOM Level",
+			"fieldtype": "Data",
+			"fieldname": "bom_level",
+			"width": 100
+		},
+		{
 			"label": "Standard Description",
 			"fieldtype": "data",
 			"fieldname": "description",
diff --git a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
index 1c6758e..ed8b939 100644
--- a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
+++ b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
@@ -70,12 +70,12 @@
 					ON bom_item.item_code = ledger.item_code
 				{conditions}
 			WHERE
-				bom_item.parent = '{bom}' and bom_item.parenttype='BOM'
+				bom_item.parent = {bom} and bom_item.parenttype='BOM'
 
 			GROUP BY bom_item.item_code""".format(
 				qty_field=qty_field,
 				table=table,
 				conditions=conditions,
-				bom=bom,
+				bom=frappe.db.escape(bom),
 				qty_to_produce=qty_to_produce or 1)
 			)
diff --git a/erpnext/manufacturing/report/job_card_summary/job_card_summary.js b/erpnext/manufacturing/report/job_card_summary/job_card_summary.js
index bd68db1..cb771e4 100644
--- a/erpnext/manufacturing/report/job_card_summary/job_card_summary.js
+++ b/erpnext/manufacturing/report/job_card_summary/job_card_summary.js
@@ -68,6 +68,18 @@
 			get_data: function(txt) {
 				return frappe.db.get_link_options('Item', txt);
 			}
+		},
+		{
+			label: __("Workstation"),
+			fieldname: "workstation",
+			fieldtype: "Link",
+			options: "Workstation"
+		},
+		{
+			label: __("Operation"),
+			fieldname: "operation",
+			fieldtype: "Link",
+			options: "Operation"
 		}
 	]
 };
diff --git a/erpnext/manufacturing/report/job_card_summary/job_card_summary.json b/erpnext/manufacturing/report/job_card_summary/job_card_summary.json
index 9f08fc3..ecf2b74 100644
--- a/erpnext/manufacturing/report/job_card_summary/job_card_summary.json
+++ b/erpnext/manufacturing/report/job_card_summary/job_card_summary.json
@@ -1,14 +1,16 @@
 {
- "add_total_row": 0,
+ "add_total_row": 1,
+ "columns": [],
  "creation": "2020-04-20 12:00:21.436619",
  "disable_prepared_report": 0,
  "disabled": 0,
  "docstatus": 0,
  "doctype": "Report",
+ "filters": [],
  "idx": 0,
  "is_standard": "Yes",
- "letter_head": "Gadgets International",
- "modified": "2020-04-20 12:00:21.436619",
+ "letter_head": "",
+ "modified": "2020-12-30 11:49:21.713561",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Job Card Summary",
diff --git a/erpnext/accounts/accounts b/erpnext/manufacturing/report/production_plan_summary/__init__.py
similarity index 100%
rename from erpnext/accounts/accounts
rename to erpnext/manufacturing/report/production_plan_summary/__init__.py
diff --git a/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.js b/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.js
new file mode 100644
index 0000000..59396fe
--- /dev/null
+++ b/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.js
@@ -0,0 +1,32 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Production Plan Summary"] = {
+	"filters": [
+		{
+			fieldname: "production_plan",
+			label: __("Production Plan"),
+			fieldtype: "Link",
+			options: "Production Plan",
+			reqd: 1,
+			get_query: function() {
+				return {
+					filters: {
+						"docstatus": 1
+					}
+				};
+			}
+		}
+	],
+	"formatter": function(value, row, column, data, default_formatter) {
+		value = default_formatter(value, row, column, data);
+
+		if (column.fieldname == "document_name") {
+			var color = data.pending_qty > 0 ? 'red': 'green';
+			value = `<a style='color:${color}' href="#Form/${data['document_type']}/${data['document_name']}" data-doctype="${data['document_type']}">${data['document_name']}</a>`;
+		}
+
+		return value;
+	},
+};
diff --git a/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.json b/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.json
new file mode 100644
index 0000000..33aca21
--- /dev/null
+++ b/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.json
@@ -0,0 +1,26 @@
+{
+ "add_total_row": 0,
+ "columns": [],
+ "creation": "2020-12-27 11:43:39.781793",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "filters": [],
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2020-12-27 11:43:42.677584",
+ "modified_by": "Administrator",
+ "module": "Manufacturing",
+ "name": "Production Plan Summary",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Production Plan",
+ "report_name": "Production Plan Summary",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Manufacturing User"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py b/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py
new file mode 100644
index 0000000..81b1791
--- /dev/null
+++ b/erpnext/manufacturing/report/production_plan_summary/production_plan_summary.py
@@ -0,0 +1,136 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.utils import flt
+
+def execute(filters=None):
+	columns, data = [], []
+	data = get_data(filters)
+	columns = get_column(filters)
+
+	return columns, data
+
+def get_data(filters):
+	data = []
+
+	order_details = {}
+	get_work_order_details(filters, order_details)
+	get_purchase_order_details(filters, order_details)
+	get_production_plan_item_details(filters, data, order_details)
+
+	return data
+
+def get_production_plan_item_details(filters, data, order_details):
+	itemwise_indent = {}
+
+	production_plan_doc = frappe.get_cached_doc("Production Plan", filters.get("production_plan"))
+	for row in production_plan_doc.po_items:
+		work_order = frappe.get_cached_value("Work Order", {"production_plan_item": row.name,
+			"bom_no": row.bom_no, "production_item": row.item_code}, "name")
+
+		if row.item_code not in itemwise_indent:
+			itemwise_indent.setdefault(row.item_code, {})
+
+		data.append({
+			"indent": 0,
+			"item_code": row.item_code,
+			"item_name": frappe.get_cached_value("Item", row.item_code, "item_name"),
+			"qty": row.planned_qty,
+			"document_type": "Work Order",
+			"document_name": work_order,
+			"bom_level": frappe.get_cached_value("BOM", row.bom_no, "bom_level"),
+			"produced_qty": order_details.get((work_order, row.item_code)).get("produced_qty"),
+			"pending_qty": flt(row.planned_qty) - flt(order_details.get((work_order, row.item_code)).get("produced_qty"))
+		})
+
+		get_production_plan_sub_assembly_item_details(filters, row, production_plan_doc, data, order_details)
+
+def get_production_plan_sub_assembly_item_details(filters, row, production_plan_doc, data, order_details):
+	for item in production_plan_doc.sub_assembly_items:
+		if row.name == item.production_plan_item:
+			subcontracted_item = (item.type_of_manufacturing == 'Subcontract')
+
+			if subcontracted_item:
+				docname = frappe.get_cached_value("Purchase Order Item",
+					{"production_plan_sub_assembly_item": item.name, "docstatus": ("<", 2)}, "parent")
+			else:
+				docname = frappe.get_cached_value("Work Order",
+					{"production_plan_sub_assembly_item": item.name, "docstatus": ("<", 2)}, "name")
+
+			data.append({
+				"indent": 1,
+				"item_code": item.production_item,
+				"item_name": item.item_name,
+				"qty": item.qty,
+				"document_type": "Work Order" if not subcontracted_item else "Purchase Order",
+				"document_name": docname,
+				"bom_level": item.bom_level,
+				"produced_qty": order_details.get((docname, item.production_item)).get("produced_qty"),
+				"pending_qty": flt(item.qty) - flt(order_details.get((docname, item.production_item)).get("produced_qty"))
+			})
+
+def get_work_order_details(filters, order_details):
+	for row in frappe.get_all("Work Order", filters = {"production_plan": filters.get("production_plan")},
+		fields=["name", "produced_qty", "production_plan", "production_item"]):
+		order_details.setdefault((row.name, row.production_item), row)
+
+def get_purchase_order_details(filters, order_details):
+	for row in frappe.get_all("Purchase Order Item", filters = {"production_plan": filters.get("production_plan")},
+		fields=["parent", "received_qty as produced_qty", "item_code"]):
+		order_details.setdefault((row.parent, row.item_code), row)
+
+def get_column(filters):
+	return [
+		{
+			"label": "Finished Good",
+			"fieldtype": "Link",
+			"fieldname": "item_code",
+			"width": 300,
+			"options": "Item"
+		},
+		{
+			"label": "Item Name",
+			"fieldtype": "data",
+			"fieldname": "item_name",
+			"width": 100
+		},
+		{
+			"label": "Document Type",
+			"fieldtype": "Link",
+			"fieldname": "document_type",
+			"width": 150,
+			"options": "DocType"
+		},
+		{
+			"label": "Document Name",
+			"fieldtype": "Dynamic Link",
+			"fieldname": "document_name",
+			"width": 150
+		},
+		{
+			"label": "BOM Level",
+			"fieldtype": "Int",
+			"fieldname": "bom_level",
+			"width": 100
+		},
+		{
+			"label": "Order Qty",
+			"fieldtype": "Float",
+			"fieldname": "qty",
+			"width": 120
+		},
+		{
+			"label": "Received Qty",
+			"fieldtype": "Float",
+			"fieldname": "produced_qty",
+			"width": 160
+		},
+		{
+			"label": "Pending Qty",
+			"fieldtype": "Float",
+			"fieldname": "pending_qty",
+			"width": 110
+		}
+	]
diff --git a/erpnext/manufacturing/report/work_order_summary/work_order_summary.py b/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
index fb047b2..612dad0 100644
--- a/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
+++ b/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
@@ -19,7 +19,7 @@
 	return columns, data, None, chart_data
 
 def get_data(filters):
-	query_filters = {"docstatus": 1}
+	query_filters = {"docstatus": ("<", 2)}
 
 	fields = ["name", "status", "sales_order", "production_item", "qty", "produced_qty",
 		"planned_start_date", "planned_end_date", "actual_start_date", "actual_end_date", "lead_time"]
@@ -62,7 +62,8 @@
 		"Not Started": 0,
 		"In Process": 0,
 		"Stopped": 0,
-		"Completed": 0
+		"Completed": 0,
+		"Draft": 0
 	}
 
 	for d in data:
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index c93f7a7..0ae8130 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -293,3 +293,5 @@
 erpnext.patches.v13_0.update_response_by_variance
 erpnext.patches.v13_0.bill_for_rejected_quantity_in_purchase_invoice
 erpnext.patches.v13_0.update_job_card_details
+erpnext.patches.v13_0.update_level_in_bom #1234sswef
+erpnext.patches.v13_0.add_missing_fg_item_for_stock_entry
diff --git a/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py b/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py
new file mode 100644
index 0000000..48999e6
--- /dev/null
+++ b/erpnext/patches/v13_0/add_missing_fg_item_for_stock_entry.py
@@ -0,0 +1,110 @@
+# Copyright (c) 2020, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+from frappe.utils import cstr, flt, cint
+from erpnext.stock.stock_ledger import make_sl_entries
+from erpnext.controllers.stock_controller import create_repost_item_valuation_entry
+
+def execute():
+	if not frappe.db.has_column('Work Order', 'has_batch_no'):
+		return
+
+	if cint(frappe.db.get_single_value('Manufacturing Settings', 'make_serial_no_batch_from_work_order')):
+		return
+
+	frappe.reload_doc('manufacturing', 'doctype', 'work_order')
+	filters = {
+		'docstatus': 1,
+		'produced_qty': ('>', 0),
+		'creation': ('>=', '2021-06-29 00:00:00'),
+		'has_batch_no': 1
+	}
+
+	fields = ['name', 'production_item']
+
+	work_orders = [d.name for d in frappe.get_all('Work Order', filters = filters, fields=fields)]
+
+	if not work_orders:
+		return
+
+	repost_stock_entries = []
+	stock_entries = frappe.db.sql_list('''
+		SELECT
+			se.name
+		FROM
+			`tabStock Entry` se
+		WHERE
+			se.purpose = 'Manufacture' and se.docstatus < 2 and se.work_order in {work_orders}
+			and not exists(
+				select name from `tabStock Entry Detail` sed where sed.parent = se.name and sed.is_finished_item = 1
+			)
+		Order BY
+			se.posting_date, se.posting_time
+	'''.format(work_orders=tuple(work_orders)))
+
+	if stock_entries:
+		print('Length of stock entries', len(stock_entries))
+
+	for stock_entry in stock_entries:
+		doc = frappe.get_doc('Stock Entry', stock_entry)
+		doc.set_work_order_details()
+		doc.load_items_from_bom()
+		doc.calculate_rate_and_amount()
+		set_expense_account(doc)
+		doc.make_batches('t_warehouse')
+
+		if doc.docstatus == 0:
+			doc.save()
+		else:
+			repost_stock_entry(doc)
+			repost_stock_entries.append(doc)
+
+	for repost_doc in repost_stock_entries:
+		repost_future_sle_and_gle(repost_doc)
+
+def set_expense_account(doc):
+	for row in doc.items:
+		if row.is_finished_item and not row.expense_account:
+			row.expense_account = frappe.get_cached_value('Company', doc.company, 'stock_adjustment_account')
+
+def repost_stock_entry(doc):
+	doc.db_update()
+	for child_row in doc.items:
+		if child_row.is_finished_item:
+			child_row.db_update()
+
+	sl_entries = []
+	finished_item_row = doc.get_finished_item_row()
+	get_sle_for_target_warehouse(doc, sl_entries, finished_item_row)
+
+	if sl_entries:
+		try:
+			make_sl_entries(sl_entries, True)
+		except Exception:
+			print(f'SLE entries not posted for the stock entry {doc.name}')
+			traceback = frappe.get_traceback()
+			frappe.log_error(traceback)
+
+def get_sle_for_target_warehouse(doc, sl_entries, finished_item_row):
+	for d in doc.get('items'):
+		if cstr(d.t_warehouse) and finished_item_row and d.name == finished_item_row.name:
+			sle = doc.get_sl_entries(d, {
+				"warehouse": cstr(d.t_warehouse),
+				"actual_qty": flt(d.transfer_qty),
+				"incoming_rate": flt(d.valuation_rate)
+			})
+
+			sle.recalculate_rate = 1
+			sl_entries.append(sle)
+
+def repost_future_sle_and_gle(doc):
+	args = frappe._dict({
+		"posting_date": doc.posting_date,
+		"posting_time": doc.posting_time,
+		"voucher_type": doc.doctype,
+		"voucher_no": doc.name,
+		"company": doc.company
+	})
+
+	create_repost_item_valuation_entry(args)
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/update_level_in_bom.py b/erpnext/patches/v13_0/update_level_in_bom.py
new file mode 100644
index 0000000..0d03c42
--- /dev/null
+++ b/erpnext/patches/v13_0/update_level_in_bom.py
@@ -0,0 +1,30 @@
+# Copyright (c) 2020, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	for document in ["bom", "bom_item", "bom_explosion_item"]:
+		frappe.reload_doc('manufacturing', 'doctype', document)
+
+	frappe.db.sql(" update `tabBOM` set bom_level = 0 where docstatus = 1")
+
+	bom_list = frappe.db.sql_list("""select name from `tabBOM` bom
+		where docstatus=1 and is_active=1 and not exists(select bom_no from `tabBOM Item`
+		where parent=bom.name and ifnull(bom_no, '')!='')""")
+
+	count = 0
+	while(count < len(bom_list)):
+		for parent_bom in get_parent_boms(bom_list[count]):
+			bom_doc = frappe.get_cached_doc("BOM", parent_bom)
+			bom_doc.set_bom_level(update=True)
+			bom_list.append(parent_bom)
+		count += 1
+
+def get_parent_boms(bom_no):
+	return frappe.db.sql_list("""
+		select distinct bom_item.parent from `tabBOM Item` bom_item
+		where bom_item.bom_no = %s and bom_item.docstatus=1 and bom_item.parenttype='BOM'
+			and exists(select bom.name from `tabBOM` bom where bom.name=bom_item.parent and bom.is_active=1)
+	""", bom_no)
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 5f9d5ed..9265460 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -12,7 +12,10 @@
 from frappe.utils import today
 
 def setup(company=None, patch=True):
-	setup_company_independent_fixtures(patch=patch)
+	# Company independent fixtures should be called only once at the first company setup
+	if frappe.db.count('Company', {'country': 'India'}) <=1:
+		setup_company_independent_fixtures(patch=patch)
+
 	if not patch:
 		make_fixtures(company)
 
@@ -122,10 +125,12 @@
 def make_property_setters(patch=False):
 	# GST rules do not allow for an invoice no. bigger than 16 characters
 	journal_entry_types = frappe.get_meta("Journal Entry").get_options("voucher_type").split("\n") + ['Reversal Of ITC']
+	sales_invoice_series = ['SINV-.YY.-', 'SRET-.YY.-', ''] + frappe.get_meta("Sales Invoice").get_options("naming_series").split("\n")
+	purchase_invoice_series = ['PINV-.YY.-', 'PRET-.YY.-', ''] + frappe.get_meta("Purchase Invoice").get_options("naming_series").split("\n")
 
 	if not patch:
-		make_property_setter('Sales Invoice', 'naming_series', 'options', 'SINV-.YY.-\nSRET-.YY.-', '')
-		make_property_setter('Purchase Invoice', 'naming_series', 'options', 'PINV-.YY.-\nPRET-.YY.-', '')
+		make_property_setter('Sales Invoice', 'naming_series', 'options', '\n'.join(sales_invoice_series), '')
+		make_property_setter('Purchase Invoice', 'naming_series', 'options', '\n'.join(purchase_invoice_series), '')
 		make_property_setter('Journal Entry', 'voucher_type', 'options', '\n'.join(journal_entry_types), '')
 
 def make_custom_fields(update=True):
@@ -786,7 +791,7 @@
 			doc.flags.ignore_mandatory = True
 			doc.insert()
 		else:
-			doc = frappe.get_doc("Tax Withholding Category", d.get("name"))
+			doc = frappe.get_doc("Tax Withholding Category", d.get("name"), for_update=True)
 
 			if accounts:
 				doc.append("accounts", accounts[0])
diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js
index f7b2c1d..6e36d28 100644
--- a/erpnext/selling/page/point_of_sale/pos_item_cart.js
+++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js
@@ -367,15 +367,16 @@
 			`<div class="add-discount-field"></div>`
 		);
 		const me = this;
+		const frm = me.events.get_frm();
+		let discount = frm.doc.additional_discount_percentage;
 
 		this.discount_field = frappe.ui.form.make_control({
 			df: {
 				label: __('Discount'),
 				fieldtype: 'Data',
-				placeholder: __('Enter discount percentage.'),
+				placeholder: ( discount ? discount + '%' :  __('Enter discount percentage.') ),
 				input_class: 'input-xs',
 				onchange: function() {
-					const frm = me.events.get_frm();
 					if (flt(this.value) != 0) {
 						frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', flt(this.value));
 						me.hide_discount_control(this.value);
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 36a7d20..8755125 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -291,7 +291,7 @@
 		cash = frappe.db.get_value('Mode of Payment', {'type': 'Cash'}, 'name')
 		if cash and self.default_cash_account \
 			and not frappe.db.get_value('Mode of Payment Account', {'company': self.name, 'parent': cash}):
-			mode_of_payment = frappe.get_doc('Mode of Payment', cash)
+			mode_of_payment = frappe.get_doc('Mode of Payment', cash, for_update=True)
 			mode_of_payment.append('accounts', {
 				'company': self.name,
 				'default_account': self.default_cash_account
diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py
index 6ea0ca4..c375dac 100644
--- a/erpnext/setup/setup_wizard/operations/taxes_setup.py
+++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py
@@ -26,7 +26,7 @@
 	if 'chart_of_accounts' not in country_wise_tax:
 		country_wise_tax = simple_to_detailed(country_wise_tax)
 
-	from_detailed_data(company_name, country_wise_tax.get('chart_of_accounts'))
+	from_detailed_data(company_name, country_wise_tax)
 	update_regional_tax_settings(country, company_name)
 
 
@@ -78,11 +78,12 @@
 def from_detailed_data(company_name, data):
 	"""Create Taxes and Charges Templates from detailed data."""
 	coa_name = frappe.db.get_value('Company', company_name, 'chart_of_accounts')
-	tax_templates = data.get(coa_name) or data.get('*')
-	sales_tax_templates = tax_templates.get('sales_tax_templates') or tax_templates.get('*')
-	purchase_tax_templates = tax_templates.get('purchase_tax_templates') or tax_templates.get('*')
-	item_tax_templates = tax_templates.get('item_tax_templates') or tax_templates.get('*')
-	tax_categories = tax_templates.get('tax_categories')
+	coa_data = data.get('chart_of_accounts', {})
+	tax_templates = coa_data.get(coa_name) or coa_data.get('*', {})
+	tax_categories = data.get('tax_categories')
+	sales_tax_templates = tax_templates.get('sales_tax_templates') or tax_templates.get('*', {})
+	purchase_tax_templates = tax_templates.get('purchase_tax_templates') or tax_templates.get('*', {})
+	item_tax_templates = tax_templates.get('item_tax_templates') or tax_templates.get('*', {})
 
 	if tax_categories:
 		for tax_category in tax_categories:
diff --git a/erpnext/stock/doctype/batch/batch.json b/erpnext/stock/doctype/batch/batch.json
index e6d2e13..fc4cf1d 100644
--- a/erpnext/stock/doctype/batch/batch.json
+++ b/erpnext/stock/doctype/batch/batch.json
@@ -193,7 +193,7 @@
  "image_field": "image",
  "links": [],
  "max_attachments": 5,
- "modified": "2021-01-07 11:10:09.149170",
+ "modified": "2021-07-08 16:22:01.343105",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Batch",
@@ -217,5 +217,6 @@
  "quick_entry": 1,
  "sort_field": "modified",
  "sort_order": "DESC",
- "title_field": "batch_id"
+ "title_field": "batch_id",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
index 55f2ebb..5f31d9c 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
@@ -133,6 +133,6 @@
 
 def get_repost_item_valuation_entries():
 	return frappe.db.sql(""" SELECT name from `tabRepost Item Valuation`
-		WHERE status != 'Completed' and creation <= %s and docstatus = 1
+		WHERE status in ('Queued', 'In Progress') and creation <= %s and docstatus = 1
 		ORDER BY timestamp(posting_date, posting_time) asc, creation asc
 	""", now(), as_dict=1)
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 90b81dd..fcb6f0f 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -72,7 +72,7 @@
 		self.validate_with_material_request()
 		self.validate_batch()
 		self.validate_inspection()
-		self.validate_fg_completed_qty()
+		# self.validate_fg_completed_qty()
 		self.validate_difference_account()
 		self.set_job_card_data()
 		self.set_purpose_for_stock_entry()
@@ -719,6 +719,10 @@
 			frappe.throw(_("Multiple items cannot be marked as finished item"))
 
 		if self.purpose == "Manufacture":
+			if not finished_items:
+				frappe.throw(_('Finished Good has not set in the stock entry {0}')
+					.format(self.name))
+
 			allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings",
 				"overproduction_percentage_for_work_order"))
 
@@ -1090,13 +1094,13 @@
 			"is_finished_item": 1
 		}
 
-		if self.work_order and self.pro_doc.has_batch_no:
+		if self.work_order and self.pro_doc.has_batch_no and cint(frappe.db.get_single_value('Manufacturing Settings',
+			'make_serial_no_batch_from_work_order', cache=True)):
 			self.set_batchwise_finished_goods(args, item)
 		else:
-			self.add_finisged_goods(args, item)
+			self.add_finished_goods(args, item)
 
 	def set_batchwise_finished_goods(self, args, item):
-		qty = flt(self.fg_completed_qty)
 		filters = {
 			"reference_name": self.pro_doc.name,
 			"reference_doctype": self.pro_doc.doctype,
@@ -1105,7 +1109,17 @@
 
 		fields = ["qty_to_produce as qty", "produced_qty", "name"]
 
-		for row in frappe.get_all("Batch", filters = filters, fields = fields, order_by="creation asc"):
+		data = frappe.get_all("Batch", filters = filters, fields = fields, order_by="creation asc")
+
+		if not data:
+			self.add_finished_goods(args, item)
+		else:
+			self.add_batchwise_finished_good(data, args, item)
+
+	def add_batchwise_finished_good(self, data, args, item):
+		qty = flt(self.fg_completed_qty)
+
+		for row in data:
 			batch_qty = flt(row.qty) - flt(row.produced_qty)
 			if not batch_qty:
 				continue
@@ -1121,9 +1135,9 @@
 			args["qty"] = fg_qty
 			args["batch_no"] = row.name
 
-			self.add_finisged_goods(args, item)
+			self.add_finished_goods(args, item)
 
-	def add_finisged_goods(self, args, item):
+	def add_finished_goods(self, args, item):
 		self.add_to_stock_entry_detail({
 			item.name: args
 		}, bom_no = self.bom_no)
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 3e15d54..9875491 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -405,17 +405,18 @@
 
 			key = (d.item_code, d.warehouse)
 			if key not in merge_similar_entries:
+				d.total_amount = (d.actual_qty * d.valuation_rate)
 				merge_similar_entries[key] = d
 			elif d.serial_no:
 				data = merge_similar_entries[key]
 				data.actual_qty += d.actual_qty
 				data.qty_after_transaction += d.qty_after_transaction
 
-				data.valuation_rate = (data.valuation_rate + d.valuation_rate) / data.actual_qty
+				data.total_amount += (d.actual_qty * d.valuation_rate)
+				data.valuation_rate = (data.total_amount) / data.actual_qty
 				data.serial_no += '\n' + d.serial_no
 
-				if data.incoming_rate:
-					data.incoming_rate = (data.incoming_rate + d.incoming_rate) / data.actual_qty
+				data.incoming_rate = (data.total_amount) / data.actual_qty
 
 		for key, value in merge_similar_entries.items():
 			new_sl_entries.append(value)
diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
index cbe413b..c192582 100644
--- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
@@ -6,7 +6,7 @@
 
 from __future__ import unicode_literals
 import frappe, unittest
-from frappe.utils import flt, nowdate, nowtime, add_days
+from frappe.utils import flt, nowdate, nowtime, random_string, add_days
 from erpnext.accounts.utils import get_stock_and_account_balance
 from erpnext.stock.stock_ledger import get_previous_sle, update_entries_after
 from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError, get_items
@@ -152,6 +152,42 @@
 			stock_doc = frappe.get_doc("Stock Reconciliation", d)
 			stock_doc.cancel()
 
+
+	def test_stock_reco_for_merge_serialized_item(self):
+		to_delete_records = []
+
+		# Add new serial nos
+		serial_item_code = "Stock-Reco-Serial-Item-2"
+		serial_warehouse = "_Test Warehouse for Stock Reco1 - _TC"
+
+		sr = create_stock_reconciliation(item_code=serial_item_code, serial_no=random_string(6),
+			warehouse = serial_warehouse, qty=1, rate=100, do_not_submit=True, purpose='Opening Stock')
+
+		for i in range(3):
+			sr.append('items', {
+				'item_code': serial_item_code,
+				'warehouse': serial_warehouse,
+				'qty': 1,
+				'valuation_rate': 100,
+				'serial_no': random_string(6)
+			})
+
+		sr.save()
+		sr.submit()
+
+		sle_entries = frappe.get_all('Stock Ledger Entry', filters= {'voucher_no': sr.name},
+			fields = ['name', 'incoming_rate'])
+
+		self.assertEqual(len(sle_entries), 1)
+		self.assertEqual(sle_entries[0].incoming_rate, 100)
+
+		to_delete_records.append(sr.name)
+		to_delete_records.reverse()
+
+		for d in to_delete_records:
+			stock_doc = frappe.get_doc("Stock Reconciliation", d)
+			stock_doc.cancel()
+
 	def test_stock_reco_for_batch_item(self):
 		to_delete_records = []
 		to_delete_serial_nos = []
@@ -364,6 +400,12 @@
 		serial_item_doc.serial_no_series = "SRSI.####"
 		serial_item_doc.save(ignore_permissions=True)
 
+	serial_item_doc = create_item("Stock-Reco-Serial-Item-2", is_stock_item=1)
+	if not serial_item_doc.has_serial_no:
+		serial_item_doc.has_serial_no = 1
+		serial_item_doc.serial_no_series = "SRSII.####"
+		serial_item_doc.save(ignore_permissions=True)
+
 	batch_item_doc = create_item("Stock-Reco-batch-Item-1", is_stock_item=1)
 	if not batch_item_doc.has_batch_no:
 		batch_item_doc.has_batch_no = 1
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index ca174a3..4657700 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -441,7 +441,7 @@
 
 	if item_tax_templates is None:
 		item_tax_templates = {}
-	
+
 	if item_rates is None:
 		item_rates = {}
 
@@ -807,10 +807,14 @@
 def validate_conversion_rate(args, meta):
 	from erpnext.controllers.accounts_controller import validate_conversion_rate
 
-	if (not args.conversion_rate
-		and args.currency==frappe.get_cached_value('Company',  args.company,  "default_currency")):
+	company_currency = frappe.get_cached_value('Company',  args.company,  "default_currency")
+	if (not args.conversion_rate and args.currency==company_currency):
 		args.conversion_rate = 1.0
 
+	if (not args.ignore_conversion_rate and args.conversion_rate == 1 and args.currency!=company_currency):
+		args.conversion_rate = get_exchange_rate(args.currency,
+			company_currency, args.transaction_date, "for_buying") or 1.0
+
 	# validate currency conversion rate
 	validate_conversion_rate(args.currency, args.conversion_rate,
 		meta.get_label("conversion_rate"), args.company)
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index 8a6a3a3..b57b2aa 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -314,13 +314,16 @@
 	for row_idx, row in enumerate(result):
 		data = row.items() if is_dict_obj else enumerate(row)
 		for key, value in data:
-			if key not in convertible_columns or not conversion_factors[row_idx-1]:
+			if key not in convertible_columns:
 				continue
+			# If no conversion factor for the UOM, defaults to 1
+			if not conversion_factors[row_idx]:
+				conversion_factors[row_idx] = 1
 
 			if convertible_columns.get(key) == 'rate':
-				new_value = flt(value) * conversion_factors[row_idx-1]
+				new_value = flt(value) * conversion_factors[row_idx]
 			else:
-				new_value = flt(value) / conversion_factors[row_idx-1]
+				new_value = flt(value) / conversion_factors[row_idx]
 
 			if not is_dict_obj:
 				row.insert(key+1, new_value)
@@ -386,4 +389,4 @@
 	reposting_in_progress = frappe.db.exists("Repost Item Valuation",
 		{'docstatus': 1, 'status': ['in', ['Queued','In Progress']]})
 	if reposting_in_progress:
-		frappe.msgprint(_("Item valuation reposting in progress. Report might show incorrect item valuation."), alert=1)
\ No newline at end of file
+		frappe.msgprint(_("Item valuation reposting in progress. Report might show incorrect item valuation."), alert=1)
diff --git a/erpnext/templates/includes/projects/project_timesheets.html b/erpnext/templates/includes/projects/project_timesheets.html
index fa5b2f9..b8e0682 100644
--- a/erpnext/templates/includes/projects/project_timesheets.html
+++ b/erpnext/templates/includes/projects/project_timesheets.html
@@ -12,7 +12,7 @@
           .get_value("User", timesheet.modified_by, [
             "full_name", "user_image"
           ], as_dict = True)
- %}
+ 		    %}
         {% if user_details.user_image %}
           <span class="avatar avatar-small" style="width:32px; height:32px;" title="{{ user_details.full_name }}">
             <img src="{{ user_details.user_image }}">