fix: merge conflict
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index d031bc5..f40b957 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__ = '12.1.8'
+__version__ = '12.2.0'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 75107b0..3bb3df8 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -357,7 +357,7 @@
 			return
 		if not gl_entries:
 			gl_entries = self.get_gl_entries()
-			
+
 		if gl_entries:
 			update_outstanding = "No" if (cint(self.is_paid) or self.write_off_account) else "Yes"
 
@@ -507,7 +507,7 @@
 				elif not item.is_fixed_asset or (item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category)):
 					expense_account = (item.expense_account
 						if (not item.enable_deferred_expense or self.is_return) else item.deferred_expense_account)
-					
+
 					if not item.is_fixed_asset:
 						amount = flt(item.base_net_amount, item.precision("base_net_amount"))
 					else:
@@ -520,7 +520,7 @@
 							"cost_center": item.cost_center,
 							"project": item.project
 						}, account_currency, item=item))
-					
+
 					# If asset is bought through this document and not linked to PR
 					if self.update_stock and item.landed_cost_voucher_amount:
 						expenses_included_in_asset_valuation = self.get_company_default("expenses_included_in_asset_valuation")
@@ -542,9 +542,9 @@
 							"debit": flt(item.landed_cost_voucher_amount),
 							"project": item.project
 						}, item=item))
-						
+
 						# update gross amount of asset bought through this document
-						assets = frappe.db.get_all('Asset', 
+						assets = frappe.db.get_all('Asset',
 							filters={ 'purchase_invoice': self.name, 'item_code': item.item_code }
 						)
 						for asset in assets:
@@ -636,7 +636,7 @@
 								if asset_eiiav_currency == self.company_currency else
 									item.item_tax_amount / self.conversion_rate)
 						}, item=item))
-					
+
 					# When update stock is checked
 					# Assets are bought through this document then it will be linked to this document
 					if self.update_stock:
@@ -658,9 +658,9 @@
 								"debit": flt(item.landed_cost_voucher_amount),
 								"project": item.project
 							}, item=item))
-						
+
 						# update gross amount of assets bought through this document
-						assets = frappe.db.get_all('Asset', 
+						assets = frappe.db.get_all('Asset',
 							filters={ 'purchase_invoice': self.name, 'item_code': item.item_code }
 						)
 						for asset in assets:
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 7a48fcc..2ba319d 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -185,7 +185,7 @@
 					raise_exception=StockValueAndAccountBalanceOutOfSync,
 					title=_('Values Out Of Sync'),
 					primary_action={
-						'label': 'Make Journal Entry',
+						'label': _('Make Journal Entry'),
 						'client_action': 'erpnext.route_to_adjustment_jv',
 						'args': journal_entry_args
 					})
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 382a89b..94697be 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -630,7 +630,7 @@
 			'select name from `tabPurchase Invoice` where release_date IS NOT NULL and release_date > CURDATE()',
 			as_dict=1
 		)
-		held_invoices = [d['name'] for d in held_invoices]
+		held_invoices = set([d['name'] for d in held_invoices])
 
 	return held_invoices
 
@@ -639,14 +639,19 @@
 	outstanding_invoices = []
 	precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
 
-	if erpnext.get_party_account_type(party_type) == 'Receivable':
+	if account:
+		root_type = frappe.get_cached_value("Account", account, "root_type")
+		party_account_type = "Receivable" if root_type == "Asset" else "Payable"
+	else:
+		party_account_type = erpnext.get_party_account_type(party_type)
+
+	if party_account_type == 'Receivable':
 		dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
 		payment_dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
 	else:
 		dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
 		payment_dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
 
