diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 46dbe0742017f02e46fa8d1e4ea3c739a0da3b7f..7a41e8192870e8156172d307635a6260cd15c865 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -187,7 +187,7 @@ frappe.ui.form.on("Asset", { if (frm.doc.docstatus == 0) { frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation); - if (frm.doc.is_composite_asset && !frm.doc.capitalized_in) { + if (frm.doc.is_composite_asset) { $(".primary-action").prop("hidden", true); $(".form-message").text("Capitalize this asset to confirm"); @@ -524,6 +524,8 @@ frappe.ui.form.on("Asset", { frappe.call({ args: { asset: frm.doc.name, + asset_name: frm.doc.asset_name, + item_code: frm.doc.item_code, }, method: "erpnext.assets.doctype.asset.asset.create_asset_capitalization", callback: function (r) { diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index 99a430cbb400d38be8f9d7c3d868ffc784dc8a21..152c40c00b3246bc56bfc4af60cad82ea284a604 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -75,8 +75,7 @@ "purchase_amount", "default_finance_book", "depr_entry_posting_status", - "amended_from", - "capitalized_in" + "amended_from" ], "fields": [ { @@ -222,7 +221,7 @@ "read_only": 1 }, { - "depends_on": "eval:!(doc.is_composite_asset && !doc.capitalized_in)", + "depends_on": "eval:!doc.is_composite_asset", "fieldname": "gross_purchase_amount", "fieldtype": "Currency", "label": "Gross Purchase Amount", @@ -508,14 +507,6 @@ "fieldtype": "Check", "label": "Is Composite Asset" }, - { - "fieldname": "capitalized_in", - "fieldtype": "Link", - "hidden": 1, - "label": "Capitalized In", - "options": "Asset Capitalization", - "read_only": 1 - }, { "depends_on": "eval:doc.docstatus > 0", "fieldname": "total_asset_cost", @@ -589,7 +580,7 @@ "link_fieldname": "target_asset" } ], - "modified": "2024-05-21 13:46:21.066483", + "modified": "2024-07-07 22:27:14.733839", "modified_by": "Administrator", "module": "Assets", "name": "Asset", diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 2116db01cd92bbfee7ad2074c61e2fb9175d5926..60f2f738452cddf07788b08d96fd59b2bed2cf7f 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -60,7 +60,6 @@ class Asset(AccountsController): available_for_use_date: DF.Date | None booked_fixed_asset: DF.Check calculate_depreciation: DF.Check - capitalized_in: DF.Link | None company: DF.Link comprehensive_insurance: DF.Data | None cost_center: DF.Link | None @@ -163,7 +162,6 @@ class Asset(AccountsController): def on_cancel(self): self.validate_cancellation() self.cancel_movement_entries() - self.cancel_capitalization() self.reload() self.delete_depreciation_entries() cancel_asset_depr_schedules(self) @@ -526,13 +524,6 @@ class Asset(AccountsController): movement = frappe.get_doc("Asset Movement", movement.get("name")) movement.cancel() - def cancel_capitalization(self): - if self.capitalized_in: - self.db_set("capitalized_in", None) - asset_capitalization = frappe.get_doc("Asset Capitalization", self.capitalized_in) - if asset_capitalization.docstatus == 1: - asset_capitalization.cancel() - def delete_depreciation_entries(self): if self.calculate_depreciation: for row in self.get("finance_books"): @@ -871,10 +862,15 @@ def create_asset_repair(asset, asset_name): @frappe.whitelist() -def create_asset_capitalization(asset): +def create_asset_capitalization(asset, asset_name, item_code): asset_capitalization = frappe.new_doc("Asset Capitalization") asset_capitalization.update( - {"target_asset": asset, "capitalization_method": "Choose a WIP composite asset"} + { + "target_asset": asset, + "capitalization_method": "Choose a WIP composite asset", + "target_asset_name": asset_name, + "target_item_code": item_code, + } ) return asset_capitalization diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py index 9e9176f592823254249857ab493bcfc76b4f788f..abfab740b08b66f7b1012f9281e0b67635d7ce38 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py @@ -138,22 +138,10 @@ class AssetCapitalization(StockController): "Asset", "Asset Movement", ) - self.cancel_target_asset() self.update_stock_ledger() self.make_gl_entries() self.restore_consumed_asset_items() - def on_trash(self): - frappe.db.set_value("Asset", self.target_asset, "capitalized_in", None) - super().on_trash() - - def cancel_target_asset(self): - if self.entry_type == "Capitalization" and self.target_asset: - asset_doc = frappe.get_doc("Asset", self.target_asset) - asset_doc.db_set("capitalized_in", None) - if asset_doc.docstatus == 1: - asset_doc.cancel() - def set_title(self): self.title = self.target_asset_name or self.target_item_name or self.target_item_code @@ -329,8 +317,12 @@ class AssetCapitalization(StockController): 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")) + if not (self.get("stock_items") or self.get("asset_items") or self.get("service_items")): + frappe.throw( + _( + "Consumed Stock Items, Consumed Asset Items or Consumed Service Items is mandatory for Capitalization" + ) + ) def validate_item(self, item): from erpnext.stock.doctype.item.item import validate_end_of_life @@ -617,7 +609,6 @@ class AssetCapitalization(StockController): asset_doc.purchase_date = self.posting_date asset_doc.gross_purchase_amount = total_target_asset_value asset_doc.purchase_amount = total_target_asset_value - asset_doc.capitalized_in = self.name asset_doc.flags.ignore_validate = True asset_doc.flags.asset_created_via_asset_capitalization = True asset_doc.insert() @@ -653,7 +644,6 @@ class AssetCapitalization(StockController): asset_doc = frappe.get_doc("Asset", self.target_asset) asset_doc.gross_purchase_amount = total_target_asset_value asset_doc.purchase_amount = total_target_asset_value - asset_doc.capitalized_in = self.name asset_doc.flags.ignore_validate = True asset_doc.save() diff --git a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py index 31723ef3be318497bfd38d560bf644621393aad3..5508bdcbef2a0153894b1f7f9f4e73cd83064350 100644 --- a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py @@ -386,6 +386,56 @@ class TestAssetCapitalization(unittest.TestCase): self.assertFalse(get_actual_gle_dict(asset_capitalization.name)) self.assertFalse(get_actual_sle_dict(asset_capitalization.name)) + def test_capitalize_only_service_item(self): + company = "_Test Company" + # Variables + + service_rate = 500 + service_qty = 2 + service_amount = 1000 + + total_amount = 1000 + + wip_composite_asset = create_asset( + asset_name="Asset Capitalization WIP Composite Asset", + is_composite_asset=1, + warehouse="Stores - TCP1", + company=company, + ) + + # Create and submit Asset Captitalization + asset_capitalization = create_asset_capitalization( + entry_type="Capitalization", + capitalization_method="Choose a WIP composite asset", + target_asset=wip_composite_asset.name, + target_asset_location="Test Location", + service_qty=service_qty, + service_rate=service_rate, + service_expense_account="Expenses Included In Asset Valuation - _TC", + company=company, + submit=1, + ) + + self.assertEqual(asset_capitalization.service_items[0].amount, service_amount) + self.assertEqual(asset_capitalization.service_items_total, service_amount) + + target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset) + self.assertEqual(target_asset.gross_purchase_amount, total_amount) + self.assertEqual(target_asset.purchase_amount, total_amount) + + expected_gle = { + "_Test Fixed Asset - _TC": 1000.0, + "Expenses Included In Asset Valuation - _TC": -1000.0, + } + + actual_gle = get_actual_gle_dict(asset_capitalization.name) + self.assertEqual(actual_gle, expected_gle) + + # Cancel Asset Capitalization and make test entries and status are reversed + asset_capitalization.cancel() + self.assertFalse(get_actual_gle_dict(asset_capitalization.name)) + self.assertFalse(get_actual_sle_dict(asset_capitalization.name)) + def create_asset_capitalization_data(): create_item("Capitalization Target Stock Item", is_stock_item=1, is_fixed_asset=0, is_purchase_item=0) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index a76bd7220818782d4fd1c07c7f0789369cddfd71..f3995ae9ae5c0d83b5d0527926f282734a5339b7 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -392,6 +392,7 @@ erpnext.patches.dokos.v4_0.update_advance_for_down_payments #2024-05-207 erpnext.patches.v14_0.migrate_gl_to_payment_ledger erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index # 2023-12-20 erpnext.patches.v14_0.set_maintain_stock_for_bom_item +erpnext.patches.v15_0.delete_orphaned_asset_movement_item_records erpnext.patches.v15_0.fix_debit_credit_in_transaction_currency erpnext.patches.v15_0.rename_purchase_receipt_amount_to_purchase_amount erpnext.patches.v14_0.enable_set_priority_for_pricing_rules #1