Prorated Asset Depreciation
This commit is contained in:
parent
620e0981cb
commit
34e335ba34
@ -185,20 +185,26 @@ frappe.ui.form.on('Asset', {
|
|||||||
|
|
||||||
create_asset_maintenance: function(frm) {
|
create_asset_maintenance: function(frm) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
args: {
|
method: "GET",
|
||||||
"asset": frm.doc.name,
|
|
||||||
"item_code": frm.doc.item_code,
|
|
||||||
"item_name": frm.doc.item_name,
|
|
||||||
"asset_category": frm.doc.asset_category,
|
|
||||||
"company": frm.doc.company
|
|
||||||
},
|
|
||||||
method: "erpnext.assets.doctype.asset.asset.create_asset_maintenance",
|
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
var doclist = frappe.model.sync(r.message);
|
var doclist = frappe.model.sync(r.message);
|
||||||
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
|
||||||
|
calculate_depreciation: function(frm) {
|
||||||
|
frappe.db.get_value("Asset Settings", {'name':"Asset Settings"}, 'schedule_based_on_fiscal_year', (data) => {
|
||||||
|
if (data.schedule_based_on_fiscal_year == 1) {
|
||||||
|
frm.set_df_property("depreciation_method", "options", "\nStraight Line\nManual")
|
||||||
|
frm.toggle_reqd("available_for_use_date", true);
|
||||||
|
frm.toggle_display("frequency_of_depreciation", false);
|
||||||
|
frappe.db.get_value("Fiscal Year", {'name': frappe.sys_defaults.fiscal_year}, "year_end_date", (data) => {
|
||||||
|
frm.set_value("next_depreciation_date", data.year_end_date);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on('Depreciation Schedule', {
|
frappe.ui.form.on('Depreciation Schedule', {
|
||||||
@ -316,4 +322,4 @@ erpnext.asset.transfer_asset = function(frm) {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
dialog.show();
|
dialog.show();
|
||||||
};
|
};
|
||||||
|
@ -507,6 +507,36 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "available_for_use_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": "Available-for-use 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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -1221,7 +1251,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-12-19 12:58:44.137460",
|
"modified": "2018-01-05 09:53:05.945328",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset",
|
"name": "Asset",
|
||||||
@ -1277,4 +1307,4 @@
|
|||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 0,
|
"track_changes": 0,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt, add_months, cint, nowdate, getdate, today
|
from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff, nowdate
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import get_fixed_asset_account
|
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import get_fixed_asset_account
|
||||||
from erpnext.assets.doctype.asset.depreciation \
|
from erpnext.assets.doctype.asset.depreciation \
|
||||||
@ -87,11 +87,15 @@ class Asset(Document):
|
|||||||
if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(self.purchase_date):
|
if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(self.purchase_date):
|
||||||
frappe.throw(_("Next Depreciation Date cannot be before Purchase Date"))
|
frappe.throw(_("Next Depreciation Date cannot be before Purchase Date"))
|
||||||
|
|
||||||
|
if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(self.available_for_use_date):
|
||||||
|
frappe.throw(_("Next Depreciation Date cannot be before Available-for-use Date"))
|
||||||
|
|
||||||
if (flt(self.value_after_depreciation) > flt(self.expected_value_after_useful_life)
|
if (flt(self.value_after_depreciation) > flt(self.expected_value_after_useful_life)
|
||||||
and not self.next_depreciation_date and self.calculate_depreciation):
|
and not self.next_depreciation_date and self.calculate_depreciation):
|
||||||
frappe.throw(_("Please set Next Depreciation Date"))
|
frappe.throw(_("Please set Next Depreciation Date"))
|
||||||
|
|
||||||
def make_depreciation_schedule(self):
|
def make_depreciation_schedule(self):
|
||||||
|
|
||||||
if self.depreciation_method != 'Manual':
|
if self.depreciation_method != 'Manual':
|
||||||
self.schedules = []
|
self.schedules = []
|
||||||
|
|
||||||
@ -101,17 +105,42 @@ class Asset(Document):
|
|||||||
number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \
|
number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \
|
||||||
cint(self.number_of_depreciations_booked)
|
cint(self.number_of_depreciations_booked)
|
||||||
if number_of_pending_depreciations:
|
if number_of_pending_depreciations:
|
||||||
for n in xrange(number_of_pending_depreciations):
|
if (cint(frappe.db.get_value("Asset Settings", None, "schedule_based_on_fiscal_year")) == 1) and getdate(self.next_depreciation_date) < getdate(add_months(self.available_for_use_date, number_of_pending_depreciations * 12)):
|
||||||
schedule_date = add_months(self.next_depreciation_date,
|
number_of_pending_depreciations += 1
|
||||||
n * cint(self.frequency_of_depreciation))
|
|
||||||
|
|
||||||
depreciation_amount = self.get_depreciation_amount(value_after_depreciation)
|
for n in xrange(number_of_pending_depreciations):
|
||||||
value_after_depreciation -= flt(depreciation_amount)
|
if n == xrange(number_of_pending_depreciations)[-1]:
|
||||||
|
schedule_date = add_months(self.available_for_use_date, n * 12)
|
||||||
|
previous_scheduled_date = add_months(self.next_depreciation_date, (n-1) * 12)
|
||||||
|
depreciation_amount = self.get_depreciation_amount_prorata_temporis(value_after_depreciation, previous_scheduled_date, schedule_date)
|
||||||
|
|
||||||
self.append("schedules", {
|
elif n == xrange(number_of_pending_depreciations)[0]:
|
||||||
"schedule_date": schedule_date,
|
schedule_date = self.next_depreciation_date
|
||||||
"depreciation_amount": depreciation_amount
|
depreciation_amount = self.get_depreciation_amount_prorata_temporis(value_after_depreciation, self.available_for_use_date, schedule_date)
|
||||||
})
|
|
||||||
|
else:
|
||||||
|
schedule_date = add_months(self.next_depreciation_date, n * 12)
|
||||||
|
depreciation_amount = self.get_depreciation_amount_prorata_temporis(value_after_depreciation)
|
||||||
|
|
||||||
|
if value_after_depreciation != 0:
|
||||||
|
value_after_depreciation -= flt(depreciation_amount)
|
||||||
|
|
||||||
|
self.append("schedules", {
|
||||||
|
"schedule_date": schedule_date,
|
||||||
|
"depreciation_amount": depreciation_amount
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
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)
|
||||||
|
value_after_depreciation -= flt(depreciation_amount)
|
||||||
|
|
||||||
|
self.append("schedules", {
|
||||||
|
"schedule_date": schedule_date,
|
||||||
|
"depreciation_amount": depreciation_amount
|
||||||
|
})
|
||||||
|
|
||||||
def set_accumulated_depreciation(self):
|
def set_accumulated_depreciation(self):
|
||||||
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
|
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
|
||||||
@ -143,6 +172,21 @@ class Asset(Document):
|
|||||||
|
|
||||||
return depreciation_amount
|
return depreciation_amount
|
||||||
|
|
||||||
|
def get_depreciation_amount_prorata_temporis(self, depreciable_value, start_date=None, end_date=None):
|
||||||
|
if start_date and end_date:
|
||||||
|
prorata_temporis = min(abs(flt(date_diff(str(end_date), str(start_date)))) / flt(frappe.db.get_value("Asset Settings", None, "number_of_days_in_fiscal_year")), 1)
|
||||||
|
else:
|
||||||
|
prorata_temporis = 1
|
||||||
|
|
||||||
|
if self.depreciation_method in ("Straight Line", "Manual"):
|
||||||
|
depreciation_amount = (flt(self.value_after_depreciation) -
|
||||||
|
flt(self.expected_value_after_useful_life)) / (cint(self.total_number_of_depreciations) -
|
||||||
|
cint(self.number_of_depreciations_booked)) * prorata_temporis
|
||||||
|
|
||||||
|
return depreciation_amount
|
||||||
|
else:
|
||||||
|
self.get_depreciation_amount(depreciable_value)
|
||||||
|
|
||||||
def validate_expected_value_after_useful_life(self):
|
def validate_expected_value_after_useful_life(self):
|
||||||
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")])
|
||||||
@ -174,7 +218,7 @@ class Asset(Document):
|
|||||||
def set_status(self, status=None):
|
def set_status(self, status=None):
|
||||||
'''Get and update status'''
|
'''Get and update status'''
|
||||||
if not status:
|
if not status:
|
||||||
status = self.get_status()
|
status = self.get_status()
|
||||||
self.db_set("status", status)
|
self.db_set("status", status)
|
||||||
|
|
||||||
def get_status(self):
|
def get_status(self):
|
||||||
|
@ -12,24 +12,25 @@ from erpnext.assets.doctype.asset.asset import make_sales_invoice, make_purchase
|
|||||||
class TestAsset(unittest.TestCase):
|
class TestAsset(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
set_depreciation_settings_in_company()
|
set_depreciation_settings_in_company()
|
||||||
|
remove_prorated_depreciation_schedule()
|
||||||
create_asset()
|
create_asset()
|
||||||
frappe.db.sql("delete from `tabTax Rule`")
|
frappe.db.sql("delete from `tabTax Rule`")
|
||||||
|
|
||||||
def test_purchase_asset(self):
|
def test_purchase_asset(self):
|
||||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
asset.submit()
|
asset.submit()
|
||||||
|
|
||||||
pi = make_purchase_invoice(asset.name, asset.item_code, asset.gross_purchase_amount,
|
pi = make_purchase_invoice(asset.name, asset.item_code, asset.gross_purchase_amount,
|
||||||
asset.company, asset.purchase_date)
|
asset.company, asset.purchase_date)
|
||||||
pi.supplier = "_Test Supplier"
|
pi.supplier = "_Test Supplier"
|
||||||
pi.insert()
|
pi.insert()
|
||||||
pi.submit()
|
pi.submit()
|
||||||
|
|
||||||
asset.load_from_db()
|
asset.load_from_db()
|
||||||
self.assertEqual(asset.supplier, "_Test Supplier")
|
self.assertEqual(asset.supplier, "_Test Supplier")
|
||||||
self.assertEqual(asset.purchase_date, getdate("2015-01-01"))
|
self.assertEqual(asset.purchase_date, getdate("2015-01-01"))
|
||||||
self.assertEqual(asset.purchase_invoice, pi.name)
|
self.assertEqual(asset.purchase_invoice, pi.name)
|
||||||
|
|
||||||
expected_gle = (
|
expected_gle = (
|
||||||
("_Test Fixed Asset - _TC", 100000.0, 0.0),
|
("_Test Fixed Asset - _TC", 100000.0, 0.0),
|
||||||
("Creditors - _TC", 0.0, 100000.0)
|
("Creditors - _TC", 0.0, 100000.0)
|
||||||
@ -46,10 +47,10 @@ class TestAsset(unittest.TestCase):
|
|||||||
asset.load_from_db()
|
asset.load_from_db()
|
||||||
self.assertEqual(asset.supplier, None)
|
self.assertEqual(asset.supplier, None)
|
||||||
self.assertEqual(asset.purchase_invoice, None)
|
self.assertEqual(asset.purchase_invoice, None)
|
||||||
|
|
||||||
self.assertFalse(frappe.db.get_value("GL Entry",
|
self.assertFalse(frappe.db.get_value("GL Entry",
|
||||||
{"voucher_type": "Purchase Invoice", "voucher_no": pi.name}))
|
{"voucher_type": "Purchase Invoice", "voucher_no": pi.name}))
|
||||||
|
|
||||||
|
|
||||||
def test_schedule_for_straight_line_method(self):
|
def test_schedule_for_straight_line_method(self):
|
||||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
@ -66,14 +67,14 @@ 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_straight_line_method_for_existing_asset(self):
|
def test_schedule_for_straight_line_method_for_existing_asset(self):
|
||||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
asset.is_existing_asset = 1
|
asset.is_existing_asset = 1
|
||||||
asset.number_of_depreciations_booked = 1
|
asset.number_of_depreciations_booked = 1
|
||||||
asset.opening_accumulated_depreciation = 40000
|
asset.opening_accumulated_depreciation = 40000
|
||||||
asset.save()
|
asset.save()
|
||||||
|
|
||||||
self.assertEqual(asset.status, "Draft")
|
self.assertEqual(asset.status, "Draft")
|
||||||
|
|
||||||
expected_schedules = [
|
expected_schedules = [
|
||||||
@ -102,7 +103,7 @@ 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_double_declining_method_for_existing_asset(self):
|
def test_schedule_for_double_declining_method_for_existing_asset(self):
|
||||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
asset.depreciation_method = "Double Declining Balance"
|
asset.depreciation_method = "Double Declining Balance"
|
||||||
@ -120,7 +121,7 @@ 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):
|
def test_schedule_for_manual_method(self):
|
||||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
asset.depreciation_method = "Manual"
|
asset.depreciation_method = "Manual"
|
||||||
@ -145,6 +146,29 @@ class TestAsset(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(schedules, expected_schedules)
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|
||||||
|
def test_schedule_for_prorated_straight_line_method(self):
|
||||||
|
set_prorated_depreciation_schedule()
|
||||||
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
|
asset.is_existing_asset = 0
|
||||||
|
asset.available_for_use_date = "2020-01-30"
|
||||||
|
asset.next_depreciation_date = "2020-12-31"
|
||||||
|
asset.depreciation_method = "Straight Line"
|
||||||
|
asset.save()
|
||||||
|
|
||||||
|
expected_schedules = [
|
||||||
|
["2020-12-31", 28000, 28000],
|
||||||
|
["2021-12-31", 30000, 58000],
|
||||||
|
["2022-12-31", 30000, 88000],
|
||||||
|
["2023-01-30", 2000, 90000]
|
||||||
|
]
|
||||||
|
|
||||||
|
schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
|
||||||
|
for d in asset.get("schedules")]
|
||||||
|
|
||||||
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|
||||||
|
remove_prorated_depreciation_schedule()
|
||||||
|
|
||||||
def test_depreciation(self):
|
def test_depreciation(self):
|
||||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
asset.submit()
|
asset.submit()
|
||||||
@ -172,23 +196,23 @@ class TestAsset(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(gle, expected_gle)
|
self.assertEqual(gle, expected_gle)
|
||||||
self.assertEqual(asset.get("value_after_depreciation"), 70000)
|
self.assertEqual(asset.get("value_after_depreciation"), 70000)
|
||||||
|
|
||||||
def test_depreciation_entry_cancellation(self):
|
def test_depreciation_entry_cancellation(self):
|
||||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
asset.submit()
|
asset.submit()
|
||||||
post_depreciation_entries(date="2021-01-01")
|
post_depreciation_entries(date="2021-01-01")
|
||||||
|
|
||||||
asset.load_from_db()
|
asset.load_from_db()
|
||||||
|
|
||||||
# cancel depreciation entry
|
# cancel depreciation entry
|
||||||
depr_entry = asset.get("schedules")[0].journal_entry
|
depr_entry = asset.get("schedules")[0].journal_entry
|
||||||
self.assertTrue(depr_entry)
|
self.assertTrue(depr_entry)
|
||||||
frappe.get_doc("Journal Entry", depr_entry).cancel()
|
frappe.get_doc("Journal Entry", depr_entry).cancel()
|
||||||
|
|
||||||
asset.load_from_db()
|
asset.load_from_db()
|
||||||
depr_entry = asset.get("schedules")[0].journal_entry
|
depr_entry = asset.get("schedules")[0].journal_entry
|
||||||
self.assertFalse(depr_entry)
|
self.assertFalse(depr_entry)
|
||||||
|
|
||||||
|
|
||||||
def test_scrap_asset(self):
|
def test_scrap_asset(self):
|
||||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||||
@ -284,7 +308,7 @@ def create_asset():
|
|||||||
|
|
||||||
if not frappe.db.exists("Item", "Macbook Pro"):
|
if not frappe.db.exists("Item", "Macbook Pro"):
|
||||||
create_fixed_asset_item()
|
create_fixed_asset_item()
|
||||||
|
|
||||||
asset = frappe.get_doc({
|
asset = frappe.get_doc({
|
||||||
"doctype": "Asset",
|
"doctype": "Asset",
|
||||||
"asset_name": "Macbook Pro 1",
|
"asset_name": "Macbook Pro 1",
|
||||||
@ -342,6 +366,21 @@ def set_depreciation_settings_in_company():
|
|||||||
company.disposal_account = "_Test Gain/Loss on Asset Disposal - _TC"
|
company.disposal_account = "_Test Gain/Loss on Asset Disposal - _TC"
|
||||||
company.depreciation_cost_center = "_Test Cost Center - _TC"
|
company.depreciation_cost_center = "_Test Cost Center - _TC"
|
||||||
company.save()
|
company.save()
|
||||||
|
|
||||||
# Enable booking asset depreciation entry automatically
|
# Enable booking asset depreciation entry automatically
|
||||||
frappe.db.set_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically", 1)
|
frappe.db.set_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically", 1)
|
||||||
|
|
||||||
|
def remove_prorated_depreciation_schedule():
|
||||||
|
asset_settings = frappe.get_doc("Asset Settings", "Asset Settings")
|
||||||
|
asset_settings.schedule_based_on_fiscal_year = 0
|
||||||
|
asset_settings.save()
|
||||||
|
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
def set_prorated_depreciation_schedule():
|
||||||
|
asset_settings = frappe.get_doc("Asset Settings", "Asset Settings")
|
||||||
|
asset_settings.schedule_based_on_fiscal_year = 1
|
||||||
|
asset_settings.number_of_days_in_fiscal_year = 360
|
||||||
|
asset_settings.save()
|
||||||
|
|
||||||
|
frappe.db.commit()
|
||||||
|
@ -12,4 +12,4 @@ class AssetCategory(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
for field in ("total_number_of_depreciations", "frequency_of_depreciation"):
|
for field in ("total_number_of_depreciations", "frequency_of_depreciation"):
|
||||||
if cint(self.get(field))<1:
|
if cint(self.get(field))<1:
|
||||||
frappe.throw(_("{0} must be greater than 0").format(self.meta.get_label(field)), frappe.MandatoryError)
|
frappe.throw(_("{0} must be greater than 0").format(self.meta.get_label(field)), frappe.MandatoryError)
|
||||||
|
0
erpnext/assets/doctype/asset_settings/__init__.py
Normal file
0
erpnext/assets/doctype/asset_settings/__init__.py
Normal file
8
erpnext/assets/doctype/asset_settings/asset_settings.js
Normal file
8
erpnext/assets/doctype/asset_settings/asset_settings.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Asset Settings', {
|
||||||
|
refresh: function(frm) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
175
erpnext/assets/doctype/asset_settings/asset_settings.json
Normal file
175
erpnext/assets/doctype/asset_settings/asset_settings.json
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-01-03 10:30:32.983381",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "depreciation_options",
|
||||||
|
"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": "Depreciation Options",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "schedule_based_on_fiscal_year",
|
||||||
|
"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": "Calculate Prorated Depreciation Schedule Based on Fiscal Year",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "360",
|
||||||
|
"depends_on": "eval:doc.schedule_based_on_fiscal_year",
|
||||||
|
"description": "This value is used for pro-rata temporis calculation",
|
||||||
|
"fieldname": "number_of_days_in_fiscal_year",
|
||||||
|
"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": "Number of Days in Fiscal Year",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 1,
|
||||||
|
"istable": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2018-01-05 10:10:39.803255",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Assets",
|
||||||
|
"name": "Asset Settings",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"apply_user_permissions": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 0,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 0,
|
||||||
|
"role": "System Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"apply_user_permissions": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 0,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 0,
|
||||||
|
"role": "Accounts Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1,
|
||||||
|
"track_seen": 0
|
||||||
|
}
|
10
erpnext/assets/doctype/asset_settings/asset_settings.py
Normal file
10
erpnext/assets/doctype/asset_settings/asset_settings.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, 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 AssetSettings(Document):
|
||||||
|
pass
|
23
erpnext/assets/doctype/asset_settings/test_asset_settings.js
Normal file
23
erpnext/assets/doctype/asset_settings/test_asset_settings.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// rename this file from _test_[name] to test_[name] to activate
|
||||||
|
// and remove above this line
|
||||||
|
|
||||||
|
QUnit.test("test: Asset Settings", function (assert) {
|
||||||
|
let done = assert.async();
|
||||||
|
|
||||||
|
// number of asserts
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
frappe.run_serially([
|
||||||
|
// insert a new Asset Settings
|
||||||
|
() => frappe.tests.make('Asset Settings', [
|
||||||
|
// values to be set
|
||||||
|
{key: 'value'}
|
||||||
|
]),
|
||||||
|
() => {
|
||||||
|
assert.equal(cur_frm.doc.key, 'value');
|
||||||
|
},
|
||||||
|
() => done()
|
||||||
|
]);
|
||||||
|
|
||||||
|
});
|
10
erpnext/assets/doctype/asset_settings/test_asset_settings.py
Normal file
10
erpnext/assets/doctype/asset_settings/test_asset_settings.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestAssetSettings(unittest.TestCase):
|
||||||
|
pass
|
@ -13,6 +13,10 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Asset Category",
|
"name": "Asset Category",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Asset Settings",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -74,4 +78,4 @@ def get_data():
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
BIN
erpnext/docs/assets/img/asset/asset_prorated_depreciation.png
Normal file
BIN
erpnext/docs/assets/img/asset/asset_prorated_depreciation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
@ -50,6 +50,13 @@ On the scheduled date, system creates depreciation entry by creating a Journal E
|
|||||||
|
|
||||||
In the depreciation entry, the "Accumulated Depreciation Account" is credited and "Depreciation Expense Account" is debited. The related accounts can be set in the Asset Category or Company.
|
In the depreciation entry, the "Accumulated Depreciation Account" is credited and "Depreciation Expense Account" is debited. The related accounts can be set in the Asset Category or Company.
|
||||||
|
|
||||||
|
If you are required to calculate the depreciation based on your Fiscal Year and prorated by the number of days left, select the corresponding option in "Account Settings".
|
||||||
|
|
||||||
|
The system will automatically set the fiscal year end date as the next depreciation date and calculate the depreciation amount prorata temporis based on the Available-for-use Date (IFRS16)
|
||||||
|
|
||||||
|
<img class="screenshot" alt="Asset" src="/docs/assets/img/asset/asset-prorated-depreciation.png">
|
||||||
|
|
||||||
|
|
||||||
For better visibility, net value of the asset on different depreciation dates are shown in a line graph.
|
For better visibility, net value of the asset on different depreciation dates are shown in a line graph.
|
||||||
|
|
||||||
<img class="screenshot" alt="Asset" src="/docs/assets/img/asset/asset-graph.png">
|
<img class="screenshot" alt="Asset" src="/docs/assets/img/asset/asset-graph.png">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user