Depreciation Schedule considering already booked depreciations for existing asset and testcases
diff --git a/erpnext/accounts/doctype/asset/asset.js b/erpnext/accounts/doctype/asset/asset.js
index 548de08..0dfdb21 100644
--- a/erpnext/accounts/doctype/asset/asset.js
+++ b/erpnext/accounts/doctype/asset/asset.js
@@ -60,7 +60,8 @@
 			"asset": frm.doc.name,
 			"item_code": frm.doc.item_code,
 			"gross_purchase_amount": frm.doc.gross_purchase_amount,
-			"company": frm.doc.company
+			"company": frm.doc.company,
+			"posting_date": frm.doc.purchase_date
 		},
 		method: "erpnext.accounts.doctype.asset.asset.make_purchase_invoice",
 		callback: function(r) {
diff --git a/erpnext/accounts/doctype/asset/asset.json b/erpnext/accounts/doctype/asset/asset.json
index cf03bf6..826f70e 100644
--- a/erpnext/accounts/doctype/asset/asset.json
+++ b/erpnext/accounts/doctype/asset/asset.json
@@ -398,14 +398,14 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "number_of_depreciations", 
+   "fieldname": "total_number_of_depreciations", 
    "fieldtype": "Int", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Number of Depreciations", 
+   "label": "Total Number of Depreciations", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -423,6 +423,32 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "depends_on": "eval:(doc.is_existing_asset && doc.opening_accumulated_depreciation)", 
+   "fieldname": "number_of_depreciations_booked", 
+   "fieldtype": "Int", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Number of Depreciations Booked", 
+   "length": 0, 
+   "no_copy": 1, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "frequency_of_depreciation", 
    "fieldtype": "Int", 
    "hidden": 0, 
@@ -686,7 +712,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-04-08 18:42:52.810809", 
+ "modified": "2016-04-20 15:46:49.479769", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Asset", 
@@ -714,6 +740,7 @@
    "write": 1
   }
  ], 
+ "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 1, 
  "sort_field": "modified", 
diff --git a/erpnext/accounts/doctype/asset/asset.py b/erpnext/accounts/doctype/asset/asset.py
index 1807d70..fff493e 100644
--- a/erpnext/accounts/doctype/asset/asset.py
+++ b/erpnext/accounts/doctype/asset/asset.py
@@ -8,7 +8,8 @@
 from frappe.utils import flt, add_months, cint, nowdate, getdate
 from frappe.model.document import Document
 from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import get_fixed_asset_account
-from erpnext.accounts.doctype.asset.depreciation import get_disposal_account_and_cost_center
+from erpnext.accounts.doctype.asset.depreciation \
+	import get_disposal_account_and_cost_center, get_depreciation_accounts
 
 class Asset(Document):
 	def validate(self):
@@ -17,7 +18,8 @@
 		self.validate_asset_values()
 		self.set_depreciation_settings()
 		self.make_depreciation_schedule()
-		self.validate_depreciation_settings_in_company()
+		# Validate depreciation related accounts
+		get_depreciation_accounts(self)
 
 	def on_submit(self):
 		self.set_status()
@@ -43,6 +45,7 @@
 		
 		if not self.is_existing_asset:
 			self.opening_accumulated_depreciation = 0
+			self.number_of_depreciations_booked = 0
 			if not self.next_depreciation_date:
 				frappe.throw(_("Next Depreciation Date is mandatory for new asset"))
 		else:
@@ -51,14 +54,28 @@
 					frappe.throw(_("Opening Accumulated Depreciation must be less than equal to {0}")
 						.format(depreciable_amount))
 						
+			if self.opening_accumulated_depreciation:
+				if not self.number_of_depreciations_booked:
+					frappe.throw(_("Please set Number of Depreciations Booked"))
+			else:
+				self.number_of_depreciations_booked = 0
+				
+			if cint(self.number_of_depreciations_booked) > cint(self.total_number_of_depreciations):
+				frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations"))
+						
 		if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(nowdate()):
 			frappe.throw(_("Next Depreciation Date must be on or after today"))
