Reschedule for future depreciations and booked difference amount in accumulated depreciation account

This commit is contained in:
Rohit Waghchaure 2018-05-12 12:06:00 +05:30
parent aa7b434270
commit 16bc853f6a
10 changed files with 247 additions and 73 deletions

View File

@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe, erpnext, json
from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, nowdate
from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, nowdate, cint
from frappe import msgprint, _, scrub
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.accounts.utils import get_balance_on, get_account_currency
@ -92,6 +92,7 @@ class JournalEntry(AccountsController):
self.unlink_advance_entry_reference()
self.unlink_asset_reference()
self.unlink_inter_company_jv()
self.unlink_asset_adjustment_entry()
def unlink_advance_entry_reference(self):
for d in self.get("accounts"):
@ -109,9 +110,12 @@ class JournalEntry(AccountsController):
for s in asset.get("schedules"):
if s.journal_entry == self.name:
s.db_set("journal_entry", None)
asset.value_after_depreciation += s.depreciation_amount
asset.db_set("value_after_depreciation", asset.value_after_depreciation)
idx = cint(s.finance_book_id) or 1
finance_books = asset.get('finance_books')[idx - 1]
finance_books.value_after_depreciation += s.depreciation_amount
finance_books.db_update()
asset.set_status()
def unlink_inter_company_jv(self):
@ -121,6 +125,10 @@ class JournalEntry(AccountsController):
frappe.db.set_value("Journal Entry", self.name,\
"inter_company_journal_entry_reference", "")
def unlink_asset_adjustment_entry(self):
frappe.db.sql(""" update `tabAsset Adjustment`
set journal_entry = null where journal_entry = %s""", self.name)
def validate_party(self):
for d in self.get("accounts"):
account_type = frappe.db.get_value("Account", d.account, "account_type")

View File

@ -80,6 +80,12 @@ frappe.ui.form.on('Asset', {
frm.trigger("create_asset_maintenance");
}, __("Make"));
}
if (frm.doc.status != 'Fully Depreciated') {
frm.add_custom_button(__("Asset Adjustment"), function() {
frm.trigger("create_asset_maintenance");
}, __("Make"));
}
frm.page.set_inner_btn_group_as_primary(__("Make"));
frm.trigger("setup_chart");
}

View File

@ -1600,6 +1600,36 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "purchase_receipt_amount",
"fieldtype": "Currency",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Purchase Receipt Amount",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"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,
@ -1673,7 +1703,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-05-11 01:48:18.711485",
"modified": "2018-05-11 10:41:45.972686",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",

View File

