feat: is composite component checkbox (#47602)

* feat: composite component

* chore: update mandatory depends on according to the new checkbox

* chore: validate disposal date for composite component asset

* fix: updated modified time
This commit is contained in:
Khushi Rawat
2025-05-20 16:51:02 +05:30
committed by GitHub
parent ee27730b72
commit 0f5be4b245
4 changed files with 36 additions and 17 deletions

View File

@@ -22,6 +22,7 @@
"asset_owner_company", "asset_owner_company",
"is_existing_asset", "is_existing_asset",
"is_composite_asset", "is_composite_asset",
"is_composite_component",
"purchase_details_section", "purchase_details_section",
"purchase_receipt", "purchase_receipt",
"purchase_receipt_item", "purchase_receipt_item",
@@ -236,18 +237,18 @@
"fieldname": "available_for_use_date", "fieldname": "available_for_use_date",
"fieldtype": "Date", "fieldtype": "Date",
"label": "Available-for-use 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", "default": "0",
"fieldname": "calculate_depreciation", "fieldname": "calculate_depreciation",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Calculate Depreciation", "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", "default": "0",
"depends_on": "eval:!doc.is_composite_asset", "depends_on": "eval:(!doc.is_composite_asset && !doc.is_composite_component)",
"fieldname": "is_existing_asset", "fieldname": "is_existing_asset",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Is Existing Asset" "label": "Is Existing Asset"
@@ -469,7 +470,7 @@
}, },
{ {
"default": "0", "default": "0",
"depends_on": "eval:!doc.is_existing_asset", "depends_on": "eval:(!doc.is_existing_asset && !doc.is_composite_component)",
"fieldname": "is_composite_asset", "fieldname": "is_composite_asset",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Is Composite Asset" "label": "Is Composite Asset"
@@ -550,6 +551,13 @@
"fieldname": "section_break_jtou", "fieldname": "section_break_jtou",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Additional Info" "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, "idx": 72,
@@ -593,7 +601,7 @@
"link_fieldname": "target_asset" "link_fieldname": "target_asset"
} }
], ],
"modified": "2025-05-20 00:44:06.229177", "modified": "2025-05-20 13:44:06.229177",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Assets", "module": "Assets",
"name": "Asset", "name": "Asset",

View File

@@ -77,6 +77,7 @@ class Asset(AccountsController):
insured_value: DF.Data | None insured_value: DF.Data | None
insurer: DF.Data | None insurer: DF.Data | None
is_composite_asset: DF.Check is_composite_asset: DF.Check
is_composite_component: DF.Check
is_existing_asset: DF.Check is_existing_asset: DF.Check
is_fully_depreciated: DF.Check is_fully_depreciated: DF.Check
item_code: DF.Link item_code: DF.Link
@@ -186,7 +187,7 @@ class Asset(AccountsController):
self.validate_in_use_date() self.validate_in_use_date()
self.make_asset_movement() self.make_asset_movement()
self.reload() 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() self.make_gl_entries()
if self.calculate_depreciation and not self.split_from: if self.calculate_depreciation and not self.split_from:
convert_draft_asset_depr_schedules_into_active(self) convert_draft_asset_depr_schedules_into_active(self)
@@ -201,8 +202,9 @@ class Asset(AccountsController):
cancel_asset_depr_schedules(self) cancel_asset_depr_schedules(self)
self.set_status() self.set_status()
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry") self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
make_reverse_gl_entries(voucher_type="Asset", voucher_no=self.name) if not self.is_composite_component:
self.db_set("booked_fixed_asset", 0) 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")) add_asset_activity(self.name, _("Asset cancelled"))
def after_insert(self): def after_insert(self):
@@ -310,7 +312,7 @@ class Asset(AccountsController):
) )
def validate_in_use_date(self): 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")) frappe.throw(_("Available for use date is required"))
for d in self.finance_books: for d in self.finance_books:

View File

@@ -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): def get_value_after_depreciation_on_disposal_date(asset, disposal_date, finance_book=None):
asset_doc = frappe.get_doc("Asset", asset) asset_doc = frappe.get_doc("Asset", asset)
if asset_doc.available_for_use_date > getdate(disposal_date): if asset_doc.is_composite_component:
frappe.throw( validate_disposal_date(asset_doc.purchase_date, getdate(disposal_date), "purchase")
"Disposal date {} cannot be before available for use date {} of the asset.".format( return flt(asset_doc.value_after_depreciation)
disposal_date, asset_doc.available_for_use_date
) validate_disposal_date(asset_doc.available_for_use_date, getdate(disposal_date), "available for use")
)
elif asset_doc.available_for_use_date == getdate(disposal_date): if asset_doc.available_for_use_date == getdate(disposal_date):
return flt(asset_doc.gross_purchase_amount - asset_doc.opening_accumulated_depreciation) return flt(asset_doc.gross_purchase_amount - asset_doc.opening_accumulated_depreciation)
if not asset_doc.calculate_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, flt(asset_doc.gross_purchase_amount) - accumulated_depr_amount,
asset_doc.precision("gross_purchase_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
)
)

View File

@@ -70,7 +70,7 @@ class AssetCapitalization(StockController):
amended_from: DF.Link | None amended_from: DF.Link | None
asset_items: DF.Table[AssetCapitalizationAssetItem] asset_items: DF.Table[AssetCapitalizationAssetItem]
asset_items_total: DF.Currency 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 company: DF.Link
cost_center: DF.Link | None cost_center: DF.Link | None
finance_book: DF.Link | None finance_book: DF.Link | None