-	invoice = 'Sales Invoice' if erpnext.get_party_account_type(party_type) == 'Receivable' else 'Purchase Invoice'
 	held_invoices = get_held_invoices(party_type, party)
 
 	invoice_list = frappe.db.sql("""
@@ -665,7 +670,6 @@
 		group by voucher_type, voucher_no
 		order by posting_date, name""".format(
 			dr_or_cr=dr_or_cr,
-			invoice = invoice,
 			condition=condition or ""
 		), {
 			"party_type": party_type,
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 546f374..40f1e1e 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -33,7 +33,7 @@
 		self.make_asset_movement()
 		if not self.booked_fixed_asset and is_cwip_accounting_enabled(self.asset_category):
 			self.make_gl_entries()
-		
+
 	def before_cancel(self):
 		self.cancel_auto_gen_movement()
 
@@ -43,7 +43,7 @@
 		self.set_status()
 		delete_gl_entries(voucher_type='Asset', voucher_no=self.name)
 		self.db_set('booked_fixed_asset', 0)
-	
+
 	def validate_asset_and_reference(self):
 		if self.purchase_invoice or self.purchase_receipt:
 			reference_doc = 'Purchase Invoice' if self.purchase_invoice else 'Purchase Receipt'
@@ -51,8 +51,8 @@
 			reference_doc = frappe.get_doc(reference_doc, reference_name)
 			if reference_doc.get('company') != self.company:
 				frappe.throw(_("Company of asset {0} and purchase document {1} doesn't matches.").format(self.name, reference_doc.get('name')))
-		
-		
+
+
 		if self.is_existing_asset and self.purchase_invoice:
 			frappe.throw(_("Purchase Invoice cannot be made against an existing asset {0}").format(self.name))
 
@@ -125,15 +125,17 @@
 			frappe.throw(_("Available-for-use Date should be after purchase date"))
 
 	def cancel_auto_gen_movement(self):
-		reference_docname = self.purchase_invoice or self.purchase_receipt
-		movement = frappe.db.get_all('Asset Movement', filters={ 'reference_name': reference_docname, 'docstatus': 1 })
-		if len(movement) > 1:
+		movements = frappe.db.sql(
+			"""SELECT asm.name, asm.docstatus
+			FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
+			WHERE asm_item.parent=asm.name and asm_item.asset=%s and asm.docstatus=1""", self.name, as_dict=1)
+		if len(movements) > 1:
 			frappe.throw(_('Asset has multiple Asset Movement Entries which has to be \
 				cancelled manually to cancel this asset.'))
-		movement = frappe.get_doc('Asset Movement', movement[0].get('name'))
+		movement = frappe.get_doc('Asset Movement', movements[0].get('name'))
 		movement.flags.ignore_validate = True
 		movement.cancel()
-		
+
 	def make_asset_movement(self):
 		reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
 		reference_docname = self.purchase_receipt or self.purchase_invoice
@@ -202,7 +204,7 @@
 				if has_pro_rata and n==0:
 					depreciation_amount, days, months = get_pro_rata_amt(d, depreciation_amount,
 						self.available_for_use_date, d.depreciation_start_date)
-					
+
 					# For first depr schedule date will be the start date
 					# so monthly schedule date is calculated by removing month difference between use date and start date
 					monthly_schedule_date = add_months(d.depreciation_start_date, - months + 1)
@@ -260,7 +262,7 @@
 							else:
 								date = add_months(monthly_schedule_date, r)
 								amount = depreciation_amount / month_range
-							
+
 							self.append("schedules", {
 								"schedule_date": date,
 								"depreciation_amount": amount,
@@ -650,31 +652,18 @@
 def make_asset_movement(assets, purpose=None):
 	import json
 	from six import string_types
-	
+
 	if isinstance(assets, string_types):
 		assets = json.loads(assets)
-	
+
 	if len(assets) == 0:
 		frappe.throw(_('Atleast one asset has to be selected.'))
 
 	asset_movement = frappe.new_doc("Asset Movement")
-	asset_movement.purpose = purpose
-	prev_reference_docname = ''
-
+	asset_movement.quantity = len(assets)
 	for asset in assets:
 		asset = frappe.get_doc('Asset', asset.get('name'))
-		# get PR/PI linked with asset
-		reference_docname = asset.get('purchase_receipt') if asset.get('purchase_receipt') \
-				else asset.get('purchase_invoice')
-		# checks if all the assets are linked with a single PR/PI
-		if prev_reference_docname == '':
-			prev_reference_docname = reference_docname
-		elif prev_reference_docname != reference_docname:
-			frappe.throw(_('Assets selected should belong to same reference document.'))
-
 		asset_movement.company = asset.get('company')
-		asset_movement.reference_doctype = 'Purchase Receipt' if asset.get('purchase_receipt') else 'Purchase Invoice'
-		asset_movement.reference_name = prev_reference_docname
 		asset_movement.append("assets", {
 			'asset': asset.get('name'),
 			'source_location': asset.get('location'),
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.js b/erpnext/assets/doctype/asset_movement/asset_movement.js
index 89977e2..06d8879 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.js
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.js
@@ -31,6 +31,13 @@
 					name: ["in", ["Purchase Receipt", "Purchase Invoice"]]
 				}
 			};
+		}),
+		frm.set_query("asset", "assets", () => {
+			return {
+				filters: {
+					status: ["not in", ["Draft"]]
+				}
+			}
 		})
 	},
 
@@ -76,50 +83,6 @@
 			});
 		});
 		frm.refresh_field('assets');