@ -63,9 +63,6 @@ class Asset(AccountsController):
if not self.calculate_depreciation:
return
self.value_after_depreciation = (flt(self.gross_purchase_amount) -
flt(self.opening_accumulated_depreciation))
if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(nowdate()):
frappe.throw(_("Available-for-use Date is entered as past date"))
@ -79,7 +76,9 @@ class Asset(AccountsController):
for d in self.get('finance_books'):
self.validate_asset_finance_books(d)
value_after_depreciation = flt(self.value_after_depreciation)
value_after_depreciation = (flt(self.gross_purchase_amount) -
flt(self.opening_accumulated_depreciation))
d.value_after_depreciation = value_after_depreciation
no_of_depreciations = cint(d.total_number_of_depreciations - 1) - cint(self.number_of_depreciations_booked)
@ -139,7 +138,8 @@ class Asset(AccountsController):
depreciation_amount = days * rate_per_day
from_date = schedule_date
else:
depreciation_amount = self.get_depreciation_amount(value_after_depreciation,d)
depreciation_amount = self.get_depreciation_amount(value_after_depreciation,
d.total_number_of_depreciations, d)
if depreciation_amount:
value_after_depreciation -= flt(depreciation_amount)
@ -187,21 +187,24 @@ class Asset(AccountsController):
frappe.throw(_("Depreciation Row {0}: Next Depreciation Date cannot be before Available-for-use Date")
.format(row.idx))
def set_accumulated_depreciation(self):
value_after_depreciation = flt(self.value_after_depreciation)
def set_accumulated_depreciation(self, ignore_booked_entry = False):
straight_line_idx = [d.idx for d in self.get("schedules") if d.depreciation_method == 'Straight Line']
finance_books = []
for i, d in enumerate(self.get("schedules")):
if ignore_booked_entry and d.journal_entry:
continue
if d.finance_book_id not in finance_books:
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
value_after_depreciation = flt(self.get_value_after_depreciation(d.finance_book_id))
finance_books.append(d.finance_book_id)
depreciation_amount = flt(d.depreciation_amount, d.precision("depreciation_amount"))
value_after_depreciation -= flt(depreciation_amount)
if straight_line_idx and i == max(straight_line_idx) - 1:
book = self.get('finance_books')[d.finance_book_id - 1]
book = self.get('finance_books')[cint(d.finance_book_id) - 1]
depreciation_amount += flt(value_after_depreciation -
flt(book.expected_value_after_useful_life), d.precision("depreciation_amount"))
@ -210,10 +213,13 @@ class Asset(AccountsController):
d.accumulated_depreciation_amount = flt(accumulated_depreciation,
d.precision("accumulated_depreciation_amount"))
def get_depreciation_amount(self, depreciable_value, row):
def get_value_after_depreciation(self, idx):
return flt(self.get('finance_books')[cint(idx)-1].value_after_depreciation)
def get_depreciation_amount(self, depreciable_value, total_number_of_depreciations, row):
percentage_value = 100.0 if row.depreciation_method == 'Written Down Value' else 200.0
factor = percentage_value / row.total_number_of_depreciations
factor = percentage_value / total_number_of_depreciations
depreciation_amount = flt(depreciable_value * factor / 100, 0)
value_after_depreciation = flt(depreciable_value) - depreciation_amount
@ -229,7 +235,7 @@ class Asset(AccountsController):
prorata_temporis = 1
if row.depreciation_method in ("Straight Line", "Manual"):
depreciation_amount = (flt(self.value_after_depreciation) -
depreciation_amount = (flt(row.value_after_depreciation) -
flt(row.expected_value_after_useful_life)) / (cint(row.total_number_of_depreciations) -
cint(self.number_of_depreciations_booked)) * prorata_temporis
else:
@ -306,7 +312,7 @@ class Asset(AccountsController):
doc.submit()
def make_gl_entries(self):
if self.purchase_receipt:
if self.purchase_receipt and self.purchase_receipt_amount:
from erpnext.accounts.general_ledger import make_gl_entries
gl_entries = []
@ -320,8 +326,8 @@ class Asset(AccountsController):
"against": fixed_aseet_account,
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"posting_date": self.available_for_use_date,
"credit": self.gross_purchase_amount,
"credit_in_account_currency": self.gross_purchase_amount
"credit": self.purchase_receipt_amount,
"credit_in_account_currency": self.purchase_receipt_amount
}))
gl_entries.append(self.get_gl_dict({
@ -329,8 +335,8 @@ class Asset(AccountsController):
"against": cwip_account,
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"posting_date": self.available_for_use_date,
"debit": self.gross_purchase_amount,
"debit_in_account_currency": self.gross_purchase_amount
"debit": self.purchase_receipt_amount,
"debit_in_account_currency": self.purchase_receipt_amount
}))
make_gl_entries(gl_entries)

View File