+			
+		if (flt(self.value_after_depreciation) > flt(self.expected_value_after_useful_life) 
+			and not self.next_depreciation_date):
+				frappe.throw(_("Please set Next Depreciation Date"))
+			
 		
 
 	def set_depreciation_settings(self):
 		asset_category = frappe.get_doc("Asset Category", self.asset_category)
 
-		for field in ("depreciation_method", "number_of_depreciations", "frequency_of_depreciation"):
+		for field in ("depreciation_method", "total_number_of_depreciations", "frequency_of_depreciation"):
 			if not self.get(field):
 				self.set(field, asset_category.get(field))
 
@@ -67,27 +84,32 @@
 		if not self.get("schedules") and self.next_depreciation_date:
 			accumulated_depreciation = flt(self.opening_accumulated_depreciation)
 			value_after_depreciation = flt(self.value_after_depreciation)
-			for n in xrange(self.number_of_depreciations):
-				schedule_date = add_months(self.next_depreciation_date,
-					n * cint(self.frequency_of_depreciation))
+			
+			number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \
+				cint(self.number_of_depreciations_booked)
+			if number_of_pending_depreciations:
+				for n in xrange(number_of_pending_depreciations):
+					schedule_date = add_months(self.next_depreciation_date,
+						n * cint(self.frequency_of_depreciation))
 
-				depreciation_amount = self.get_depreciation_amount(value_after_depreciation)
+					depreciation_amount = self.get_depreciation_amount(value_after_depreciation)
 				
-				accumulated_depreciation += flt(depreciation_amount)
-				value_after_depreciation -= flt(depreciation_amount)
+					accumulated_depreciation += flt(depreciation_amount)
+					value_after_depreciation -= flt(depreciation_amount)
 
-				self.append("schedules", {
-					"schedule_date": schedule_date,
-					"depreciation_amount": depreciation_amount,
-					"accumulated_depreciation_amount": accumulated_depreciation
-				})
+					self.append("schedules", {
+						"schedule_date": schedule_date,
+						"depreciation_amount": depreciation_amount,
+						"accumulated_depreciation_amount": accumulated_depreciation
+					})
 
 	def get_depreciation_amount(self, depreciable_value):
 		if self.depreciation_method == "Straight Line":
 			depreciation_amount = (flt(self.value_after_depreciation) -
-				flt(self.expected_value_after_useful_life)) / cint(self.number_of_depreciations)
+				flt(self.expected_value_after_useful_life)) / (cint(self.total_number_of_depreciations) - 
+				cint(self.number_of_depreciations_booked))
 		else:
-			factor = 200.0 /  cint(self.number_of_depreciations)
+			factor = 200.0 /  self.total_number_of_depreciations
 			depreciation_amount = flt(depreciable_value * factor / 100, 0)
 
 			value_after_depreciation = flt(depreciable_value) - depreciation_amount
@@ -112,14 +134,6 @@
 		self.db_set("value_after_depreciation", 
 			(flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)))
 
-	def validate_depreciation_settings_in_company(self):
-		company = frappe.get_doc("Company", self.company)
-		for field in ("accumulated_depreciation_account", "depreciation_expense_account",
-			"disposal_account", "depreciation_cost_center"):
-				if not company.get(field):
-					frappe.throw(_("Please set {0} in Company {1}")
-						.format(company.meta.get_label(field), self.company))
-
 	def set_status(self, status=None):
 		'''Get and update status'''
 		if not status:
@@ -144,10 +158,11 @@
 		return status
 
 @frappe.whitelist()
-def make_purchase_invoice(asset, item_code, gross_purchase_amount, company):
+def make_purchase_invoice(asset, item_code, gross_purchase_amount, company, posting_date):
 	pi = frappe.new_doc("Purchase Invoice")
 	pi.company = company
 	pi.currency = frappe.db.get_value("Company", company, "default_currency")