-	},
-
-	reference_name: function(frm) {
-		if (frm.doc.reference_name && frm.doc.reference_doctype) {
-			const reference_doctype = frm.doc.reference_doctype === 'Purchase Invoice' ? 'purchase_invoice' : 'purchase_receipt';
-			// On selection of reference name,
-			// sets query to display assets linked to that reference doc
-			frm.set_query('asset', 'assets', function() {
-				return {
-					filters: {
-						[reference_doctype] : frm.doc.reference_name
-					}
-				};
-			});
-
-			// fetches linked asset & adds to the assets table
-			frappe.db.get_list('Asset', {
-				fields: ['name', 'location', 'custodian'],
-				filters: {
-					[reference_doctype] : frm.doc.reference_name
-				}
-			}).then((docs) => {
-				if (docs.length == 0) {
-					frappe.msgprint(frappe._(`Please select ${frm.doc.reference_doctype} which has assets.`));
-					frm.doc.reference_name = '';
-					frm.refresh_field('reference_name');
-					return;
-				}
-				frm.doc.assets = [];
-				docs.forEach(doc => {
-					frm.add_child('assets', {
-						asset: doc.name,
-						source_location: doc.location,
-						from_employee: doc.custodian
-					});
-					frm.refresh_field('assets');
-				})
-			}).catch((err) => {
-				console.log(err); // eslint-disable-line
-			});
-		} else {
-			// if reference is deleted then remove query
-			frm.set_query('asset', 'assets', () => ({ filters: {} }));
-		}
 	}
 });
 
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.json b/erpnext/assets/doctype/asset_movement/asset_movement.json
index e62d684..3472ab5 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.json
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.json
@@ -9,12 +9,12 @@
   "purpose",
   "column_break_4",
   "transaction_date",
+  "section_break_10",
+  "assets",
   "reference",
   "reference_doctype",
   "column_break_9",
   "reference_name",
-  "section_break_10",
-  "assets",
   "amended_from"
  ],
  "fields": [
@@ -47,6 +47,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "collapsible": 1,
    "fieldname": "reference",
    "fieldtype": "Section Break",
    "label": "Reference"
@@ -54,18 +55,16 @@
   {
    "fieldname": "reference_doctype",
    "fieldtype": "Link",
-   "label": "Reference Document",
+   "label": "Reference Document Type",
    "no_copy": 1,
-   "options": "DocType",
-   "reqd": 1
+   "options": "DocType"
   },
   {
    "fieldname": "reference_name",
    "fieldtype": "Dynamic Link",
    "label": "Reference Document Name",
    "no_copy": 1,
-   "options": "reference_doctype",
-   "reqd": 1
+   "options": "reference_doctype"
   },
   {
    "fieldname": "amended_from",
@@ -93,7 +92,7 @@
   }
  ],
  "is_submittable": 1,
- "modified": "2019-11-21 14:35:51.880332",
+ "modified": "2019-11-23 13:28:47.256935",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Movement",
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.py b/erpnext/assets/doctype/asset_movement/asset_movement.py
index 714845d..4e1822b 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.py
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.py
@@ -22,7 +22,7 @@
 			if company != self.company:
 				frappe.throw(_("Asset {0} does not belong to company {1}").format(d.asset, self.company))
 
-			if not(d.source_location or d.target_location or d.from_employee or d.to_employee):
+			if not (d.source_location or d.target_location or d.from_employee or d.to_employee):
 				frappe.throw(_("Either location or employee must be required"))
 
 	def validate_location(self):
