mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-13 10:11:20 +00:00
chore: removal of decapitalization feature (#45162)
* chore: removal of decapitalization feature * fix: rearrangement of asset capitalization doctype fields
This commit is contained in:
@@ -364,7 +364,7 @@ class SalesInvoice(SellingController):
|
|||||||
if self.update_stock:
|
if self.update_stock:
|
||||||
frappe.throw(_("'Update Stock' cannot be checked for fixed asset sale"))
|
frappe.throw(_("'Update Stock' cannot be checked for fixed asset sale"))
|
||||||
|
|
||||||
elif asset.status in ("Scrapped", "Cancelled", "Capitalized", "Decapitalized") or (
|
elif asset.status in ("Scrapped", "Cancelled", "Capitalized") or (
|
||||||
asset.status == "Sold" and not self.is_return
|
asset.status == "Sold" and not self.is_return
|
||||||
):
|
):
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
|
|||||||
@@ -353,7 +353,7 @@
|
|||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Maintenance\nOut of Order\nIssue\nReceipt\nCapitalized\nDecapitalized\nWork In Progress",
|
"options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Maintenance\nOut of Order\nIssue\nReceipt\nCapitalized\nWork In Progress",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ class Asset(AccountsController):
|
|||||||
"Issue",
|
"Issue",
|
||||||
"Receipt",
|
"Receipt",
|
||||||
"Capitalized",
|
"Capitalized",
|
||||||
"Decapitalized",
|
|
||||||
"Work In Progress",
|
"Work In Progress",
|
||||||
]
|
]
|
||||||
supplier: DF.Link | None
|
supplier: DF.Link | None
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ frappe.listview_settings["Asset"] = {
|
|||||||
return [__("Sold"), "green", "status,=,Sold"];
|
return [__("Sold"), "green", "status,=,Sold"];
|
||||||
} else if (doc.status === "Work In Progress") {
|
} else if (doc.status === "Work In Progress") {
|
||||||
return [__("Work In Progress"), "orange", "status,=,Work In Progress"];
|
return [__("Work In Progress"), "orange", "status,=,Work In Progress"];
|
||||||
} else if (["Capitalized", "Decapitalized"].includes(doc.status)) {
|
} else if (doc.status === "Capitalized") {
|
||||||
return [__(doc.status), "grey", "status,=," + doc.status];
|
return [__("Capitalized"), "grey", "status,=,Capitalized"];
|
||||||
} else if (doc.status === "Scrapped") {
|
} else if (doc.status === "Scrapped") {
|
||||||
return [__("Scrapped"), "grey", "status,=,Scrapped"];
|
return [__("Scrapped"), "grey", "status,=,Scrapped"];
|
||||||
} else if (doc.status === "In Maintenance") {
|
} else if (doc.status === "In Maintenance") {
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ def scrap_asset(asset_name, scrap_date=None):
|
|||||||
|
|
||||||
if asset.docstatus != 1:
|
if asset.docstatus != 1:
|
||||||
frappe.throw(_("Asset {0} must be submitted").format(asset.name))
|
frappe.throw(_("Asset {0} must be submitted").format(asset.name))
|
||||||
elif asset.status in ("Cancelled", "Sold", "Scrapped", "Capitalized", "Decapitalized"):
|
elif asset.status in ("Cancelled", "Sold", "Scrapped", "Capitalized"):
|
||||||
frappe.throw(_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status))
|
frappe.throw(_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status))
|
||||||
|
|
||||||
today_date = getdate(today())
|
today_date = getdate(today())
|
||||||
|
|||||||
@@ -36,11 +36,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
|
|||||||
me.setup_warehouse_query();
|
me.setup_warehouse_query();
|
||||||
|
|
||||||
me.frm.set_query("target_item_code", function () {
|
me.frm.set_query("target_item_code", function () {
|
||||||
if (me.frm.doc.entry_type == "Capitalization") {
|
return erpnext.queries.item({ is_stock_item: 0, is_fixed_asset: 1 });
|
||||||
return erpnext.queries.item({ is_stock_item: 0, is_fixed_asset: 1 });
|
|
||||||
} else {
|
|
||||||
return erpnext.queries.item({ is_stock_item: 1, is_fixed_asset: 0 });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
me.frm.set_query("target_asset", function () {
|
me.frm.set_query("target_asset", function () {
|
||||||
@@ -51,7 +47,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
|
|||||||
|
|
||||||
me.frm.set_query("asset", "asset_items", function () {
|
me.frm.set_query("asset", "asset_items", function () {
|
||||||
var filters = {
|
var filters = {
|
||||||
status: ["not in", ["Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"]],
|
status: ["not in", ["Draft", "Scrapped", "Sold", "Capitalized"]],
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,30 +8,26 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"title",
|
"title",
|
||||||
"company",
|
|
||||||
"naming_series",
|
"naming_series",
|
||||||
"entry_type",
|
|
||||||
"target_item_name",
|
|
||||||
"target_is_fixed_asset",
|
|
||||||
"target_has_batch_no",
|
|
||||||
"target_has_serial_no",
|
|
||||||
"column_break_9",
|
|
||||||
"capitalization_method",
|
"capitalization_method",
|
||||||
"target_item_code",
|
"target_item_code",
|
||||||
"target_asset_location",
|
"target_item_name",
|
||||||
"target_asset",
|
"target_asset",
|
||||||
"target_asset_name",
|
"target_asset_name",
|
||||||
"target_warehouse",
|
|
||||||
"target_qty",
|
"target_qty",
|
||||||
"target_stock_uom",
|
"target_asset_location",
|
||||||
"target_batch_no",
|
"column_break_9",
|
||||||
"target_serial_no",
|
"company",
|
||||||
"column_break_5",
|
|
||||||
"finance_book",
|
|
||||||
"posting_date",
|
"posting_date",
|
||||||
"posting_time",
|
"posting_time",
|
||||||
"set_posting_time",
|
"set_posting_time",
|
||||||
|
"finance_book",
|
||||||
|
"target_batch_no",
|
||||||
|
"target_serial_no",
|
||||||
"amended_from",
|
"amended_from",
|
||||||
|
"target_is_fixed_asset",
|
||||||
|
"target_has_batch_no",
|
||||||
|
"target_has_serial_no",
|
||||||
"section_break_16",
|
"section_break_16",
|
||||||
"stock_items",
|
"stock_items",
|
||||||
"stock_items_total",
|
"stock_items_total",
|
||||||
@@ -58,12 +54,12 @@
|
|||||||
"label": "Title"
|
"label": "Title"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:(doc.target_item_code && !doc.__islocal && doc.capitalization_method !== 'Choose a WIP composite asset') || ((doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset') || doc.entry_type=='Decapitalization')",
|
"depends_on": "eval:(doc.target_item_code && !doc.__islocal && doc.capitalization_method !== 'Choose a WIP composite asset') || doc.capitalization_method=='Create a new composite asset'",
|
||||||
"fieldname": "target_item_code",
|
"fieldname": "target_item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Target Item Code",
|
"label": "Target Item Code",
|
||||||
"mandatory_depends_on": "eval:(doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset') || doc.entry_type=='Decapitalization'",
|
"mandatory_depends_on": "eval:doc.capitalization_method=='Create a new composite asset'",
|
||||||
"options": "Item"
|
"options": "Item"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,22 +80,18 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_5",
|
"depends_on": "eval:(doc.target_asset && !doc.__islocal) || doc.capitalization_method=='Choose a WIP composite asset'",
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"depends_on": "eval:(doc.target_asset && !doc.__islocal) || (doc.entry_type=='Capitalization' && doc.capitalization_method=='Choose a WIP composite asset')",
|
|
||||||
"fieldname": "target_asset",
|
"fieldname": "target_asset",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Target Asset",
|
"label": "Target Asset",
|
||||||
"mandatory_depends_on": "eval:doc.entry_type=='Capitalization' && doc.capitalization_method=='Choose a WIP composite asset'",
|
"mandatory_depends_on": "eval:doc.capitalization_method=='Choose a WIP composite asset'",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Asset",
|
"options": "Asset",
|
||||||
"read_only_depends_on": "eval:(doc.entry_type=='Decapitalization') || (doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset')"
|
"read_only_depends_on": "eval:doc.capitalization_method=='Create a new composite asset'"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:(doc.target_asset_name && !doc.__islocal) || (doc.target_asset && doc.entry_type=='Capitalization' && doc.capitalization_method=='Choose a WIP composite asset')",
|
"depends_on": "eval:(doc.target_asset_name && !doc.__islocal) || (doc.target_asset && doc.capitalization_method=='Choose a WIP composite asset')",
|
||||||
"fetch_from": "target_asset.asset_name",
|
"fetch_from": "target_asset.asset_name",
|
||||||
"fieldname": "target_asset_name",
|
"fieldname": "target_asset_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
@@ -162,7 +154,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.entry_type=='Capitalization' && (doc.docstatus == 0 || (doc.stock_items && doc.stock_items.length))",
|
"depends_on": "eval:doc.docstatus == 0 || (doc.stock_items && doc.stock_items.length)",
|
||||||
"fieldname": "section_break_16",
|
"fieldname": "section_break_16",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Consumed Stock Items"
|
"label": "Consumed Stock Items"
|
||||||
@@ -173,14 +165,6 @@
|
|||||||
"label": "Stock Items",
|
"label": "Stock Items",
|
||||||
"options": "Asset Capitalization Stock Item"
|
"options": "Asset Capitalization Stock Item"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"depends_on": "eval:doc.entry_type=='Decapitalization'",
|
|
||||||
"fieldname": "target_warehouse",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Target Warehouse",
|
|
||||||
"mandatory_depends_on": "eval:doc.entry_type=='Decapitalization'",
|
|
||||||
"options": "Warehouse"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"depends_on": "target_has_batch_no",
|
"depends_on": "target_has_batch_no",
|
||||||
"fieldname": "target_batch_no",
|
"fieldname": "target_batch_no",
|
||||||
@@ -190,20 +174,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"depends_on": "eval:doc.entry_type=='Decapitalization'",
|
|
||||||
"fieldname": "target_qty",
|
"fieldname": "target_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Target Qty",
|
"label": "Target Qty"
|
||||||
"read_only_depends_on": "eval:doc.entry_type=='Capitalization'"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"depends_on": "eval:doc.entry_type=='Decapitalization'",
|
|
||||||
"fetch_from": "target_item_code.stock_uom",
|
|
||||||
"fieldname": "target_stock_uom",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Stock UOM",
|
|
||||||
"options": "UOM",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@@ -241,16 +214,6 @@
|
|||||||
"label": "Assets",
|
"label": "Assets",
|
||||||
"options": "Asset Capitalization Asset Item"
|
"options": "Asset Capitalization Asset Item"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"default": "Capitalization",
|
|
||||||
"fieldname": "entry_type",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Entry Type",
|
|
||||||
"options": "Capitalization\nDecapitalization",
|
|
||||||
"reqd": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "stock_items_total",
|
"fieldname": "stock_items_total",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
@@ -272,7 +235,7 @@
|
|||||||
"options": "Finance Book"
|
"options": "Finance Book"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.entry_type=='Capitalization' && (doc.docstatus == 0 || (doc.service_items && doc.service_items.length))",
|
"depends_on": "eval:doc.docstatus == 0 || (doc.service_items && doc.service_items.length)",
|
||||||
"fieldname": "service_expenses_section",
|
"fieldname": "service_expenses_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Service Expenses"
|
"label": "Service Expenses"
|
||||||
@@ -337,26 +300,24 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset'",
|
"depends_on": "eval:doc.capitalization_method=='Create a new composite asset'",
|
||||||
"fieldname": "target_asset_location",
|
"fieldname": "target_asset_location",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Target Asset Location",
|
"label": "Target Asset Location",
|
||||||
"mandatory_depends_on": "eval:doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset'",
|
"mandatory_depends_on": "eval:doc.capitalization_method=='Create a new composite asset'",
|
||||||
"options": "Location"
|
"options": "Location"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.entry_type=='Capitalization'",
|
|
||||||
"fieldname": "capitalization_method",
|
"fieldname": "capitalization_method",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Capitalization Method",
|
"label": "Capitalization Method",
|
||||||
"mandatory_depends_on": "eval:doc.entry_type=='Capitalization'",
|
|
||||||
"options": "\nCreate a new composite asset\nChoose a WIP composite asset"
|
"options": "\nCreate a new composite asset\nChoose a WIP composite asset"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-03-27 13:06:33.080441",
|
"modified": "2025-01-08 13:14:33.008458",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Capitalization",
|
"name": "Asset Capitalization",
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ force_fields = [
|
|||||||
"target_is_fixed_asset",
|
"target_is_fixed_asset",
|
||||||
"target_has_serial_no",
|
"target_has_serial_no",
|
||||||
"target_has_batch_no",
|
"target_has_batch_no",
|
||||||
"target_stock_uom",
|
|
||||||
"stock_uom",
|
"stock_uom",
|
||||||
"fixed_asset_account",
|
"fixed_asset_account",
|
||||||
"valuation_rate",
|
"valuation_rate",
|
||||||
@@ -74,7 +73,6 @@ class AssetCapitalization(StockController):
|
|||||||
capitalization_method: DF.Literal["", "Create a new composite asset", "Choose a WIP composite asset"]
|
capitalization_method: DF.Literal["", "Create a new composite asset", "Choose a WIP composite asset"]
|
||||||
company: DF.Link
|
company: DF.Link
|
||||||
cost_center: DF.Link | None
|
cost_center: DF.Link | None
|
||||||
entry_type: DF.Literal["Capitalization", "Decapitalization"]
|
|
||||||
finance_book: DF.Link | None
|
finance_book: DF.Link | None
|
||||||
naming_series: DF.Literal["ACC-ASC-.YYYY.-"]
|
naming_series: DF.Literal["ACC-ASC-.YYYY.-"]
|
||||||
posting_date: DF.Date
|
posting_date: DF.Date
|
||||||
@@ -97,8 +95,6 @@ class AssetCapitalization(StockController):
|
|||||||
target_item_name: DF.Data | None
|
target_item_name: DF.Data | None
|
||||||
target_qty: DF.Float
|
target_qty: DF.Float
|
||||||
target_serial_no: DF.SmallText | None
|
target_serial_no: DF.SmallText | None
|
||||||
target_stock_uom: DF.Link | None
|
|
||||||
target_warehouse: DF.Link | None
|
|
||||||
title: DF.Data | None
|
title: DF.Data | None
|
||||||
total_value: DF.Currency
|
total_value: DF.Currency
|
||||||
# end: auto-generated types
|
# end: auto-generated types
|
||||||
@@ -191,31 +187,18 @@ class AssetCapitalization(StockController):
|
|||||||
def validate_target_item(self):
|
def validate_target_item(self):
|
||||||
target_item = frappe.get_cached_doc("Item", self.target_item_code)
|
target_item = frappe.get_cached_doc("Item", self.target_item_code)
|
||||||
|
|
||||||
if not target_item.is_fixed_asset and not target_item.is_stock_item:
|
if not target_item.is_fixed_asset:
|
||||||
frappe.throw(
|
|
||||||
_("Target Item {0} is neither a Fixed Asset nor a Stock Item").format(target_item.name)
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.entry_type == "Capitalization" and not target_item.is_fixed_asset:
|
|
||||||
frappe.throw(_("Target Item {0} must be a Fixed Asset item").format(target_item.name))
|
frappe.throw(_("Target Item {0} must be a Fixed Asset item").format(target_item.name))
|
||||||
elif self.entry_type == "Decapitalization" and not target_item.is_stock_item:
|
|
||||||
frappe.throw(_("Target Item {0} must be a Stock Item").format(target_item.name))
|
|
||||||
|
|
||||||
if target_item.is_fixed_asset:
|
if target_item.is_fixed_asset:
|
||||||
self.target_qty = 1
|
self.target_qty = 1
|
||||||
if flt(self.target_qty) <= 0:
|
if flt(self.target_qty) <= 0:
|
||||||
frappe.throw(_("Target Qty must be a positive number"))
|
frappe.throw(_("Target Qty must be a positive number"))
|
||||||
|
|
||||||
if not target_item.is_stock_item:
|
|
||||||
self.target_warehouse = None
|
|
||||||
if not target_item.has_batch_no:
|
if not target_item.has_batch_no:
|
||||||
self.target_batch_no = None
|
self.target_batch_no = None
|
||||||
if not target_item.has_serial_no:
|
if not target_item.has_serial_no:
|
||||||
self.target_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)
|
self.validate_item(target_item)
|
||||||
|
|
||||||
def validate_target_asset(self):
|
def validate_target_asset(self):
|
||||||
@@ -232,7 +215,7 @@ class AssetCapitalization(StockController):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if target_asset.status in ("Scrapped", "Sold", "Capitalized", "Decapitalized"):
|
if target_asset.status in ("Scrapped", "Sold", "Capitalized"):
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("Target Asset {0} cannot be {1}").format(target_asset.name, target_asset.status)
|
_("Target Asset {0} cannot be {1}").format(target_asset.name, target_asset.status)
|
||||||
)
|
)
|
||||||
@@ -274,7 +257,7 @@ class AssetCapitalization(StockController):
|
|||||||
|
|
||||||
asset = self.get_asset_for_validation(d.asset)
|
asset = self.get_asset_for_validation(d.asset)
|
||||||
|
|
||||||
if asset.status in ("Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"):
|
if asset.status in ("Draft", "Scrapped", "Sold", "Capitalized"):
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("Row #{0}: Consumed Asset {1} cannot be {2}").format(
|
_("Row #{0}: Consumed Asset {1} cannot be {2}").format(
|
||||||
d.idx, asset.name, asset.status
|
d.idx, asset.name, asset.status
|
||||||
@@ -315,9 +298,6 @@ class AssetCapitalization(StockController):
|
|||||||
d.cost_center = frappe.get_cached_value("Company", self.company, "cost_center")
|
d.cost_center = frappe.get_cached_value("Company", self.company, "cost_center")
|
||||||
|
|
||||||
def validate_source_mandatory(self):
|
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 self.capitalization_method == "Create a new composite asset" and not (
|
if self.capitalization_method == "Create a new composite asset" and not (
|
||||||
self.get("stock_items") or self.get("asset_items")
|
self.get("stock_items") or self.get("asset_items")
|
||||||
):
|
):
|
||||||
@@ -421,18 +401,6 @@ class AssetCapitalization(StockController):
|
|||||||
)
|
)
|
||||||
sl_entries.append(sle)
|
sl_entries.append(sle)
|
||||||
|
|
||||||
if self.entry_type == "Decapitalization" and not self.target_is_fixed_asset:
|
|
||||||
sle = self.get_sl_entries(
|
|
||||||
self,
|
|
||||||
{
|
|
||||||
"item_code": self.target_item_code,
|
|
||||||
"warehouse": self.target_warehouse,
|
|
||||||
"actual_qty": flt(self.target_qty),
|
|
||||||
"incoming_rate": flt(self.target_incoming_rate),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
sl_entries.append(sle)
|
|
||||||
|
|
||||||
# reverse sl entries if cancel
|
# reverse sl entries if cancel
|
||||||
if self.docstatus == 2:
|
if self.docstatus == 2:
|
||||||
sl_entries.reverse()
|
sl_entries.reverse()
|
||||||
@@ -475,21 +443,18 @@ class AssetCapitalization(StockController):
|
|||||||
return gl_entries
|
return gl_entries
|
||||||
|
|
||||||
def get_target_account(self):
|
def get_target_account(self):
|
||||||
if self.target_is_fixed_asset:
|
from erpnext.assets.doctype.asset.asset import is_cwip_accounting_enabled
|
||||||
from erpnext.assets.doctype.asset.asset import is_cwip_accounting_enabled
|
|
||||||
|
|
||||||
asset_category = frappe.get_cached_value("Asset", self.target_asset, "asset_category")
|
asset_category = frappe.get_cached_value("Asset", self.target_asset, "asset_category")
|
||||||
if is_cwip_accounting_enabled(asset_category):
|
if is_cwip_accounting_enabled(asset_category):
|
||||||
target_account = get_asset_category_account(
|
target_account = get_asset_category_account(
|
||||||
"capital_work_in_progress_account",
|
"capital_work_in_progress_account",
|
||||||
asset_category=asset_category,
|
asset_category=asset_category,
|
||||||
company=self.company,
|
company=self.company,
|
||||||
)
|
)
|
||||||
return target_account if target_account else self.target_fixed_asset_account
|
return target_account if target_account else self.target_fixed_asset_account
|
||||||
else:
|
|
||||||
return self.target_fixed_asset_account
|
|
||||||
else:
|
else:
|
||||||
return self.warehouse_account[self.target_warehouse]["account"]
|
return self.target_fixed_asset_account
|
||||||
|
|
||||||
def get_gl_entries_for_consumed_stock_items(self, gl_entries, target_account, target_against, precision):
|
def get_gl_entries_for_consumed_stock_items(self, gl_entries, target_account, target_against, precision):
|
||||||
# Consumed Stock Items
|
# Consumed Stock Items
|
||||||
@@ -590,33 +555,9 @@ class AssetCapitalization(StockController):
|
|||||||
item=self,
|
item=self,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
# Target Stock Item
|
|
||||||
sle_list = self.sle_map.get(self.name)
|
|
||||||
for sle in sle_list:
|
|
||||||
stock_value_difference = flt(sle.stock_value_difference, precision)
|
|
||||||
account = self.warehouse_account[sle.warehouse]["account"]
|
|
||||||
|
|
||||||
gl_entries.append(
|
|
||||||
self.get_gl_dict(
|
|
||||||
{
|
|
||||||
"account": account,
|
|
||||||
"against": ", ".join(target_against),
|
|
||||||
"cost_center": self.cost_center,
|
|
||||||
"project": self.get("project"),
|
|
||||||
"remarks": self.get("remarks") or "Accounting Entry for Stock",
|
|
||||||
"debit": stock_value_difference,
|
|
||||||
},
|
|
||||||
self.warehouse_account[sle.warehouse]["account_currency"],
|
|
||||||
item=self,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def create_target_asset(self):
|
def create_target_asset(self):
|
||||||
if (
|
if self.capitalization_method != "Create a new composite asset":
|
||||||
self.entry_type != "Capitalization"
|
|
||||||
or self.capitalization_method != "Create a new composite asset"
|
|
||||||
):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
total_target_asset_value = flt(self.total_value, self.precision("total_value"))
|
total_target_asset_value = flt(self.total_value, self.precision("total_value"))
|
||||||
@@ -655,10 +596,7 @@ class AssetCapitalization(StockController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def update_target_asset(self):
|
def update_target_asset(self):
|
||||||
if (
|
if self.capitalization_method != "Choose a WIP composite asset":
|
||||||
self.entry_type != "Capitalization"
|
|
||||||
or self.capitalization_method != "Choose a WIP composite asset"
|
|
||||||
):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
total_target_asset_value = flt(self.total_value, self.precision("total_value"))
|
total_target_asset_value = flt(self.total_value, self.precision("total_value"))
|
||||||
@@ -701,14 +639,6 @@ class AssetCapitalization(StockController):
|
|||||||
get_link_to_form("Asset Capitalization", self.name)
|
get_link_to_form("Asset Capitalization", self.name)
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
asset.set_status("Decapitalized")
|
|
||||||
add_asset_activity(
|
|
||||||
asset.name,
|
|
||||||
_("Asset decapitalized after Asset Capitalization {0} was submitted").format(
|
|
||||||
get_link_to_form("Asset Capitalization", self.name)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
asset.set_status()
|
asset.set_status()
|
||||||
add_asset_activity(
|
add_asset_activity(
|
||||||
@@ -730,16 +660,12 @@ def get_target_item_details(item_code=None, company=None):
|
|||||||
|
|
||||||
# Set Item Details
|
# Set Item Details
|
||||||
out.target_item_name = item.item_name
|
out.target_item_name = item.item_name
|
||||||
out.target_stock_uom = item.stock_uom
|
|
||||||
out.target_is_fixed_asset = cint(item.is_fixed_asset)
|
out.target_is_fixed_asset = cint(item.is_fixed_asset)
|
||||||
out.target_has_batch_no = cint(item.has_batch_no)
|
out.target_has_batch_no = cint(item.has_batch_no)
|
||||||
out.target_has_serial_no = cint(item.has_serial_no)
|
out.target_has_serial_no = cint(item.has_serial_no)
|
||||||
|
|
||||||
if out.target_is_fixed_asset:
|
if out.target_is_fixed_asset:
|
||||||
out.target_qty = 1
|
out.target_qty = 1
|
||||||
out.target_warehouse = None
|
|
||||||
else:
|
|
||||||
out.target_asset = None
|
|
||||||
|
|
||||||
if not out.target_has_batch_no:
|
if not out.target_has_batch_no:
|
||||||
out.target_batch_no = None
|
out.target_batch_no = None
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ class TestAssetCapitalization(IntegrationTestCase):
|
|||||||
|
|
||||||
# Create and submit Asset Captitalization
|
# Create and submit Asset Captitalization
|
||||||
asset_capitalization = create_asset_capitalization(
|
asset_capitalization = create_asset_capitalization(
|
||||||
entry_type="Capitalization",
|
|
||||||
capitalization_method="Create a new composite asset",
|
capitalization_method="Create a new composite asset",
|
||||||
target_item_code="Macbook Pro",
|
target_item_code="Macbook Pro",
|
||||||
target_asset_location="Test Location",
|
target_asset_location="Test Location",
|
||||||
@@ -76,7 +75,6 @@ class TestAssetCapitalization(IntegrationTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Test Asset Capitalization values
|
# Test Asset Capitalization values
|
||||||
self.assertEqual(asset_capitalization.entry_type, "Capitalization")
|
|
||||||
self.assertEqual(asset_capitalization.target_qty, 1)
|
self.assertEqual(asset_capitalization.target_qty, 1)
|
||||||
|
|
||||||
self.assertEqual(asset_capitalization.stock_items[0].valuation_rate, stock_rate)
|
self.assertEqual(asset_capitalization.stock_items[0].valuation_rate, stock_rate)
|
||||||
@@ -152,7 +150,6 @@ class TestAssetCapitalization(IntegrationTestCase):
|
|||||||
|
|
||||||
# Create and submit Asset Captitalization
|
# Create and submit Asset Captitalization
|
||||||
asset_capitalization = create_asset_capitalization(
|
asset_capitalization = create_asset_capitalization(
|
||||||
entry_type="Capitalization",
|
|
||||||
capitalization_method="Create a new composite asset",
|
capitalization_method="Create a new composite asset",
|
||||||
target_item_code="Macbook Pro",
|
target_item_code="Macbook Pro",
|
||||||
target_asset_location="Test Location",
|
target_asset_location="Test Location",
|
||||||
@@ -167,7 +164,6 @@ class TestAssetCapitalization(IntegrationTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Test Asset Capitalization values
|
# Test Asset Capitalization values
|
||||||
self.assertEqual(asset_capitalization.entry_type, "Capitalization")
|
|
||||||
self.assertEqual(asset_capitalization.target_qty, 1)
|
self.assertEqual(asset_capitalization.target_qty, 1)
|
||||||
|
|
||||||
self.assertEqual(asset_capitalization.stock_items[0].valuation_rate, stock_rate)
|
self.assertEqual(asset_capitalization.stock_items[0].valuation_rate, stock_rate)
|
||||||
@@ -244,7 +240,6 @@ class TestAssetCapitalization(IntegrationTestCase):
|
|||||||
|
|
||||||
# Create and submit Asset Captitalization
|
# Create and submit Asset Captitalization
|
||||||
asset_capitalization = create_asset_capitalization(
|
asset_capitalization = create_asset_capitalization(
|
||||||
entry_type="Capitalization",
|
|
||||||
capitalization_method="Choose a WIP composite asset",
|
capitalization_method="Choose a WIP composite asset",
|
||||||
target_asset=wip_composite_asset.name,
|
target_asset=wip_composite_asset.name,
|
||||||
target_asset_location="Test Location",
|
target_asset_location="Test Location",
|
||||||
@@ -256,7 +251,6 @@ class TestAssetCapitalization(IntegrationTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Test Asset Capitalization values
|
# Test Asset Capitalization values
|
||||||
self.assertEqual(asset_capitalization.entry_type, "Capitalization")
|
|
||||||
self.assertEqual(asset_capitalization.capitalization_method, "Choose a WIP composite asset")
|
self.assertEqual(asset_capitalization.capitalization_method, "Choose a WIP composite asset")
|
||||||
self.assertEqual(asset_capitalization.target_qty, 1)
|
self.assertEqual(asset_capitalization.target_qty, 1)
|
||||||
|
|
||||||
@@ -297,110 +291,6 @@ class TestAssetCapitalization(IntegrationTestCase):
|
|||||||
self.assertFalse(get_actual_gle_dict(asset_capitalization.name))
|
self.assertFalse(get_actual_gle_dict(asset_capitalization.name))
|
||||||
self.assertFalse(get_actual_sle_dict(asset_capitalization.name))
|
self.assertFalse(get_actual_sle_dict(asset_capitalization.name))
|
||||||
|
|
||||||
def test_decapitalization_with_depreciation(self):
|
|
||||||
# Variables
|
|
||||||
purchase_date = "2020-01-01"
|
|
||||||
depreciation_start_date = "2020-12-31"
|
|
||||||
capitalization_date = "2021-06-30"
|
|
||||||
|
|
||||||
total_number_of_depreciations = 3
|
|
||||||
expected_value_after_useful_life = 10_000
|
|
||||||
consumed_asset_purchase_value = 100_000
|
|
||||||
consumed_asset_current_value = 70_000
|
|
||||||
consumed_asset_value_before_disposal = 55_000
|
|
||||||
|
|
||||||
target_qty = 10
|
|
||||||
target_incoming_rate = 5500
|
|
||||||
|
|
||||||
depreciation_before_disposal_amount = 15_000
|
|
||||||
accumulated_depreciation = 45_000
|
|
||||||
|
|
||||||
# to accomodate for depreciation on disposal calculation minor difference
|
|
||||||
consumed_asset_value_before_disposal = 55_123.29
|
|
||||||
target_incoming_rate = 5512.329
|
|
||||||
depreciation_before_disposal_amount = 14_876.71
|
|
||||||
accumulated_depreciation = 44_876.71
|
|
||||||
|
|
||||||
# Create assets
|
|
||||||
consumed_asset = create_depreciation_asset(
|
|
||||||
asset_name="Asset Capitalization Consumable Asset",
|
|
||||||
asset_value=consumed_asset_purchase_value,
|
|
||||||
purchase_date=purchase_date,
|
|
||||||
depreciation_start_date=depreciation_start_date,
|
|
||||||
depreciation_method="Straight Line",
|
|
||||||
total_number_of_depreciations=total_number_of_depreciations,
|
|
||||||
frequency_of_depreciation=12,
|
|
||||||
expected_value_after_useful_life=expected_value_after_useful_life,
|
|
||||||
company="_Test Company with perpetual inventory",
|
|
||||||
submit=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
first_asset_depr_schedule = get_asset_depr_schedule_doc(consumed_asset.name, "Active")
|
|
||||||
self.assertEqual(first_asset_depr_schedule.status, "Active")
|
|
||||||
|
|
||||||
# Create and submit Asset Captitalization
|
|
||||||
asset_capitalization = create_asset_capitalization(
|
|
||||||
entry_type="Decapitalization",
|
|
||||||
posting_date=capitalization_date, # half a year
|
|
||||||
target_item_code="Capitalization Target Stock Item",
|
|
||||||
target_qty=target_qty,
|
|
||||||
consumed_asset=consumed_asset.name,
|
|
||||||
company="_Test Company with perpetual inventory",
|
|
||||||
submit=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Test Asset Capitalization values
|
|
||||||
self.assertEqual(asset_capitalization.entry_type, "Decapitalization")
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
asset_capitalization.asset_items[0].current_asset_value, consumed_asset_current_value
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
asset_capitalization.asset_items[0].asset_value, consumed_asset_value_before_disposal
|
|
||||||
)
|
|
||||||
self.assertEqual(asset_capitalization.asset_items_total, consumed_asset_value_before_disposal)
|
|
||||||
|
|
||||||
self.assertEqual(asset_capitalization.total_value, consumed_asset_value_before_disposal)
|
|
||||||
self.assertEqual(asset_capitalization.target_incoming_rate, target_incoming_rate)
|
|
||||||
|
|
||||||
# Test Consumed Asset values
|
|
||||||
consumed_asset.reload()
|
|
||||||
self.assertEqual(consumed_asset.status, "Decapitalized")
|
|
||||||
|
|
||||||
first_asset_depr_schedule.load_from_db()
|
|
||||||
|
|
||||||
second_asset_depr_schedule = get_asset_depr_schedule_doc(consumed_asset.name, "Active")
|
|
||||||
self.assertEqual(second_asset_depr_schedule.status, "Active")
|
|
||||||
self.assertEqual(first_asset_depr_schedule.status, "Cancelled")
|
|
||||||
|
|
||||||
depr_schedule_of_consumed_asset = second_asset_depr_schedule.get("depreciation_schedule")
|
|
||||||
|
|
||||||
consumed_depreciation_schedule = [
|
|
||||||
d
|
|
||||||
for d in depr_schedule_of_consumed_asset
|
|
||||||
if getdate(d.schedule_date) == getdate(capitalization_date)
|
|
||||||
]
|
|
||||||
self.assertTrue(consumed_depreciation_schedule and consumed_depreciation_schedule[0].journal_entry)
|
|
||||||
self.assertEqual(
|
|
||||||
consumed_depreciation_schedule[0].depreciation_amount, depreciation_before_disposal_amount
|
|
||||||
)
|
|
||||||
|
|
||||||
# Test General Ledger Entries
|
|
||||||
expected_gle = {
|
|
||||||
"_Test Warehouse - TCP1": consumed_asset_value_before_disposal,
|
|
||||||
"_Test Accumulated Depreciations - TCP1": accumulated_depreciation,
|
|
||||||
"_Test Fixed Asset - TCP1": -consumed_asset_purchase_value,
|
|
||||||
}
|
|
||||||
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.reload()
|
|
||||||
asset_capitalization.cancel()
|
|
||||||
self.assertEqual(consumed_asset.db_get("status"), "Partially Depreciated")
|
|
||||||
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):
|
def test_capitalize_only_service_item(self):
|
||||||
company = "_Test Company"
|
company = "_Test Company"
|
||||||
# Variables
|
# Variables
|
||||||
@@ -420,7 +310,6 @@ class TestAssetCapitalization(IntegrationTestCase):
|
|||||||
|
|
||||||
# Create and submit Asset Captitalization
|
# Create and submit Asset Captitalization
|
||||||
asset_capitalization = create_asset_capitalization(
|
asset_capitalization = create_asset_capitalization(
|
||||||
entry_type="Capitalization",
|
|
||||||
capitalization_method="Choose a WIP composite asset",
|
capitalization_method="Choose a WIP composite asset",
|
||||||
target_asset=wip_composite_asset.name,
|
target_asset=wip_composite_asset.name,
|
||||||
target_asset_location="Test Location",
|
target_asset_location="Test Location",
|
||||||
@@ -468,13 +357,11 @@ def create_asset_capitalization(**args):
|
|||||||
target_item_code = target_asset.item_code or args.target_item_code
|
target_item_code = target_asset.item_code or args.target_item_code
|
||||||
company = target_asset.company or args.company or "_Test Company"
|
company = target_asset.company or args.company or "_Test Company"
|
||||||
warehouse = args.warehouse or create_warehouse("_Test Warehouse", company=company)
|
warehouse = args.warehouse or create_warehouse("_Test Warehouse", company=company)
|
||||||
target_warehouse = args.target_warehouse or warehouse
|
|
||||||
source_warehouse = args.source_warehouse or warehouse
|
source_warehouse = args.source_warehouse or warehouse
|
||||||
|
|
||||||
asset_capitalization = frappe.new_doc("Asset Capitalization")
|
asset_capitalization = frappe.new_doc("Asset Capitalization")
|
||||||
asset_capitalization.update(
|
asset_capitalization.update(
|
||||||
{
|
{
|
||||||
"entry_type": args.entry_type or "Capitalization",
|
|
||||||
"capitalization_method": args.capitalization_method or None,
|
"capitalization_method": args.capitalization_method or None,
|
||||||
"company": company,
|
"company": company,
|
||||||
"posting_date": args.posting_date or now.strftime("%Y-%m-%d"),
|
"posting_date": args.posting_date or now.strftime("%Y-%m-%d"),
|
||||||
@@ -482,7 +369,6 @@ def create_asset_capitalization(**args):
|
|||||||
"target_item_code": target_item_code,
|
"target_item_code": target_item_code,
|
||||||
"target_asset": target_asset.name,
|
"target_asset": target_asset.name,
|
||||||
"target_asset_location": "Test Location",
|
"target_asset_location": "Test Location",
|
||||||
"target_warehouse": target_warehouse,
|
|
||||||
"target_qty": flt(args.target_qty) or 1,
|
"target_qty": flt(args.target_qty) or 1,
|
||||||
"target_batch_no": args.target_batch_no,
|
"target_batch_no": args.target_batch_no,
|
||||||
"target_serial_no": args.target_serial_no,
|
"target_serial_no": args.target_serial_no,
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ def get_conditions(filters):
|
|||||||
conditions["cost_center"] = filters.get("cost_center")
|
conditions["cost_center"] = filters.get("cost_center")
|
||||||
|
|
||||||
if status:
|
if status:
|
||||||
# In Store assets are those that are not sold or scrapped or capitalized or decapitalized
|
# In Store assets are those that are not sold or scrapped or capitalized
|
||||||
operand = "not in"
|
operand = "not in"
|
||||||
if status not in "In Location":
|
if status not in "In Location":
|
||||||
operand = "in"
|
operand = "in"
|
||||||
|
|
||||||
conditions["status"] = (operand, ["Sold", "Scrapped", "Capitalized", "Decapitalized"])
|
conditions["status"] = (operand, ["Sold", "Scrapped", "Capitalized"])
|
||||||
|
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
@@ -272,9 +272,9 @@ def get_asset_depreciation_amount_map(filters, finance_book):
|
|||||||
query = query.where(asset.cost_center == filters.cost_center)
|
query = query.where(asset.cost_center == filters.cost_center)
|
||||||
if filters.status:
|
if filters.status:
|
||||||
if filters.status == "In Location":
|
if filters.status == "In Location":
|
||||||
query = query.where(asset.status.notin(["Sold", "Scrapped", "Capitalized", "Decapitalized"]))
|
query = query.where(asset.status.notin(["Sold", "Scrapped", "Capitalized"]))
|
||||||
else:
|
else:
|
||||||
query = query.where(asset.status.isin(["Sold", "Scrapped", "Capitalized", "Decapitalized"]))
|
query = query.where(asset.status.isin(["Sold", "Scrapped", "Capitalized"]))
|
||||||
if finance_book:
|
if finance_book:
|
||||||
query = query.where((gle.finance_book.isin([cstr(finance_book), ""])) | (gle.finance_book.isnull()))
|
query = query.where((gle.finance_book.isin([cstr(finance_book), ""])) | (gle.finance_book.isnull()))
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user