+	pi.posting_date = posting_date
 	pi.append("items", {
 		"item_code": item_code,
 		"is_fixed_asset": 1,
diff --git a/erpnext/accounts/doctype/asset/test_asset.py b/erpnext/accounts/doctype/asset/test_asset.py
index ea1d6a2..2753e15 100644
--- a/erpnext/accounts/doctype/asset/test_asset.py
+++ b/erpnext/accounts/doctype/asset/test_asset.py
@@ -18,14 +18,15 @@
 		asset = frappe.get_doc("Asset", "Macbook Pro 1")
 		asset.submit()
 		
-		pi = make_purchase_invoice(asset.name, asset.item_code, asset.gross_purchase_amount, asset.company)
+		pi = make_purchase_invoice(asset.name, asset.item_code, asset.gross_purchase_amount, 
+			asset.company, asset.purchase_date)
 		pi.supplier = "_Test Supplier"
 		pi.insert()
 		pi.submit()
 		
 		asset.load_from_db()
 		self.assertEqual(asset.supplier, "_Test Supplier")
-		self.assertEqual(getdate(asset.purchase_date), getdate(nowdate()))
+		self.assertEqual(asset.purchase_date, getdate("2015-01-01"))
 		self.assertEqual(asset.purchase_invoice, pi.name)
 		
 		expected_gle = (
@@ -43,7 +44,6 @@
 
 		asset.load_from_db()
 		self.assertEqual(asset.supplier, None)
-		self.assertEqual(asset.purchase_date, None)
 		self.assertEqual(asset.purchase_invoice, None)
 		
 		self.assertFalse(frappe.db.get_value("GL Entry", 
@@ -65,6 +65,25 @@
 			for d in asset.get("schedules")]
 
 		self.assertEqual(schedules, expected_schedules)
+		
+	def test_schedule_for_straight_line_method_for_existing_asset(self):
+		asset = frappe.get_doc("Asset", "Macbook Pro 1")
+		asset.is_existing_asset = 1
+		asset.number_of_depreciations_booked = 1
+		asset.opening_accumulated_depreciation = 40000
+		asset.save()
+		
+		self.assertEqual(asset.status, "Draft")
+
+		expected_schedules = [
+			["2020-12-31", 25000, 65000],
+			["2021-03-31", 25000, 90000]
+		]
+
+		schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
+			for d in asset.get("schedules")]
+
+		self.assertEqual(schedules, expected_schedules)
 
 
 	def test_schedule_for_double_declining_method(self):
@@ -82,6 +101,24 @@
 			for d in asset.get("schedules")]
 
 		self.assertEqual(schedules, expected_schedules)
+		
+	def test_schedule_for_double_declining_method_for_existing_asset(self):
+		asset = frappe.get_doc("Asset", "Macbook Pro 1")
+		asset.depreciation_method = "Double Declining Balance"
+		asset.is_existing_asset = 1
+		asset.number_of_depreciations_booked = 1
+		asset.opening_accumulated_depreciation = 50000
+		asset.save()
+
+		expected_schedules = [
+			["2020-12-31", 33333, 83333],
+			["2021-03-31", 6667, 90000]
+		]
+
+		schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
+			for d in asset.get("schedules")]
+
+		self.assertEqual(schedules, expected_schedules)
 
 	def test_depreciation(self):
 		asset = frappe.get_doc("Asset", "Macbook Pro 1")
@@ -204,7 +241,7 @@
 def create_asset_category():
 	asset_category = frappe.new_doc("Asset Category")
 	asset_category.asset_category_name = "Computers"
-	asset_category.number_of_depreciations = 3
+	asset_category.total_number_of_depreciations = 3
 	asset_category.frequency_of_depreciation = 3
 	asset_category.append("accounts", {
 		"company_name": "_Test Company",
diff --git a/erpnext/accounts/doctype/asset_category/asset_category.json b/erpnext/accounts/doctype/asset_category/asset_category.json
index ccdb675..20dd247 100644
--- a/erpnext/accounts/doctype/asset_category/asset_category.json
+++ b/erpnext/accounts/doctype/asset_category/asset_category.json
@@ -89,14 +89,14 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "number_of_depreciations", 
+   "fieldname": "total_number_of_depreciations", 
    "fieldtype": "Int", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Number of Depreciations", 
+   "label": "Total Number of Depreciations", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -196,7 +196,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-04-07 18:16:57.343260", 
+ "modified": "2016-04-20 13:23:09.890324", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Asset Category", 
@@ -244,6 +244,7 @@
    "write": 1
   }
  ], 
+ "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
  "sort_field": "modified", 
diff --git a/erpnext/accounts/doctype/asset_category/asset_category.py b/erpnext/accounts/doctype/asset_category/asset_category.py
index f46dc84..5279c37 100644
--- a/erpnext/accounts/doctype/asset_category/asset_category.py
+++ b/erpnext/accounts/doctype/asset_category/asset_category.py
@@ -10,6 +10,6 @@
 
 class AssetCategory(Document):
 	def validate(self):
-		for field in ("number_of_depreciations", "frequency_of_depreciation"):
+		for field in ("total_number_of_depreciations", "frequency_of_depreciation"):
 			if cint(self.get(field))<1:
 				frappe.throw(_("{0} must be greater than 0").format(self.meta.get_label(field)), frappe.MandatoryError)
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/asset_category/test_asset_category.py b/erpnext/accounts/doctype/asset_category/test_asset_category.py
index 624e019..b32f9b5 100644
--- a/erpnext/accounts/doctype/asset_category/test_asset_category.py
+++ b/erpnext/accounts/doctype/asset_category/test_asset_category.py
@@ -13,7 +13,7 @@
 		
 		self.assertRaises(frappe.MandatoryError, asset_category.insert)
 		
-		asset_category.number_of_depreciations = 3
+		asset_category.total_number_of_depreciations = 3
 		asset_category.frequency_of_depreciation = 3
 		asset_category.append("accounts", {
 			"company_name": "_Test Company",
diff --git a/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.json b/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.json
index 50fba88..dc854b2 100644
--- a/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.json
+++ b/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.json
@@ -146,15 +146,17 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-03-09 12:21:27.938215", 
+ "modified": "2016-04-20 16:43:21.407123", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Depreciation Schedule", 
  "name_case": "", 
  "owner": "Administrator", 
  "permissions": [], 
+ "quick_entry": 1, 
  "read_only": 0, 
  "read_only_onload": 0, 
  "sort_field": "modified", 
- "sort_order": "DESC"
+ "sort_order": "DESC", 
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 65c8c02..b31c1ab 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -322,7 +322,6 @@
 					asset.supplier = self.supplier
 				else:
 					asset.purchase_invoice = None
-					asset.purchase_date = None
 					asset.supplier = None
 					
 				asset.flags.ignore_validate_update_after_submit = True
diff --git a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
index d651892..890833b 100644
--- a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
+++ b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
@@ -29,13 +29,13 @@
 			
 		row.update(asset_depreciations.get(asset_category))
 		row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) + 
-			flt(row.depreciation_amount_during_the_period))
-			
+			flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated))
+		
 		row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) - 
 			flt(row.accumulated_depreciation_as_on_from_date))
