Merge pull request #6994 from nabinhait/manual_depreciation
Manual Depreciation Schedule for Asset
This commit is contained in:
commit
c16b373969
@ -28,6 +28,7 @@ frappe.ui.form.on('Asset', {
|
|||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
frappe.ui.form.trigger("Asset", "is_existing_asset");
|
frappe.ui.form.trigger("Asset", "is_existing_asset");
|
||||||
frm.toggle_display("next_depreciation_date", frm.doc.docstatus < 1);
|
frm.toggle_display("next_depreciation_date", frm.doc.docstatus < 1);
|
||||||
|
frm.events.make_schedules_editable(frm);
|
||||||
|
|
||||||
if (frm.doc.docstatus==1) {
|
if (frm.doc.docstatus==1) {
|
||||||
if (frm.doc.status=='Submitted' && !frm.doc.is_existing_asset && !frm.doc.purchase_invoice) {
|
if (frm.doc.status=='Submitted' && !frm.doc.is_existing_asset && !frm.doc.purchase_invoice) {
|
||||||
@ -141,6 +142,22 @@ frappe.ui.form.on('Asset', {
|
|||||||
frm.toggle_enable("supplier", frm.doc.is_existing_asset);
|
frm.toggle_enable("supplier", frm.doc.is_existing_asset);
|
||||||
frm.toggle_reqd("next_depreciation_date", !frm.doc.is_existing_asset);
|
frm.toggle_reqd("next_depreciation_date", !frm.doc.is_existing_asset);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
opening_accumulated_depreciation: function(frm) {
|
||||||
|
erpnext.asset.set_accululated_depreciation(frm);
|
||||||
|
},
|
||||||
|
|
||||||
|
depreciation_method: function(frm) {
|
||||||
|
frm.events.make_schedules_editable(frm);
|
||||||
|
},
|
||||||
|
|
||||||
|
make_schedules_editable: function(frm) {
|
||||||
|
var is_editable = frm.doc.depreciation_method==="Manual" ? true : false;
|
||||||
|
frm.toggle_enable("schedules", is_editable);
|
||||||
|
frm.fields_dict["schedules"].grid.toggle_enable("schedule_date", is_editable);
|
||||||
|
frm.fields_dict["schedules"].grid.toggle_enable("depreciation_amount", is_editable);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on('Depreciation Schedule', {
|
frappe.ui.form.on('Depreciation Schedule', {
|
||||||
@ -159,9 +176,25 @@ frappe.ui.form.on('Depreciation Schedule', {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
depreciation_amount: function(frm, cdt, cdn) {
|
||||||
|
erpnext.asset.set_accululated_depreciation(frm);
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
erpnext.asset.set_accululated_depreciation = function(frm) {
|
||||||
|
if(frm.doc.depreciation_method != "Manual") return;
|
||||||
|
|
||||||
|
accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation);
|
||||||
|
$.each(frm.doc.schedules || [], function(i, row) {
|
||||||
|
accumulated_depreciation += flt(row.depreciation_amount);
|
||||||
|
frappe.model.set_value(row.doctype, row.name,
|
||||||
|
"accumulated_depreciation_amount", accumulated_depreciation);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
erpnext.asset.make_purchase_invoice = function(frm) {
|
erpnext.asset.make_purchase_invoice = function(frm) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
args: {
|
args: {
|
||||||
|
@ -516,7 +516,7 @@
|
|||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "value_after_depreciation",
|
"fieldname": "value_after_depreciation",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 1,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
@ -580,7 +580,7 @@
|
|||||||
"label": "Depreciation Method",
|
"label": "Depreciation Method",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "\nStraight Line\nDouble Declining Balance",
|
"options": "\nStraight Line\nDouble Declining Balance\nManual",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@ -750,7 +750,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@ -797,7 +797,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-11-03 14:58:53.710357",
|
"modified": "2016-11-18 15:59:19.774500",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Asset",
|
"name": "Asset",
|
||||||
|
@ -18,6 +18,7 @@ class Asset(Document):
|
|||||||
self.set_missing_values()
|
self.set_missing_values()
|
||||||
self.validate_asset_values()
|
self.validate_asset_values()
|
||||||
self.make_depreciation_schedule()
|
self.make_depreciation_schedule()
|
||||||
|
self.set_accumulated_depreciation()
|
||||||
self.validate_expected_value_after_useful_life()
|
self.validate_expected_value_after_useful_life()
|
||||||
# Validate depreciation related accounts
|
# Validate depreciation related accounts
|
||||||
get_depreciation_accounts(self)
|
get_depreciation_accounts(self)
|
||||||
@ -48,7 +49,7 @@ class Asset(Document):
|
|||||||
for field, value in item_details.items():
|
for field, value in item_details.items():
|
||||||
if not self.get(field):
|
if not self.get(field):
|
||||||
self.set(field, value)
|
self.set(field, value)
|
||||||
|
|
||||||
self.value_after_depreciation = (flt(self.gross_purchase_amount) -
|
self.value_after_depreciation = (flt(self.gross_purchase_amount) -
|
||||||
flt(self.opening_accumulated_depreciation))
|
flt(self.opening_accumulated_depreciation))
|
||||||
|
|
||||||
@ -87,9 +88,10 @@ class Asset(Document):
|
|||||||
frappe.throw(_("Please set Next Depreciation Date"))
|
frappe.throw(_("Please set Next Depreciation Date"))
|
||||||
|
|
||||||
def make_depreciation_schedule(self):
|
def make_depreciation_schedule(self):
|
||||||
self.schedules = []
|
if self.depreciation_method != 'Manual':
|
||||||
|
self.schedules = []
|
||||||
|
|
||||||
if not self.get("schedules") and self.next_depreciation_date:
|
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)
|
value_after_depreciation = flt(self.value_after_depreciation)
|
||||||
|
|
||||||
number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \
|
number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \
|
||||||
@ -100,18 +102,21 @@ class Asset(Document):
|
|||||||
n * cint(self.frequency_of_depreciation))
|
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)
|
value_after_depreciation -= flt(depreciation_amount)
|
||||||
|
|
||||||
self.append("schedules", {
|
self.append("schedules", {
|
||||||
"schedule_date": schedule_date,
|
"schedule_date": schedule_date,
|
||||||
"depreciation_amount": depreciation_amount,
|
"depreciation_amount": depreciation_amount
|
||||||
"accumulated_depreciation_amount": accumulated_depreciation
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def set_accumulated_depreciation(self):
|
||||||
|
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
|
||||||
|
for d in self.get("schedules"):
|
||||||
|
accumulated_depreciation += flt(d.depreciation_amount)
|
||||||
|
d.accumulated_depreciation_amount = accumulated_depreciation
|
||||||
|
|
||||||
def get_depreciation_amount(self, depreciable_value):
|
def get_depreciation_amount(self, depreciable_value):
|
||||||
if self.depreciation_method == "Straight Line":
|
if self.depreciation_method in ("Straight Line", "Manual"):
|
||||||
depreciation_amount = (flt(self.value_after_depreciation) -
|
depreciation_amount = (flt(self.value_after_depreciation) -
|
||||||
flt(self.expected_value_after_useful_life)) / (cint(self.total_number_of_depreciations) -
|
flt(self.expected_value_after_useful_life)) / (cint(self.total_number_of_depreciations) -
|
||||||
cint(self.number_of_depreciations_booked))
|
cint(self.number_of_depreciations_booked))
|
||||||
@ -126,16 +131,15 @@ class Asset(Document):
|
|||||||
return depreciation_amount
|
return depreciation_amount
|
||||||
|
|
||||||
def validate_expected_value_after_useful_life(self):
|
def validate_expected_value_after_useful_life(self):
|
||||||
if self.depreciation_method == "Double Declining Balance":
|
accumulated_depreciation_after_full_schedule = \
|
||||||
accumulated_depreciation_after_full_schedule = \
|
max([d.accumulated_depreciation_amount for d in self.get("schedules")])
|
||||||
max([d.accumulated_depreciation_amount for d in self.get("schedules")])
|
|
||||||
|
asset_value_after_full_schedule = (flt(self.gross_purchase_amount) -
|
||||||
asset_value_after_full_schedule = (flt(self.gross_purchase_amount) -
|
flt(accumulated_depreciation_after_full_schedule))
|
||||||
flt(accumulated_depreciation_after_full_schedule))
|
|
||||||
|
if self.expected_value_after_useful_life < asset_value_after_full_schedule:
|
||||||
if self.expected_value_after_useful_life < asset_value_after_full_schedule:
|
frappe.throw(_("Expected value after useful life must be greater than or equal to {0}")
|
||||||
frappe.throw(_("Expected value after useful life must be greater than or equal to {0}")
|
.format(asset_value_after_full_schedule))
|
||||||
.format(asset_value_after_full_schedule))
|
|
||||||
|
|
||||||
def validate_cancellation(self):
|
def validate_cancellation(self):
|
||||||
if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):
|
if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):
|
||||||
|
@ -119,6 +119,30 @@ class TestAsset(unittest.TestCase):
|
|||||||
for d in asset.get("schedules")]
|
for d in asset.get("schedules")]
|
||||||
|
|
||||||
self.assertEqual(schedules, expected_schedules)
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|
||||||
|
def test_schedule_for_manual_method(self):
|
||||||
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
|
asset.depreciation_method = "Manual"
|
||||||
|
asset.schedules = []
|
||||||
|
for schedule_date, amount in [["2020-12-31", 40000], ["2021-06-30", 30000], ["2021-10-31", 20000]]:
|
||||||
|
asset.append("schedules", {
|
||||||
|
"schedule_date": schedule_date,
|
||||||
|
"depreciation_amount": amount
|
||||||
|
})
|
||||||
|
asset.save()
|
||||||
|
|
||||||
|
self.assertEqual(asset.status, "Draft")
|
||||||
|
|
||||||
|
expected_schedules = [
|
||||||
|
["2020-12-31", 40000, 40000],
|
||||||
|
["2021-06-30", 30000, 70000],
|
||||||
|
["2021-10-31", 20000, 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):
|
def test_depreciation(self):
|
||||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
|
@ -10,11 +10,13 @@
|
|||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "schedule_date",
|
"fieldname": "schedule_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -29,7 +31,8 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -40,6 +43,7 @@
|
|||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "depreciation_amount",
|
"fieldname": "depreciation_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -55,7 +59,8 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -66,6 +71,7 @@
|
|||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "column_break_3",
|
"fieldname": "column_break_3",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -80,6 +86,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -90,6 +97,7 @@
|
|||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "accumulated_depreciation_amount",
|
"fieldname": "accumulated_depreciation_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -106,8 +114,9 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
@ -116,6 +125,8 @@
|
|||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "eval:doc.docstatus==1",
|
||||||
"fieldname": "journal_entry",
|
"fieldname": "journal_entry",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -132,6 +143,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -142,7 +154,8 @@
|
|||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"depends_on": "eval:(!doc.journal_entry && doc.schedule_date <= get_today())",
|
"columns": 0,
|
||||||
|
"depends_on": "eval:(doc.docstatus==1 && !doc.journal_entry && doc.schedule_date <= get_today())",
|
||||||
"fieldname": "make_depreciation_entry",
|
"fieldname": "make_depreciation_entry",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -158,6 +171,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
@ -175,7 +189,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-07-11 03:27:59.603924",
|
"modified": "2016-11-18 16:42:19.543657",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Depreciation Schedule",
|
"name": "Depreciation Schedule",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user