diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index ec249c2419..3af7b24b07 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -37,7 +37,6 @@ from erpnext.assets.doctype.asset.depreciation import ( get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal, get_gl_entries_on_asset_regain, - post_depreciation_entries, ) from erpnext.controllers.selling_controller import SellingController from erpnext.healthcare.utils import manage_invoice_submit_cancel @@ -166,7 +165,7 @@ class SalesInvoice(SellingController): if self.update_stock: frappe.throw(_("'Update Stock' cannot be checked for fixed asset sale")) - elif asset.status in ("Scrapped", "Cancelled") or (asset.status == "Sold" and not self.is_return): + elif asset.status in ("Scrapped", "Cancelled", "Capitalized", "Decapitalized") or (asset.status == "Sold" and not self.is_return): frappe.throw(_("Row #{0}: Asset {1} cannot be submitted, it is already {2}").format(d.idx, d.asset, asset.status)) def validate_item_cost_centers(self): @@ -1007,77 +1006,6 @@ class SalesInvoice(SellingController): self.check_finance_books(item, asset) return asset - def check_finance_books(self, item, asset): - if (len(asset.finance_books) > 1 and not item.finance_book - and asset.finance_books[0].finance_book): - frappe.throw(_("Select finance book for the item {0} at row {1}") - .format(item.item_code, item.idx)) - - def depreciate_asset(self, asset): - asset.flags.ignore_validate_update_after_submit = True - asset.prepare_depreciation_data(self.posting_date) - asset.save() - - post_depreciation_entries(self.posting_date) - - def reset_depreciation_schedule(self, asset): - asset.flags.ignore_validate_update_after_submit = True - - # recreate original depreciation schedule of the asset - asset.prepare_depreciation_data() - - self.modify_depreciation_schedule_for_asset_repairs(asset) - asset.save() - - self.delete_depreciation_entry_made_after_sale(asset) - - def modify_depreciation_schedule_for_asset_repairs(self, asset): - asset_repairs = frappe.get_all( - 'Asset Repair', - filters = {'asset': asset.name}, - fields = ['name', 'increase_in_asset_life'] - ) - - for repair in asset_repairs: - if repair.increase_in_asset_life: - asset_repair = frappe.get_doc('Asset Repair', repair.name) - asset_repair.modify_depreciation_schedule() - asset.prepare_depreciation_data() - - def delete_depreciation_entry_made_after_sale(self, asset): - from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry - - posting_date_of_original_invoice = self.get_posting_date_of_sales_invoice() - - row = -1 - finance_book = asset.get('schedules')[0].get('finance_book') - for schedule in asset.get('schedules'): - if schedule.finance_book != finance_book: - row = 0 - finance_book = schedule.finance_book - else: - row += 1 - - if schedule.schedule_date == posting_date_of_original_invoice: - if not self.sale_was_made_on_original_schedule_date(asset, schedule, row, posting_date_of_original_invoice): - reverse_journal_entry = make_reverse_journal_entry(schedule.journal_entry) - reverse_journal_entry.posting_date = nowdate() - reverse_journal_entry.submit() - - def get_posting_date_of_sales_invoice(self): - return frappe.db.get_value('Sales Invoice', self.return_against, 'posting_date') - - # if the invoice had been posted on the date the depreciation was initially supposed to happen, the depreciation shouldn't be undone - def sale_was_made_on_original_schedule_date(self, asset, schedule, row, posting_date_of_original_invoice): - for finance_book in asset.get('finance_books'): - if schedule.finance_book == finance_book.finance_book: - orginal_schedule_date = add_months(finance_book.depreciation_start_date, - row * cint(finance_book.frequency_of_depreciation)) - - if orginal_schedule_date == posting_date_of_original_invoice: - return True - return False - @property def enable_discount_accounting(self): if not hasattr(self, "_enable_discount_accounting"): diff --git a/erpnext/assets/doctype/asset/asset_list.js b/erpnext/assets/doctype/asset/asset_list.js index 4302cb2c51..3d00eb74aa 100644 --- a/erpnext/assets/doctype/asset/asset_list.js +++ b/erpnext/assets/doctype/asset/asset_list.js @@ -10,6 +10,9 @@ frappe.listview_settings['Asset'] = { } else if (doc.status === "Sold") { return [__("Sold"), "green", "status,=,Sold"]; + } else if (["Capitalized", "Decapitalized"].includes(doc.status)) { + return [__(doc.status), "grey", "status,=," + doc.status]; + } else if (doc.status === "Scrapped") { return [__("Scrapped"), "grey", "status,=,Scrapped"]; diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index 609791012a..58d4bb5ebb 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -13,7 +13,7 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( ) -def post_depreciation_entries(date=None): +def post_depreciation_entries(date=None, commit=True): # Return if automatic booking of asset depreciation is disabled if not cint(frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically")): return @@ -22,7 +22,8 @@ def post_depreciation_entries(date=None): date = today() for asset in get_depreciable_assets(date): make_depreciation_entry(asset, date) - frappe.db.commit() + if commit: + frappe.db.commit() def get_depreciable_assets(date): return frappe.db.sql_list("""select a.name @@ -140,7 +141,7 @@ def scrap_asset(asset_name): if asset.docstatus != 1: frappe.throw(_("Asset {0} must be submitted").format(asset.name)) - elif asset.status in ("Cancelled", "Sold", "Scrapped"): + elif asset.status in ("Cancelled", "Sold", "Scrapped", "Capitalized", "Decapitalized"): frappe.throw(_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status)) depreciation_series = frappe.get_cached_value('Company', asset.company, "series_for_depreciation_entry") @@ -269,3 +270,25 @@ def get_disposal_account_and_cost_center(company): frappe.throw(_("Please set 'Asset Depreciation Cost Center' in Company {0}").format(company)) return disposal_account, depreciation_cost_center + + +@frappe.whitelist() +def get_value_after_depreciation_on_disposal_date(asset, disposal_date, finance_book=None): + asset_doc = frappe.get_doc("Asset", asset) + + if asset_doc.calculate_depreciation: + asset_doc.prepare_depreciation_data(getdate(disposal_date)) + + finance_book_id = 1 + if finance_book: + for fb in asset_doc.finance_books: + if fb.finance_book == finance_book: + finance_book_id = fb.idx + break + + asset_schedules = [sch for sch in asset_doc.schedules if cint(sch.finance_book_id) == finance_book_id] + accumulated_depr_amount = asset_schedules[-1].accumulated_depreciation_amount + + return flt(flt(asset_doc.gross_purchase_amount) - accumulated_depr_amount, asset_doc.precision('gross_purchase_amount')) + else: + return flt(asset_doc.value_after_depreciation) diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js index b0f7712d6e..4f8c95e9a0 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js @@ -15,6 +15,10 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s refresh() { erpnext.hide_company(); + this.show_general_ledger(); + if (this.frm.doc.stock_items || !this.frm.doc.target_is_fixed_asset) { + this.show_stock_ledger(); + } } setup_queries() { @@ -33,7 +37,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s filters['item_code'] = me.frm.doc.target_item_code; } - filters['status'] = ["not in", ["Draft", "Scrapped", "Sold"]] + filters['status'] = ["not in", ["Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"]] filters['docstatus'] = 1; return { @@ -43,7 +47,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s me.frm.set_query("asset", "asset_items", function() { var filters = { - 'status': ["not in", ["Draft", "Scrapped", "Sold"]], + 'status': ["not in", ["Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"]], 'docstatus': 1 } @@ -127,6 +131,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s posting_date() { if (this.frm.doc.posting_date) { this.get_all_item_warehouse_details(); + this.get_all_asset_values(); } } diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py index b29decb2d9..e50ddfaba8 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py @@ -2,8 +2,9 @@ # For license information, please see license.txt import frappe +# import erpnext from frappe import _ -from erpnext.controllers.accounts_controller import AccountsController +from erpnext.controllers.stock_controller import StockController from frappe.utils import cint, flt from erpnext.stock.get_item_details import get_item_warehouse, get_default_expense_account, get_default_cost_center from erpnext.stock.doctype.item.item import get_item_defaults @@ -13,6 +14,9 @@ from erpnext.stock.utils import get_incoming_rate from erpnext.stock.stock_ledger import get_previous_sle from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account from erpnext.assets.doctype.asset_value_adjustment.asset_value_adjustment import get_current_asset_value +from erpnext.stock import get_warehouse_account_map +from erpnext.assets.doctype.asset.depreciation import get_gl_entries_on_asset_disposal, get_gl_entries_on_asset_regain,\ + get_value_after_depreciation_on_disposal_date from six import string_types import json @@ -21,7 +25,7 @@ force_fields = ['target_item_name', 'target_asset_name', 'item_name', 'asset_nam 'target_stock_uom', 'stock_uom', 'target_fixed_asset_account', 'fixed_asset_account'] -class AssetCapitalization(AccountsController): +class AssetCapitalization(StockController): def validate(self): self.validate_posting_time() self.set_missing_values(for_validate=True) @@ -36,6 +40,18 @@ class AssetCapitalization(AccountsController): self.calculate_totals() self.set_title() + def before_submit(self): + self.validate_source_mandatory() + + def on_submit(self): + self.update_stock_ledger() + self.make_gl_entries() + + def on_cancel(self): + self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry', 'Repost Item Valuation') + self.update_stock_ledger() + self.make_gl_entries() + def set_entry_type(self): self.entry_type = "Capitalization" if self.target_is_fixed_asset else "Decapitalization" @@ -104,11 +120,15 @@ class AssetCapitalization(AccountsController): self.target_warehouse = None if not target_item.is_fixed_asset: self.target_asset = None + self.target_fixed_asset_account = None if not target_item.has_batch_no: self.target_batch_no = None if not target_item.has_serial_no: self.target_serial_no = "" + if target_item.is_stock_item and not self.target_warehouse: + frappe.throw(_("Target Warehouse is mandatory for Decapitalization")) + self.validate_item(target_item) def validate_target_asset(self): @@ -165,6 +185,13 @@ class AssetCapitalization(AccountsController): if not d.cost_center: d.cost_center = frappe.get_cached_value("Company", self.company, "cost_center") + def validate_source_mandatory(self): + if not self.target_is_fixed_asset and not self.get('asset_items'): + frappe.throw(_("Consumed Asset Items is mandatory for Decapitalization")) + + if not self.get('stock_items') and not self.get('asset_items'): + frappe.throw(_("Consumed Stock Items or Consumed Asset Items is mandatory for Capitalization")) + def validate_item(self, item): from erpnext.stock.doctype.item.item import validate_end_of_life validate_end_of_life(item.name, item.end_of_life, item.disabled) @@ -173,7 +200,7 @@ class AssetCapitalization(AccountsController): return frappe.db.get_value("Asset", asset, ["name", "item_code", "company", "status", "docstatus"], as_dict=1) def validate_asset(self, asset): - if asset.status in ("Draft", "Scrapped", "Sold"): + if asset.status in ("Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"): frappe.throw(_("Asset {0} is {1}").format(asset.name, asset.status)) if asset.docstatus == 0: @@ -196,7 +223,10 @@ class AssetCapitalization(AccountsController): def set_asset_values(self): for d in self.asset_items: if d.asset: - d.asset_value = flt(get_current_asset_value(d.asset, d.get('finance_book') or self.finance_book)) + finance_book = d.get('finance_book') or self.get('finance_book') + d.current_asset_value = flt(get_current_asset_value(d.asset, finance_book=finance_book)) + d.asset_value = get_value_after_depreciation_on_disposal_date(d.asset, self.posting_date, + finance_book=finance_book) def get_args_for_incoming_rate(self, item): return frappe._dict({ @@ -240,6 +270,180 @@ class AssetCapitalization(AccountsController): self.target_qty = flt(self.target_qty, self.precision('target_qty')) self.target_incoming_rate = self.total_value / self.target_qty + def update_stock_ledger(self): + sl_entries = [] + + for d in self.stock_items: + sle = self.get_sl_entries(d, { + "actual_qty": -flt(d.stock_qty), + }) + sl_entries.append(sle) + + if not frappe.db.get_value("Item", self.target_item_code, "is_fixed_asset", cache=1): + sle = self.get_sl_entries(self, { + "item_code": self.target_item_code, + "warehouse": self.target_warehouse, + "batch_no": self.target_batch_no, + "serial_no": self.target_serial_no, + "actual_qty": flt(self.target_qty), + "incoming_rate": flt(self.target_incoming_rate) + }) + sl_entries.append(sle) + + # reverse sl entries if cancel + if self.docstatus == 2: + sl_entries.reverse() + + if sl_entries: + self.make_sl_entries(sl_entries) + + def make_gl_entries(self, gl_entries=None, from_repost=False): + from erpnext.accounts.general_ledger import make_gl_entries, make_reverse_gl_entries + + if not gl_entries: + gl_entries = self.get_gl_entries() + + if self.docstatus == 1: + if gl_entries: + make_gl_entries(gl_entries, from_repost=from_repost) + elif self.docstatus == 2: + make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name) + + def get_gl_entries(self, warehouse_account=None, default_expense_account=None, default_cost_center=None): + # Stock GL Entries + gl_entries = [] + + if not warehouse_account: + warehouse_account = get_warehouse_account_map(self.company) + + precision = self.get_debit_field_precision() + sle_map = self.get_stock_ledger_details() + + if self.target_is_fixed_asset: + target_account = self.target_fixed_asset_account + else: + target_account = warehouse_account[self.target_warehouse]["account"] + + target_against = set() + + # Consumed Stock Items + total_consumed_stock_value = 0 + for item_row in self.stock_items: + sle_list = sle_map.get(item_row.name) + if sle_list: + for sle in sle_list: + stock_value_difference = flt(sle.stock_value_difference, precision) + total_consumed_stock_value += -1 * sle.stock_value_difference + + account = warehouse_account[sle.warehouse]["account"] + target_against.add(account) + + gl_entries.append(self.get_gl_dict({ + "account": account, + "against": target_account, + "cost_center": item_row.cost_center, + "project": item_row.get('project') or self.get('project'), + "remarks": self.get("remarks") or "Accounting Entry for Stock", + "credit": -1 * stock_value_difference, + }, warehouse_account[sle.warehouse]["account_currency"], item=item_row)) + + # Consumed Assets + for item in self.asset_items: + asset = self.get_asset(item) + + if self.docstatus == 2: + fixed_asset_gl_entries = get_gl_entries_on_asset_regain(asset, + item.asset_value, item.get('finance_book') or self.get('finance_book')) + asset.db_set("disposal_date", None) + + self.set_consumed_asset_status(asset) + + if asset.calculate_depreciation: + self.reset_depreciation_schedule(asset) + else: + if asset.calculate_depreciation: + self.depreciate_asset(asset) + + asset.reload() + fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, + item.asset_value, item.get('finance_book') or self.get('finance_book')) + asset.db_set("disposal_date", self.posting_date) + + self.set_consumed_asset_status(asset) + + for gle in fixed_asset_gl_entries: + gle["against"] = target_account + gl_entries.append(self.get_gl_dict(gle, item=item)) + + # Service Expenses + total_service_expenses = 0 + for item_row in self.service_items: + expense_amount = flt(item_row.amount, precision) + total_service_expenses += expense_amount + target_against.add(item_row.expense_account) + + gl_entries.append(self.get_gl_dict({ + "account": item_row.expense_account, + "against": target_account, + "cost_center": item_row.cost_center, + "project": item_row.get('project') or self.get('project'), + "remarks": self.get("remarks") or "Accounting Entry for Stock", + "credit": expense_amount, + }, item=item_row)) + + target_against = ", ".join(target_against) + total_target_stock_value = 0 + total_target_asset_value = 0 + + if self.target_is_fixed_asset: + # Target Asset Item + total_target_asset_value = flt(self.total_value, precision) + gl_entries.append(self.get_gl_dict({ + "account": self.target_fixed_asset_account, + "against": target_against, + "remarks": self.get("remarks") or _("Accounting Entry for Asset"), + "debit": total_target_asset_value, + "cost_center": self.get('cost_center') + }, item=self)) + + if self.docstatus == 1: + asset_doc = frappe.get_doc("Asset", self.target_asset) + asset_doc.purchase_date = self.posting_date + asset_doc.gross_purchase_amount = total_target_asset_value + asset_doc.purchase_receipt_amount = total_target_asset_value + asset_doc.prepare_depreciation_data() + asset_doc.flags.ignore_validate_update_after_submit = True + asset_doc.save() + else: + # Target Stock Item + sle_list = sle_map.get(self.name) + for sle in sle_list: + stock_value_difference = flt(sle.stock_value_difference, precision) + total_target_stock_value += sle.stock_value_difference + account = warehouse_account[sle.warehouse]["account"] + + gl_entries.append(self.get_gl_dict({ + "account": account, + "against": target_against, + "cost_center": self.cost_center, + "project": self.get('project'), + "remarks": self.get("remarks") or "Accounting Entry for Stock", + "debit": stock_value_difference, + }, warehouse_account[sle.warehouse]["account_currency"], item=self)) + + return gl_entries + + def get_asset(self, item): + asset = frappe.get_doc("Asset", item.asset) + self.check_finance_books(item, asset) + return asset + + def set_consumed_asset_status(self, asset): + if self.docstatus == 1: + asset.set_status("Capitalized" if self.target_is_fixed_asset else "Decapitalized") + else: + asset.set_status() + @frappe.whitelist() def get_target_item_details(item_code=None, company=None): @@ -395,8 +599,11 @@ def get_consumed_asset_details(args, get_asset_value=True): if get_asset_value: if args.asset: - out.asset_value = flt(get_current_asset_value(args.asset, finance_book=args.finance_book)) + out.current_asset_value = flt(get_current_asset_value(args.asset, finance_book=args.finance_book)) + out.asset_value = get_value_after_depreciation_on_disposal_date(args.asset, args.posting_date, + finance_book=args.finance_book) else: + out.current_asset_value = 0 out.asset_value = 0 # Account diff --git a/erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.json b/erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.json index a5f820299b..ebaaffbad1 100644 --- a/erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.json +++ b/erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.json @@ -12,6 +12,7 @@ "item_code", "item_name", "section_break_6", + "current_asset_value", "asset_value", "column_break_9", "accounting_dimensions_section", @@ -102,12 +103,20 @@ "fieldtype": "Link", "label": "Finance Book", "options": "Finance Book" + }, + { + "fieldname": "current_asset_value", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Current Asset Value", + "options": "Company:company:default_currency", + "read_only": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-08 23:42:25.143272", + "modified": "2021-09-12 14:30:02.915132", "modified_by": "Administrator", "module": "Assets", "name": "Asset Capitalization Asset Item", diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index b90db054b5..930dca8245 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -54,6 +54,7 @@ from erpnext.stock.get_item_details import ( get_item_tax_map, get_item_warehouse, ) +from erpnext.assets.doctype.asset.depreciation import post_depreciation_entries from erpnext.utilities.transaction_base import TransactionBase @@ -1457,6 +1458,86 @@ class AccountsController(TransactionBase): jv.save() jv.submit() + def check_finance_books(self, item, asset): + if (len(asset.finance_books) > 1 and not item.get('finance_book') and not self.get('finance_book') + and asset.finance_books[0].finance_book): + frappe.throw(_("Select finance book for the item {0} at row {1}") + .format(item.item_code, item.idx)) + + def depreciate_asset(self, asset): + asset.flags.ignore_validate_update_after_submit = True + asset.prepare_depreciation_data(self.posting_date) + asset.save() + + post_depreciation_entries(self.posting_date, commit=False) + + def reset_depreciation_schedule(self, asset): + asset.flags.ignore_validate_update_after_submit = True + + # recreate original depreciation schedule of the asset + asset.prepare_depreciation_data() + + self.modify_depreciation_schedule_for_asset_repairs(asset) + asset.save() + + self.delete_depreciation_entry_made_after_disposal(asset) + + def modify_depreciation_schedule_for_asset_repairs(self, asset): + asset_repairs = frappe.get_all( + 'Asset Repair', + filters={'asset': asset.name}, + fields=['name', 'increase_in_asset_life'] + ) + + for repair in asset_repairs: + if repair.increase_in_asset_life: + asset_repair = frappe.get_doc('Asset Repair', repair.name) + asset_repair.modify_depreciation_schedule() + asset.prepare_depreciation_data() + + def delete_depreciation_entry_made_after_disposal(self, asset): + from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry + + posting_date_of_original_invoice = self.get_posting_date_of_disposal_entry() + + row = -1 + finance_book = asset.get('schedules')[0].get('finance_book') + for schedule in asset.get('schedules'): + if schedule.finance_book != finance_book: + row = 0 + finance_book = schedule.finance_book + else: + row += 1 + + if schedule.schedule_date == posting_date_of_original_invoice: + if not self.disposal_was_made_on_original_schedule_date(asset, schedule, row, + posting_date_of_original_invoice): + reverse_journal_entry = make_reverse_journal_entry(schedule.journal_entry) + reverse_journal_entry.posting_date = nowdate() + + for d in reverse_journal_entry.accounts: + d.reference_type = "Asset" + d.reference_name = asset.name + + reverse_journal_entry.submit() + + def get_posting_date_of_disposal_entry(self): + if self.doctype == "Sales Invoice" and self.return_against: + return frappe.db.get_value('Sales Invoice', self.return_against, 'posting_date') + else: + return self.posting_date + + # if the invoice had been posted on the date the depreciation was initially supposed to happen, the depreciation shouldn't be undone + def disposal_was_made_on_original_schedule_date(self, asset, schedule, row, posting_date_of_original_disposal): + for finance_book in asset.get('finance_books'): + if schedule.finance_book == finance_book.finance_book: + orginal_schedule_date = add_months(finance_book.depreciation_start_date, + row * cint(finance_book.frequency_of_depreciation)) + + if orginal_schedule_date == posting_date_of_original_disposal: + return True + return False + @frappe.whitelist() def get_tax_rate(account_head): return frappe.db.get_value("Account", account_head, ["tax_rate", "account_name"], as_dict=True)