-			
+		
 		row.net_asset_value_as_on_to_date = (flt(row.cost_as_on_to_date) - 
-			flt(row.accumulated_depreciation_as_on_to_date) - flt(row.depreciation_eliminated))
+			flt(row.accumulated_depreciation_as_on_to_date))
 	
 		data.append(row)
 		
@@ -89,19 +89,20 @@
 		asset_depreciations.setdefault(d.asset_category, frappe._dict({
 			"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
 			"depreciation_amount_during_the_period": 0,
-			"depreciation_eliminated": 0
+			"depreciation_eliminated_during_the_period": 0
 		}))
 		
 		depr = asset_depreciations[d.asset_category]
 		
 		for schedule in asset.get("schedules"):
 			if getdate(schedule.schedule_date) < getdate(filters.from_date):
-				depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
+				if not asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date):
+					depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
 			elif getdate(schedule.schedule_date) <= getdate(filters.to_date):
 				depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
 				
 				if asset.disposal_date and getdate(schedule.schedule_date) > getdate(asset.disposal_date):
-					depr.depreciation_eliminated += flt(schedule.depreciation_amount)
+					depr.depreciation_eliminated_during_the_period += flt(schedule.depreciation_amount)
 		
 	return asset_depreciations
 	
@@ -158,7 +159,7 @@
 		},
 		{
 			"label": _("Depreciation Eliminated due to disposal of assets"),
-			"fieldname": "depreciation_eliminated",
+			"fieldname": "depreciation_eliminated_during_the_period",
 			"fieldtype": "Currency",
 			"width": 300
 		},