diff --git a/erpnext/change_log/v12/v12_2_0.md b/erpnext/change_log/v12/v12_2_0.md
new file mode 100644
index 0000000..0ec0eec
--- /dev/null
+++ b/erpnext/change_log/v12/v12_2_0.md
@@ -0,0 +1,14 @@
+# Version 12.2.0 Release Notes
+
+### Accounting
+
+1. Fixed Asset
+	- "Enable CWIP" options moved to Asset Category from Asset Settings
+	- Removed Asset link from Purchase Receipt Item table
+	- Enhanced Asset master
+	- Asset Movement now handles movement of multiple assets
+	- Introduced monthly depreciation
+2. GL Entries for Landed Cost Voucher now posted directly against individual Charges account
+3. Optimization of BOM Update Tool
+4. Syncing of Stock and Account balance is enforced, in case of perpetual inventory
+5. Rendered email template in Email Campaign
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 3392850..d12643a 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -641,7 +641,10 @@
 					asset = frappe.get_doc('Asset', asset.name)
 					if delete_asset and is_auto_create_enabled:
 						# need to delete movements to delete assets otherwise throws link exists error
-						movements = frappe.db.get_all('Asset Movement', filters={ 'reference_name': self.name })
+						movements = frappe.db.sql(
+							"""SELECT asm.name 
+							FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
+							WHERE asm_item.parent=asm.name and asm_item.asset=%s""", asset.name, as_dict=1)
 						for movement in movements:
 							frappe.delete_doc('Asset Movement', movement.name, force=1)
 						frappe.delete_doc("Asset", asset.name, force=1)
@@ -652,8 +655,12 @@
 						asset.purchase_date = self.posting_date
 						asset.supplier = self.supplier
 					elif self.docstatus == 2:
-						asset.set(field, None)
-						asset.supplier = None
+						if asset.docstatus == 0:
+							asset.set(field, None)
+							asset.supplier = None
+						if asset.docstatus == 1 and delete_asset:
+							frappe.throw(_('Cannot cancel this document as it is linked with submitted asset {0}.\
+								Please cancel the it to continue.').format(asset.name))
 
 					asset.flags.ignore_validate_update_after_submit = True
 					asset.flags.ignore_mandatory = True
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index f003627..5939150 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -140,32 +140,6 @@
 					"against": ",".join([d.default_account for d in self.expenses]),
 					"party_type": "Employee",
 					"party": self.employee,
-					"against_voucher_type": self.doctype,
-					"against_voucher": self.name
-				})
-			)
-
-			gl_entry.append(
-				self.get_gl_dict({
-					"account": data.advance_account,
-					"debit": data.allocated_amount,
-					"debit_in_account_currency": data.allocated_amount,
-					"against": self.payable_account,
-					"party_type": "Employee",
-					"party": self.employee,
-					"against_voucher_type": self.doctype,
-					"against_voucher": self.name
-				})
-			)
-
-			gl_entry.append(
-				self.get_gl_dict({
-					"account": self.payable_account,
-					"credit": data.allocated_amount,
-					"credit_in_account_currency": data.allocated_amount,
-					"against": data.advance_account,
-					"party_type": "Employee",
-					"party": self.employee,
 					"against_voucher_type": "Employee Advance",
 					"against_voucher": data.employee_advance
 				})
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 54fce8d..7083d69 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -7,7 +7,7 @@
 
 import frappe
 from frappe import _, throw
-from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate
+from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate, today
 from frappe.utils.nestedset import NestedSet
 from frappe.desk.form.assign_to import close_all_assignments, clear
 from frappe.utils import date_diff
@@ -212,8 +212,11 @@
 		task.save()
 
 def set_tasks_as_overdue():
-	tasks = frappe.get_all("Task", filters={'status':['not in',['Cancelled', 'Completed']]})
+	tasks = frappe.get_all("Task", filters={'status':['not in',['Cancelled', 'Closed']]})
 	for task in tasks:
+		if frappe.db.get_value("Task", task.name, "status") in 'Pending Review':
+			if getdate(frappe.db.get_value("Task", task.name, "review_date")) < getdate(today()):
+				continue
 		frappe.get_doc("Task", task.name).update_status()
 
 @frappe.whitelist()