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
},