@ -5,7 +5,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import flt, today, getdate
from frappe.utils import flt, today, getdate, cint
def post_depreciation_entries(date=None):
# Return if automatic booking of asset depreciation is disabled
@ -47,6 +47,7 @@ def make_depreciation_entry(asset_name, date=None):
je.naming_series = depreciation_series
je.posting_date = d.schedule_date
je.company = asset.company
je.finance_book = d.finance_book
je.remark = "Depreciation Entry against {0} worth {1}".format(asset_name, d.depreciation_amount)
je.append("accounts", {
@ -68,9 +69,12 @@ def make_depreciation_entry(asset_name, date=None):
je.submit()
d.db_set("journal_entry", je.name)
asset.value_after_depreciation -= d.depreciation_amount
idx = cint(d.finance_book_id)
finance_books = asset.get('finance_books')[idx - 1]
finance_books.value_after_depreciation -= d.depreciation_amount
finance_books.db_update()
asset.db_set("value_after_depreciation", asset.value_after_depreciation)
asset.set_status()
return asset

View File

@ -2,7 +2,29 @@
// For license information, please see license.txt
frappe.ui.form.on('Asset Adjustment', {
refresh: function(frm) {
asset: function(frm) {
frm.trigger("set_current_asset_value");
},
finance_book: function(frm) {
frm.trigger("set_current_asset_value");
},
set_current_asset_value: function(frm) {
debugger
if (frm.doc.finance_book && frm.doc.asset) {
frm.call({
method: "erpnext.assets.doctype.asset_adjustment.asset_adjustment.get_current_asset_value",
args: {
asset: frm.doc.asset,
finance_book: frm.doc.finance_book
},
callback: function(r) {
if (r.message) {
frm.set_value('current_asset_value', r.message);
}
}
});
}
}
});

View File

@ -12,6 +12,37 @@
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"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": "Company",
"length": 0,
"no_copy": 0,
"options": "Company",
"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,
@ -38,7 +69,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@ -100,37 +131,7 @@
"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": "current_asset_value",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Current Asset Value",
"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,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@ -231,27 +232,26 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"fieldname": "current_asset_value",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Company",
"label": "Current Asset Value",
"length": 0,
"no_copy": 0,
"options": "Company",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@ -281,7 +281,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@ -292,8 +292,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "accumulated_depreciation_account",
"fieldtype": "Link",
"fieldname": "difference_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -301,15 +301,14 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accumulated Depreciation Account",
"label": "Difference Amount",
"length": 0,
"no_copy": 0,
"options": "Account",
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@ -358,7 +357,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-05-11 00:25:07.222408",
"modified": "2018-05-11 21:45:03.459696",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Adjustment",

View File

@ -4,7 +4,100 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import flt, getdate, cint, date_diff
from erpnext.assets.doctype.asset.depreciation import get_depreciation_accounts
from frappe.model.document import Document
class AssetAdjustment(Document):
pass
def validate(self):
self.set_difference_amount()
self.set_current_asset_value()
def on_submit(self):
self.make_depreciation_entry()
self.reschedule_depreciations()
def on_cancel(self):
if self.journal_entry:
frappe.throw(_("Cancel the journal entry {0} first").format(self.journal_entry))
def set_difference_amount(self):
self.difference_amount = flt(self.current_asset_value - self.new_asset_value)
def set_current_asset_value(self):
if not self.current_asset_value and self.asset and self.finance_book:
self.current_asset_value = get_current_asset_value(self.asset, self.finance_book)
def make_depreciation_entry(self):
asset = frappe.get_doc("Asset", self.asset)
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
get_depreciation_accounts(asset)
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
["depreciation_cost_center", "series_for_depreciation_entry"])
je = frappe.new_doc("Journal Entry")
je.voucher_type = "Depreciation Entry"
je.naming_series = depreciation_series
je.posting_date = self.date
je.company = self.company
je.remark = "Depreciation Entry against {0} worth {1}".format(self.asset, self.difference_amount)
je.append("accounts", {
"account": accumulated_depreciation_account,
"credit_in_account_currency": self.difference_amount,
})
je.append("accounts", {
"account": depreciation_expense_account,
"debit_in_account_currency": self.difference_amount,
"cost_center": depreciation_cost_center
})
je.flags.ignore_permissions = True
je.submit()
self.db_set("journal_entry", je.name)
def reschedule_depreciations(self):
asset = frappe.get_doc('Asset', self.asset)
for d in asset.finance_books:
d.value_after_depreciation = self.new_asset_value
if d.depreciation_method in ("Straight Line", "Manual"):
end_date = max([s.schedule_date for s in asset.schedules if cint(s.finance_book_id) == d.idx])
total_days = date_diff(end_date, self.date)
rate_per_day = flt(d.value_after_depreciation) / flt(total_days)
from_date = self.date
else:
no_of_depreciations = len([e.name for e in asset.schedules
if (cint(s.finance_book_id) == d.idx and not e.journal_entry)])
value_after_depreciation = d.value_after_depreciation
for data in asset.schedules:
if cint(data.finance_book_id) == d.idx and not data.journal_entry:
if d.depreciation_method in ("Straight Line", "Manual"):
days = date_diff(data.schedule_date, from_date)
depreciation_amount = days * rate_per_day
from_date = data.schedule_date
else:
depreciation_amount = asset.get_depreciation_amount(value_after_depreciation,
no_of_depreciations, d)
if depreciation_amount:
value_after_depreciation -= flt(depreciation_amount)
data.depreciation_amount = depreciation_amount
d.db_update()
asset.set_accumulated_depreciation(ignore_booked_entry=True)
for asset_data in asset.schedules:
if not asset_data.journal_entry:
asset_data.db_update()
@frappe.whitelist()
def get_current_asset_value(asset, finance_book):
return frappe.db.get_value('Asset Finance Book',
{'parent': asset, 'parenttype': 'Asset', 'finance_book': finance_book}, 'value_after_depreciation', debug=1)

View File

@ -43,6 +43,10 @@ def get_data():
"type": "doctype",
"name": "Asset Maintenance Log",
},
{
"type": "doctype",
"name": "Asset Adjustment",
},
{
"type": "doctype",
"name": "Asset Repair",

View File

@ -511,6 +511,7 @@ class BuyingController(StockController):
item_data = frappe.db.get_value('Item',
row.item_code, ['asset_naming_series', 'asset_category'], as_dict=1)
purchase_amount = flt(row.base_net_amount + row.item_tax_amount)
asset = frappe.get_doc({
'doctype': 'Asset',
'item_code': row.item_code,
@ -522,7 +523,8 @@ class BuyingController(StockController):
'company': self.company,
'purchase_date': self.posting_date,
'calculate_depreciation': 1,
'gross_purchase_amount': flt(row.base_net_amount + row.item_tax_amount),
'purchase_receipt_amount': purchase_amount,
'gross_purchase_amount': purchase_amount,
'purchase_receipt': self.name if self.doctype == 'Purchase Receipt' else None,
'purchase_invoice': self.name if self.doctype == 'Purchase Invoice' else None
})