diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index 4c40e8e7e81..ccd88a59226 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -22,6 +22,7 @@ "asset_owner_company", "is_existing_asset", "is_composite_asset", + "is_composite_component", "purchase_details_section", "purchase_receipt", "purchase_receipt_item", @@ -236,18 +237,18 @@ "fieldname": "available_for_use_date", "fieldtype": "Date", "label": "Available-for-use Date", - "mandatory_depends_on": "eval:(!doc.is_composite_asset || doc.docstatus==1)" + "mandatory_depends_on": "eval:(!(doc.is_composite_component || doc.is_composite_asset) || doc.docstatus==1)" }, { "default": "0", "fieldname": "calculate_depreciation", "fieldtype": "Check", "label": "Calculate Depreciation", - "read_only_depends_on": "eval:doc.is_composite_asset && !doc.gross_purchase_amount" + "read_only_depends_on": "eval:(doc.is_composite_asset && !doc.gross_purchase_amount) || doc.is_composite_component" }, { "default": "0", - "depends_on": "eval:!doc.is_composite_asset", + "depends_on": "eval:(!doc.is_composite_asset && !doc.is_composite_component)", "fieldname": "is_existing_asset", "fieldtype": "Check", "label": "Is Existing Asset" @@ -469,7 +470,7 @@ }, { "default": "0", - "depends_on": "eval:!doc.is_existing_asset", + "depends_on": "eval:(!doc.is_existing_asset && !doc.is_composite_component)", "fieldname": "is_composite_asset", "fieldtype": "Check", "label": "Is Composite Asset" @@ -550,6 +551,13 @@ "fieldname": "section_break_jtou", "fieldtype": "Section Break", "label": "Additional Info" + }, + { + "default": "0", + "depends_on": "eval:(!doc.is_existing_asset && !doc.is_composite_asset)", + "fieldname": "is_composite_component", + "fieldtype": "Check", + "label": "Is Composite Component" } ], "idx": 72, @@ -593,7 +601,7 @@ "link_fieldname": "target_asset" } ], - "modified": "2025-05-20 00:44:06.229177", + "modified": "2025-05-20 13:44:06.229177", "modified_by": "Administrator", "module": "Assets", "name": "Asset", diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 4ddc60c4e64..9544267dcb5 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -77,6 +77,7 @@ class Asset(AccountsController): insured_value: DF.Data | None insurer: DF.Data | None is_composite_asset: DF.Check + is_composite_component: DF.Check is_existing_asset: DF.Check is_fully_depreciated: DF.Check item_code: DF.Link @@ -186,7 +187,7 @@ class Asset(AccountsController): self.validate_in_use_date() self.make_asset_movement() self.reload() - if not self.booked_fixed_asset and self.validate_make_gl_entry(): + if not self.booked_fixed_asset and not self.is_composite_component and self.validate_make_gl_entry(): self.make_gl_entries() if self.calculate_depreciation and not self.split_from: convert_draft_asset_depr_schedules_into_active(self) @@ -201,8 +202,9 @@ class Asset(AccountsController): cancel_asset_depr_schedules(self) self.set_status() self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry") - make_reverse_gl_entries(voucher_type="Asset", voucher_no=self.name) - self.db_set("booked_fixed_asset", 0) + if not self.is_composite_component: + make_reverse_gl_entries(voucher_type="Asset", voucher_no=self.name) + self.db_set("booked_fixed_asset", 0) add_asset_activity(self.name, _("Asset cancelled")) def after_insert(self): @@ -310,7 +312,7 @@ class Asset(AccountsController): ) def validate_in_use_date(self): - if not self.available_for_use_date: + if not self.available_for_use_date and not self.is_composite_component: frappe.throw(_("Available for use date is required")) for d in self.finance_books: diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index 3942118023b..259cd535fb9 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -785,13 +785,13 @@ def get_disposal_account_and_cost_center(company): def get_value_after_depreciation_on_disposal_date(asset, disposal_date, finance_book=None): asset_doc = frappe.get_doc("Asset", asset) - if asset_doc.available_for_use_date > getdate(disposal_date): - frappe.throw( - "Disposal date {} cannot be before available for use date {} of the asset.".format( - disposal_date, asset_doc.available_for_use_date - ) - ) - elif asset_doc.available_for_use_date == getdate(disposal_date): + if asset_doc.is_composite_component: + validate_disposal_date(asset_doc.purchase_date, getdate(disposal_date), "purchase") + return flt(asset_doc.value_after_depreciation) + + validate_disposal_date(asset_doc.available_for_use_date, getdate(disposal_date), "available for use") + + if asset_doc.available_for_use_date == getdate(disposal_date): return flt(asset_doc.gross_purchase_amount - asset_doc.opening_accumulated_depreciation) if not asset_doc.calculate_depreciation: @@ -816,3 +816,12 @@ def get_value_after_depreciation_on_disposal_date(asset, disposal_date, finance_ flt(asset_doc.gross_purchase_amount) - accumulated_depr_amount, asset_doc.precision("gross_purchase_amount"), ) + + +def validate_disposal_date(reference_date, disposal_date, label): + if reference_date > disposal_date: + frappe.throw( + _("Disposal date {0} cannot be before {1} date {2} of the asset.").format( + disposal_date, label, reference_date + ) + ) diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py index 76518d8e872..bb4081f35d7 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py @@ -70,7 +70,7 @@ class AssetCapitalization(StockController): amended_from: DF.Link | None asset_items: DF.Table[AssetCapitalizationAssetItem] asset_items_total: DF.Currency - capitalization_method: DF.Literal["", "Create a new composite asset", "Choose a WIP composite asset"] + capitalization_method: DF.Literal["", "Create new composite asset", "Use existing composite asset"] company: DF.Link cost_center: DF.Link | None finance_book: DF.Link | None