* feat: wip composite asset (cherry picked from commit 4907e7acd4ff549f34f6c9d0144af83db0ad9cc1) # Conflicts: # erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json # erpnext/assets/doctype/asset/asset.json # erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json * chore: resolving conflicts --------- Co-authored-by: anandbaburajan <anandbaburajan@gmail.com>
This commit is contained in:
parent
9be554a147
commit
f4f40cc776
@ -479,6 +479,12 @@ cur_frm.set_query("expense_account", "items", function(doc) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cur_frm.set_query("wip_composite_asset", "items", function() {
|
||||||
|
return {
|
||||||
|
filters: {'is_composite_asset': 1, 'docstatus': 0 }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
cur_frm.cscript.expense_account = function(doc, cdt, cdn){
|
cur_frm.cscript.expense_account = function(doc, cdt, cdn){
|
||||||
var d = locals[cdt][cdn];
|
var d = locals[cdt][cdn];
|
||||||
if(d.idx == 1 && d.expense_account){
|
if(d.idx == 1 && d.expense_account){
|
||||||
|
@ -77,6 +77,7 @@
|
|||||||
"manufacturer_part_no",
|
"manufacturer_part_no",
|
||||||
"accounting",
|
"accounting",
|
||||||
"expense_account",
|
"expense_account",
|
||||||
|
"wip_composite_asset",
|
||||||
"col_break5",
|
"col_break5",
|
||||||
"is_fixed_asset",
|
"is_fixed_asset",
|
||||||
"asset_location",
|
"asset_location",
|
||||||
@ -903,12 +904,18 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Serial and Batch Bundle",
|
"options": "Serial and Batch Bundle",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "wip_composite_asset",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "WIP Composite Asset",
|
||||||
|
"options": "Asset"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-07-26 12:54:53.178156",
|
"modified": "2023-10-03 21:01:01.824892",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Invoice Item",
|
"name": "Purchase Invoice Item",
|
||||||
|
@ -148,6 +148,15 @@ frappe.ui.form.on('Asset', {
|
|||||||
|
|
||||||
if (frm.doc.docstatus == 0) {
|
if (frm.doc.docstatus == 0) {
|
||||||
frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
|
frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
|
||||||
|
|
||||||
|
if (frm.doc.is_composite_asset && !frm.doc.capitalized_in) {
|
||||||
|
$('.primary-action').prop('hidden', true);
|
||||||
|
$('.form-message').text('Capitalize this asset to confirm');
|
||||||
|
|
||||||
|
frm.add_custom_button(__("Capitalize Asset"), function() {
|
||||||
|
frm.trigger("create_asset_capitalization");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -169,7 +178,7 @@ frappe.ui.form.on('Asset', {
|
|||||||
frm.set_df_property('purchase_invoice', 'read_only', 1);
|
frm.set_df_property('purchase_invoice', 'read_only', 1);
|
||||||
frm.set_df_property('purchase_receipt', 'read_only', 1);
|
frm.set_df_property('purchase_receipt', 'read_only', 1);
|
||||||
}
|
}
|
||||||
else if (frm.doc.is_existing_asset) {
|
else if (frm.doc.is_existing_asset || frm.doc.is_composite_asset) {
|
||||||
frm.toggle_reqd('purchase_receipt', 0);
|
frm.toggle_reqd('purchase_receipt', 0);
|
||||||
frm.toggle_reqd('purchase_invoice', 0);
|
frm.toggle_reqd('purchase_invoice', 0);
|
||||||
}
|
}
|
||||||
@ -353,7 +362,17 @@ frappe.ui.form.on('Asset', {
|
|||||||
|
|
||||||
is_existing_asset: function(frm) {
|
is_existing_asset: function(frm) {
|
||||||
frm.trigger("toggle_reference_doc");
|
frm.trigger("toggle_reference_doc");
|
||||||
// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
|
},
|
||||||
|
|
||||||
|
is_composite_asset: function(frm) {
|
||||||
|
if(frm.doc.is_composite_asset) {
|
||||||
|
frm.set_value('gross_purchase_amount', 0);
|
||||||
|
frm.set_df_property('gross_purchase_amount', 'read_only', 1);
|
||||||
|
} else {
|
||||||
|
frm.set_df_property('gross_purchase_amount', 'read_only', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
frm.trigger("toggle_reference_doc");
|
||||||
},
|
},
|
||||||
|
|
||||||
make_sales_invoice: function(frm) {
|
make_sales_invoice: function(frm) {
|
||||||
@ -403,6 +422,19 @@ frappe.ui.form.on('Asset', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
create_asset_capitalization: function(frm) {
|
||||||
|
frappe.call({
|
||||||
|
args: {
|
||||||
|
"asset": frm.doc.name,
|
||||||
|
},
|
||||||
|
method: "erpnext.assets.doctype.asset.asset.create_asset_capitalization",
|
||||||
|
callback: function(r) {
|
||||||
|
var doclist = frappe.model.sync(r.message);
|
||||||
|
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
split_asset: function(frm) {
|
split_asset: function(frm) {
|
||||||
const title = __('Split Asset');
|
const title = __('Split Asset');
|
||||||
|
|
||||||
@ -466,9 +498,11 @@ frappe.ui.form.on('Asset', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
gross_purchase_amount: function(frm) {
|
gross_purchase_amount: function(frm) {
|
||||||
frm.doc.finance_books.forEach(d => {
|
if (frm.doc.finance_books) {
|
||||||
frm.events.set_depreciation_rate(frm, d);
|
frm.doc.finance_books.forEach(d => {
|
||||||
})
|
frm.events.set_depreciation_rate(frm, d);
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
purchase_receipt: (frm) => {
|
purchase_receipt: (frm) => {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"asset_owner",
|
"asset_owner",
|
||||||
"asset_owner_company",
|
"asset_owner_company",
|
||||||
"is_existing_asset",
|
"is_existing_asset",
|
||||||
|
"is_composite_asset",
|
||||||
"supplier",
|
"supplier",
|
||||||
"customer",
|
"customer",
|
||||||
"image",
|
"image",
|
||||||
@ -72,7 +73,8 @@
|
|||||||
"purchase_receipt_amount",
|
"purchase_receipt_amount",
|
||||||
"default_finance_book",
|
"default_finance_book",
|
||||||
"depr_entry_posting_status",
|
"depr_entry_posting_status",
|
||||||
"amended_from"
|
"amended_from",
|
||||||
|
"capitalized_in"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -199,7 +201,7 @@
|
|||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Purchase Date",
|
"label": "Purchase Date",
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"read_only_depends_on": "eval:!doc.is_existing_asset",
|
"read_only_depends_on": "eval:!doc.is_existing_asset && !doc.is_composite_asset",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -237,10 +239,12 @@
|
|||||||
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
"depends_on": "eval:!doc.is_composite_asset",
|
||||||
"fieldname": "is_existing_asset",
|
"fieldname": "is_existing_asset",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Existing Asset"
|
"label": "Is Existing Asset"
|
||||||
@ -478,7 +482,7 @@
|
|||||||
"fieldname": "asset_quantity",
|
"fieldname": "asset_quantity",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Asset Quantity",
|
"label": "Asset Quantity",
|
||||||
"read_only_depends_on": "eval:!doc.is_existing_asset"
|
"read_only_depends_on": "eval:!doc.is_existing_asset && !doc.is_composite_asset"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "depr_entry_posting_status",
|
"fieldname": "depr_entry_posting_status",
|
||||||
@ -507,6 +511,21 @@
|
|||||||
"fieldname": "is_fully_depreciated",
|
"fieldname": "is_fully_depreciated",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Fully Depreciated"
|
"label": "Is Fully Depreciated"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "eval:!doc.is_existing_asset",
|
||||||
|
"fieldname": "is_composite_asset",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Is Composite Asset"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "capitalized_in",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Capitalized In",
|
||||||
|
"options": "Asset Capitalization",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 72,
|
"idx": 72,
|
||||||
@ -545,7 +564,7 @@
|
|||||||
"table_fieldname": "accounts"
|
"table_fieldname": "accounts"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2023-07-28 20:12:44.819616",
|
"modified": "2023-10-03 23:28:26.732269",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset",
|
"name": "Asset",
|
||||||
|
@ -228,7 +228,7 @@ class Asset(AccountsController):
|
|||||||
if not self.asset_category:
|
if not self.asset_category:
|
||||||
self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category")
|
self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category")
|
||||||
|
|
||||||
if not flt(self.gross_purchase_amount):
|
if not flt(self.gross_purchase_amount) and not self.is_composite_asset:
|
||||||
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
|
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
|
||||||
|
|
||||||
if is_cwip_accounting_enabled(self.asset_category):
|
if is_cwip_accounting_enabled(self.asset_category):
|
||||||
@ -768,6 +768,15 @@ def create_asset_repair(asset, asset_name):
|
|||||||
return asset_repair
|
return asset_repair
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def create_asset_capitalization(asset):
|
||||||
|
asset_capitalization = frappe.new_doc("Asset Capitalization")
|
||||||
|
asset_capitalization.update(
|
||||||
|
{"target_asset": asset, "capitalization_method": "Choose a WIP composite asset"}
|
||||||
|
)
|
||||||
|
return asset_capitalization
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_asset_value_adjustment(asset, asset_category, company):
|
def create_asset_value_adjustment(asset, asset_category, company):
|
||||||
asset_value_adjustment = frappe.new_doc("Asset Value Adjustment")
|
asset_value_adjustment = frappe.new_doc("Asset Value Adjustment")
|
||||||
|
@ -1744,6 +1744,7 @@ def create_asset(**args):
|
|||||||
"location": args.location or "Test Location",
|
"location": args.location or "Test Location",
|
||||||
"asset_owner": args.asset_owner or "Company",
|
"asset_owner": args.asset_owner or "Company",
|
||||||
"is_existing_asset": args.is_existing_asset or 1,
|
"is_existing_asset": args.is_existing_asset or 1,
|
||||||
|
"is_composite_asset": args.is_composite_asset or 0,
|
||||||
"asset_quantity": args.get("asset_quantity") or 1,
|
"asset_quantity": args.get("asset_quantity") or 1,
|
||||||
"depr_entry_posting_status": args.depr_entry_posting_status or "",
|
"depr_entry_posting_status": args.depr_entry_posting_status or "",
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,15 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
|
|||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.show_general_ledger();
|
this.show_general_ledger();
|
||||||
|
|
||||||
if ((this.frm.doc.stock_items && this.frm.doc.stock_items.length) || !this.frm.doc.target_is_fixed_asset) {
|
if ((this.frm.doc.stock_items && this.frm.doc.stock_items.length) || !this.frm.doc.target_is_fixed_asset) {
|
||||||
this.show_stock_ledger();
|
this.show_stock_ledger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.frm.doc.stock_items && !this.frm.doc.stock_items.length && this.frm.doc.target_asset && this.frm.doc.capitalization_method === "Choose a WIP composite asset") {
|
||||||
|
this.set_consumed_stock_items_tagged_to_wip_composite_asset(this.frm.doc.target_asset);
|
||||||
|
this.get_target_asset_details();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_queries() {
|
setup_queries() {
|
||||||
@ -35,18 +41,9 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
|
|||||||
});
|
});
|
||||||
|
|
||||||
me.frm.set_query("target_asset", function() {
|
me.frm.set_query("target_asset", function() {
|
||||||
var filters = {};
|
|
||||||
|
|
||||||
if (me.frm.doc.target_item_code) {
|
|
||||||
filters['item_code'] = me.frm.doc.target_item_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
filters['status'] = ["not in", ["Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"]];
|
|
||||||
filters['docstatus'] = 1;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filters: filters
|
filters: {'is_composite_asset': 1, 'docstatus': 0 }
|
||||||
};
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
me.frm.set_query("asset", "asset_items", function() {
|
me.frm.set_query("asset", "asset_items", function() {
|
||||||
@ -128,6 +125,39 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
|
|||||||
return this.get_target_item_details();
|
return this.get_target_item_details();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target_asset() {
|
||||||
|
if (this.frm.doc.target_asset && this.frm.doc.capitalization_method === "Choose a WIP composite asset") {
|
||||||
|
this.set_consumed_stock_items_tagged_to_wip_composite_asset(this.frm.doc.target_asset);
|
||||||
|
this.get_target_asset_details();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_consumed_stock_items_tagged_to_wip_composite_asset(asset) {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if (asset) {
|
||||||
|
return me.frm.call({
|
||||||
|
method: "erpnext.assets.doctype.asset_capitalization.asset_capitalization.get_items_tagged_to_wip_composite_asset",
|
||||||
|
args: {
|
||||||
|
asset: asset,
|
||||||
|
},
|
||||||
|
callback: function (r) {
|
||||||
|
if (!r.exc && r.message) {
|
||||||
|
me.frm.clear_table("stock_items");
|
||||||
|
|
||||||
|
for (let item of r.message) {
|
||||||
|
me.frm.add_child("stock_items", item);
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh_field("stock_items");
|
||||||
|
|
||||||
|
me.calculate_totals();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
item_code(doc, cdt, cdn) {
|
item_code(doc, cdt, cdn) {
|
||||||
var row = frappe.get_doc(cdt, cdn);
|
var row = frappe.get_doc(cdt, cdn);
|
||||||
if (cdt === "Asset Capitalization Stock Item") {
|
if (cdt === "Asset Capitalization Stock Item") {
|
||||||
@ -242,6 +272,26 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_target_asset_details() {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if (me.frm.doc.target_asset) {
|
||||||
|
return me.frm.call({
|
||||||
|
method: "erpnext.assets.doctype.asset_capitalization.asset_capitalization.get_target_asset_details",
|
||||||
|
child: me.frm.doc,
|
||||||
|
args: {
|
||||||
|
asset: me.frm.doc.target_asset,
|
||||||
|
company: me.frm.doc.company,
|
||||||
|
},
|
||||||
|
callback: function (r) {
|
||||||
|
if (!r.exc) {
|
||||||
|
me.frm.refresh_fields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get_consumed_stock_item_details(row) {
|
get_consumed_stock_item_details(row) {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
|
@ -8,24 +8,25 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"title",
|
"title",
|
||||||
|
"company",
|
||||||
"naming_series",
|
"naming_series",
|
||||||
"entry_type",
|
"entry_type",
|
||||||
"target_item_code",
|
|
||||||
"target_asset",
|
|
||||||
"target_item_name",
|
"target_item_name",
|
||||||
"target_is_fixed_asset",
|
"target_is_fixed_asset",
|
||||||
"target_has_batch_no",
|
"target_has_batch_no",
|
||||||
"target_has_serial_no",
|
"target_has_serial_no",
|
||||||
"column_break_9",
|
"column_break_9",
|
||||||
"target_asset_name",
|
"capitalization_method",
|
||||||
|
"target_item_code",
|
||||||
"target_asset_location",
|
"target_asset_location",
|
||||||
|
"target_asset",
|
||||||
|
"target_asset_name",
|
||||||
"target_warehouse",
|
"target_warehouse",
|
||||||
"target_qty",
|
"target_qty",
|
||||||
"target_stock_uom",
|
"target_stock_uom",
|
||||||
"target_batch_no",
|
"target_batch_no",
|
||||||
"target_serial_no",
|
"target_serial_no",
|
||||||
"column_break_5",
|
"column_break_5",
|
||||||
"company",
|
|
||||||
"finance_book",
|
"finance_book",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
"posting_time",
|
"posting_time",
|
||||||
@ -57,12 +58,13 @@
|
|||||||
"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')",
|
||||||
"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",
|
||||||
"options": "Item",
|
"mandatory_depends_on": "eval:(doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset') || doc.entry_type=='Decapitalization'",
|
||||||
"reqd": 1
|
"options": "Item"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.target_item_code && doc.target_item_name != doc.target_item_code",
|
"depends_on": "eval:doc.target_item_code && doc.target_item_name != doc.target_item_code",
|
||||||
@ -86,16 +88,18 @@
|
|||||||
"fieldtype": "Column Break"
|
"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'",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Asset",
|
"options": "Asset",
|
||||||
"read_only": 1
|
"read_only_depends_on": "eval:(doc.entry_type=='Decapitalization') || (doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset')"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.entry_type=='Capitalization'",
|
"depends_on": "eval:(doc.target_asset_name && !doc.__islocal) || (doc.target_asset && doc.entry_type=='Capitalization' && 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",
|
||||||
@ -186,12 +190,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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'"
|
"read_only_depends_on": "eval:doc.entry_type=='Capitalization'"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:doc.entry_type=='Decapitalization'",
|
||||||
"fetch_from": "target_item_code.stock_uom",
|
"fetch_from": "target_item_code.stock_uom",
|
||||||
"fieldname": "target_stock_uom",
|
"fieldname": "target_stock_uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@ -331,18 +337,26 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.entry_type=='Capitalization'",
|
"depends_on": "eval:doc.entry_type=='Capitalization' && 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'",
|
"mandatory_depends_on": "eval:doc.entry_type=='Capitalization' && doc.capitalization_method=='Create a new composite asset'",
|
||||||
"options": "Location"
|
"options": "Location"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.entry_type=='Capitalization'",
|
||||||
|
"fieldname": "capitalization_method",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Capitalization Method",
|
||||||
|
"mandatory_depends_on": "eval:doc.entry_type=='Capitalization'",
|
||||||
|
"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": "2023-06-22 14:17:07.995120",
|
"modified": "2023-10-03 22:55:59.461456",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Capitalization",
|
"name": "Asset Capitalization",
|
||||||
|
@ -53,6 +53,7 @@ class AssetCapitalization(StockController):
|
|||||||
self.validate_posting_time()
|
self.validate_posting_time()
|
||||||
self.set_missing_values(for_validate=True)
|
self.set_missing_values(for_validate=True)
|
||||||
self.validate_target_item()
|
self.validate_target_item()
|
||||||
|
self.validate_target_asset()
|
||||||
self.validate_consumed_stock_item()
|
self.validate_consumed_stock_item()
|
||||||
self.validate_consumed_asset_item()
|
self.validate_consumed_asset_item()
|
||||||
self.validate_service_item()
|
self.validate_service_item()
|
||||||
@ -67,12 +68,12 @@ class AssetCapitalization(StockController):
|
|||||||
|
|
||||||
def before_submit(self):
|
def before_submit(self):
|
||||||
self.validate_source_mandatory()
|
self.validate_source_mandatory()
|
||||||
if self.entry_type == "Capitalization":
|
self.create_target_asset()
|
||||||
self.create_target_asset()
|
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.update_stock_ledger()
|
self.update_stock_ledger()
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
|
self.update_target_asset()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.ignore_linked_doctypes = (
|
self.ignore_linked_doctypes = (
|
||||||
@ -94,6 +95,11 @@ class AssetCapitalization(StockController):
|
|||||||
if self.meta.has_field(k) and (not self.get(k) or k in force_fields):
|
if self.meta.has_field(k) and (not self.get(k) or k in force_fields):
|
||||||
self.set(k, v)
|
self.set(k, v)
|
||||||
|
|
||||||
|
target_asset_details = get_target_asset_details(self.target_asset, self.company)
|
||||||
|
for k, v in target_asset_details.items():
|
||||||
|
if self.meta.has_field(k) and (not self.get(k) or k in force_fields):
|
||||||
|
self.set(k, v)
|
||||||
|
|
||||||
for d in self.stock_items:
|
for d in self.stock_items:
|
||||||
args = self.as_dict()
|
args = self.as_dict()
|
||||||
args.update(d.as_dict())
|
args.update(d.as_dict())
|
||||||
@ -155,6 +161,33 @@ class AssetCapitalization(StockController):
|
|||||||
|
|
||||||
self.validate_item(target_item)
|
self.validate_item(target_item)
|
||||||
|
|
||||||
|
def validate_target_asset(self):
|
||||||
|
if self.target_asset:
|
||||||
|
target_asset = self.get_asset_for_validation(self.target_asset)
|
||||||
|
|
||||||
|
if not target_asset.is_composite_asset:
|
||||||
|
frappe.throw(_("Target Asset {0} needs to be composite asset").format(target_asset.name))
|
||||||
|
|
||||||
|
if target_asset.item_code != self.target_item_code:
|
||||||
|
frappe.throw(
|
||||||
|
_("Asset {0} does not belong to Item {1}").format(self.target_asset, self.target_item_code)
|
||||||
|
)
|
||||||
|
|
||||||
|
if target_asset.status in ("Scrapped", "Sold", "Capitalized", "Decapitalized"):
|
||||||
|
frappe.throw(
|
||||||
|
_("Target Asset {0} cannot be {1}").format(target_asset.name, target_asset.status)
|
||||||
|
)
|
||||||
|
|
||||||
|
if target_asset.docstatus == 1:
|
||||||
|
frappe.throw(_("Target Asset {0} cannot be submitted").format(target_asset.name))
|
||||||
|
elif target_asset.docstatus == 2:
|
||||||
|
frappe.throw(_("Target Asset {0} cannot be cancelled").format(target_asset.name))
|
||||||
|
|
||||||
|
if target_asset.company != self.company:
|
||||||
|
frappe.throw(
|
||||||
|
_("Target Asset {0} does not belong to company {1}").format(target_asset.name, self.company)
|
||||||
|
)
|
||||||
|
|
||||||
def validate_consumed_stock_item(self):
|
def validate_consumed_stock_item(self):
|
||||||
for d in self.stock_items:
|
for d in self.stock_items:
|
||||||
if d.item_code:
|
if d.item_code:
|
||||||
@ -179,7 +212,23 @@ class AssetCapitalization(StockController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
asset = self.get_asset_for_validation(d.asset)
|
asset = self.get_asset_for_validation(d.asset)
|
||||||
self.validate_asset(asset)
|
|
||||||
|
if asset.status in ("Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"):
|
||||||
|
frappe.throw(
|
||||||
|
_("Row #{0}: Consumed Asset {1} cannot be {2}").format(d.idx, asset.name, asset.status)
|
||||||
|
)
|
||||||
|
|
||||||
|
if asset.docstatus == 0:
|
||||||
|
frappe.throw(_("Row #{0}: Consumed Asset {1} cannot be Draft").format(d.idx, asset.name))
|
||||||
|
elif asset.docstatus == 2:
|
||||||
|
frappe.throw(_("Row #{0}: Consumed Asset {1} cannot be cancelled").format(d.idx, asset.name))
|
||||||
|
|
||||||
|
if asset.company != self.company:
|
||||||
|
frappe.throw(
|
||||||
|
_("Row #{0}: Consumed Asset {1} does not belong to company {2}").format(
|
||||||
|
d.idx, asset.name, self.company
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def validate_service_item(self):
|
def validate_service_item(self):
|
||||||
for d in self.service_items:
|
for d in self.service_items:
|
||||||
@ -214,21 +263,12 @@ class AssetCapitalization(StockController):
|
|||||||
|
|
||||||
def get_asset_for_validation(self, asset):
|
def get_asset_for_validation(self, asset):
|
||||||
return frappe.db.get_value(
|
return frappe.db.get_value(
|
||||||
"Asset", asset, ["name", "item_code", "company", "status", "docstatus"], as_dict=1
|
"Asset",
|
||||||
|
asset,
|
||||||
|
["name", "item_code", "company", "status", "docstatus", "is_composite_asset"],
|
||||||
|
as_dict=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
def validate_asset(self, asset):
|
|
||||||
if asset.status in ("Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"):
|
|
||||||
frappe.throw(_("Asset {0} is {1}").format(asset.name, asset.status))
|
|
||||||
|
|
||||||
if asset.docstatus == 0:
|
|
||||||
frappe.throw(_("Asset {0} is Draft").format(asset.name))
|
|
||||||
if asset.docstatus == 2:
|
|
||||||
frappe.throw(_("Asset {0} is cancelled").format(asset.name))
|
|
||||||
|
|
||||||
if asset.company != self.company:
|
|
||||||
frappe.throw(_("Asset {0} does not belong to company {1}").format(asset.name, self.company))
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def set_warehouse_details(self):
|
def set_warehouse_details(self):
|
||||||
for d in self.get("stock_items"):
|
for d in self.get("stock_items"):
|
||||||
@ -495,16 +535,25 @@ class AssetCapitalization(StockController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def create_target_asset(self):
|
def create_target_asset(self):
|
||||||
|
if (
|
||||||
|
self.entry_type != "Capitalization"
|
||||||
|
or self.capitalization_method != "Create a new composite asset"
|
||||||
|
):
|
||||||
|
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"))
|
||||||
|
|
||||||
asset_doc = frappe.new_doc("Asset")
|
asset_doc = frappe.new_doc("Asset")
|
||||||
asset_doc.company = self.company
|
asset_doc.company = self.company
|
||||||
asset_doc.item_code = self.target_item_code
|
asset_doc.item_code = self.target_item_code
|
||||||
asset_doc.is_existing_asset = 1
|
asset_doc.is_composite_asset = 1
|
||||||
asset_doc.location = self.target_asset_location
|
asset_doc.location = self.target_asset_location
|
||||||
asset_doc.available_for_use_date = self.posting_date
|
asset_doc.available_for_use_date = self.posting_date
|
||||||
asset_doc.purchase_date = self.posting_date
|
asset_doc.purchase_date = self.posting_date
|
||||||
asset_doc.gross_purchase_amount = total_target_asset_value
|
asset_doc.gross_purchase_amount = total_target_asset_value
|
||||||
asset_doc.purchase_receipt_amount = total_target_asset_value
|
asset_doc.purchase_receipt_amount = total_target_asset_value
|
||||||
|
asset_doc.purchase_receipt_amount = total_target_asset_value
|
||||||
|
asset_doc.capitalized_in = self.name
|
||||||
asset_doc.flags.ignore_validate = True
|
asset_doc.flags.ignore_validate = True
|
||||||
asset_doc.flags.asset_created_via_asset_capitalization = True
|
asset_doc.flags.asset_created_via_asset_capitalization = True
|
||||||
asset_doc.insert()
|
asset_doc.insert()
|
||||||
@ -528,6 +577,28 @@ class AssetCapitalization(StockController):
|
|||||||
).format(get_link_to_form("Asset", asset_doc.name))
|
).format(get_link_to_form("Asset", asset_doc.name))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def update_target_asset(self):
|
||||||
|
if (
|
||||||
|
self.entry_type != "Capitalization"
|
||||||
|
or self.capitalization_method != "Choose a WIP composite asset"
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
total_target_asset_value = flt(self.total_value, self.precision("total_value"))
|
||||||
|
|
||||||
|
asset_doc = frappe.get_doc("Asset", self.target_asset)
|
||||||
|
asset_doc.gross_purchase_amount = total_target_asset_value
|
||||||
|
asset_doc.purchase_receipt_amount = total_target_asset_value
|
||||||
|
asset_doc.capitalized_in = self.name
|
||||||
|
asset_doc.flags.ignore_validate = True
|
||||||
|
asset_doc.save()
|
||||||
|
|
||||||
|
frappe.msgprint(
|
||||||
|
_(
|
||||||
|
"Asset {0} has been updated. Please set the depreciation details if any and submit it."
|
||||||
|
).format(get_link_to_form("Asset", asset_doc.name))
|
||||||
|
)
|
||||||
|
|
||||||
def restore_consumed_asset_items(self):
|
def restore_consumed_asset_items(self):
|
||||||
for item in self.asset_items:
|
for item in self.asset_items:
|
||||||
asset = frappe.get_doc("Asset", item.asset)
|
asset = frappe.get_doc("Asset", item.asset)
|
||||||
@ -612,6 +683,33 @@ def get_target_item_details(item_code=None, company=None):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_target_asset_details(asset=None, company=None):
|
||||||
|
out = frappe._dict()
|
||||||
|
|
||||||
|
# Get Asset Details
|
||||||
|
asset_details = frappe._dict()
|
||||||
|
if asset:
|
||||||
|
asset_details = frappe.db.get_value("Asset", asset, ["asset_name", "item_code"], as_dict=1)
|
||||||
|
if not asset_details:
|
||||||
|
frappe.throw(_("Asset {0} does not exist").format(asset))
|
||||||
|
|
||||||
|
# Re-set item code from Asset
|
||||||
|
out.target_item_code = asset_details.item_code
|
||||||
|
|
||||||
|
# Set Asset Details
|
||||||
|
out.asset_name = asset_details.asset_name
|
||||||
|
|
||||||
|
if asset_details.item_code:
|
||||||
|
out.target_fixed_asset_account = get_asset_category_account(
|
||||||
|
"fixed_asset_account", item=asset_details.item_code, company=company
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
out.target_fixed_asset_account = None
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_consumed_stock_item_details(args):
|
def get_consumed_stock_item_details(args):
|
||||||
if isinstance(args, str):
|
if isinstance(args, str):
|
||||||
@ -760,3 +858,30 @@ def get_service_item_details(args):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_items_tagged_to_wip_composite_asset(asset):
|
||||||
|
fields = [
|
||||||
|
"item_code",
|
||||||
|
"item_name",
|
||||||
|
"batch_no",
|
||||||
|
"serial_no",
|
||||||
|
"stock_qty",
|
||||||
|
"stock_uom",
|
||||||
|
"warehouse",
|
||||||
|
"cost_center",
|
||||||
|
"qty",
|
||||||
|
"valuation_rate",
|
||||||
|
"amount",
|
||||||
|
]
|
||||||
|
|
||||||
|
pi_items = frappe.get_all(
|
||||||
|
"Purchase Invoice Item", filters={"wip_composite_asset": asset}, fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
|
pr_items = frappe.get_all(
|
||||||
|
"Purchase Receipt Item", filters={"wip_composite_asset": asset}, fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
|
return pi_items + pr_items
|
||||||
|
@ -58,6 +58,7 @@ class TestAssetCapitalization(unittest.TestCase):
|
|||||||
# Create and submit Asset Captitalization
|
# Create and submit Asset Captitalization
|
||||||
asset_capitalization = create_asset_capitalization(
|
asset_capitalization = create_asset_capitalization(
|
||||||
entry_type="Capitalization",
|
entry_type="Capitalization",
|
||||||
|
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",
|
||||||
stock_qty=stock_qty,
|
stock_qty=stock_qty,
|
||||||
@ -147,6 +148,7 @@ class TestAssetCapitalization(unittest.TestCase):
|
|||||||
# Create and submit Asset Captitalization
|
# Create and submit Asset Captitalization
|
||||||
asset_capitalization = create_asset_capitalization(
|
asset_capitalization = create_asset_capitalization(
|
||||||
entry_type="Capitalization",
|
entry_type="Capitalization",
|
||||||
|
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",
|
||||||
stock_qty=stock_qty,
|
stock_qty=stock_qty,
|
||||||
@ -211,6 +213,77 @@ class TestAssetCapitalization(unittest.TestCase):
|
|||||||
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_capitalization_with_wip_composite_asset(self):
|
||||||
|
company = "_Test Company with perpetual inventory"
|
||||||
|
set_depreciation_settings_in_company(company=company)
|
||||||
|
|
||||||
|
stock_rate = 1000
|
||||||
|
stock_qty = 2
|
||||||
|
stock_amount = 2000
|
||||||
|
|
||||||
|
total_amount = 2000
|
||||||
|
|
||||||
|
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,
|
||||||
|
target_asset_location="Test Location",
|
||||||
|
stock_qty=stock_qty,
|
||||||
|
stock_rate=stock_rate,
|
||||||
|
service_expense_account="Expenses Included In Asset Valuation - TCP1",
|
||||||
|
company=company,
|
||||||
|
submit=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 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.target_qty, 1)
|
||||||
|
|
||||||
|
self.assertEqual(asset_capitalization.stock_items[0].valuation_rate, stock_rate)
|
||||||
|
self.assertEqual(asset_capitalization.stock_items[0].amount, stock_amount)
|
||||||
|
self.assertEqual(asset_capitalization.stock_items_total, stock_amount)
|
||||||
|
|
||||||
|
self.assertEqual(asset_capitalization.total_value, total_amount)
|
||||||
|
self.assertEqual(asset_capitalization.target_incoming_rate, total_amount)
|
||||||
|
|
||||||
|
# Test Target Asset values
|
||||||
|
target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset)
|
||||||
|
self.assertEqual(target_asset.gross_purchase_amount, total_amount)
|
||||||
|
self.assertEqual(target_asset.purchase_receipt_amount, total_amount)
|
||||||
|
|
||||||
|
# Test General Ledger Entries
|
||||||
|
expected_gle = {
|
||||||
|
"_Test Fixed Asset - TCP1": 2000,
|
||||||
|
"_Test Warehouse - TCP1": -2000,
|
||||||
|
}
|
||||||
|
actual_gle = get_actual_gle_dict(asset_capitalization.name)
|
||||||
|
|
||||||
|
self.assertEqual(actual_gle, expected_gle)
|
||||||
|
|
||||||
|
# Test Stock Ledger Entries
|
||||||
|
expected_sle = {
|
||||||
|
("Capitalization Source Stock Item", "_Test Warehouse - TCP1"): {
|
||||||
|
"actual_qty": -stock_qty,
|
||||||
|
"stock_value_difference": -stock_amount,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
actual_sle = get_actual_sle_dict(asset_capitalization.name)
|
||||||
|
self.assertEqual(actual_sle, expected_sle)
|
||||||
|
|
||||||
|
# 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 test_decapitalization_with_depreciation(self):
|
def test_decapitalization_with_depreciation(self):
|
||||||
# Variables
|
# Variables
|
||||||
purchase_date = "2020-01-01"
|
purchase_date = "2020-01-01"
|
||||||
@ -347,6 +420,7 @@ def create_asset_capitalization(**args):
|
|||||||
asset_capitalization.update(
|
asset_capitalization.update(
|
||||||
{
|
{
|
||||||
"entry_type": args.entry_type or "Capitalization",
|
"entry_type": args.entry_type or "Capitalization",
|
||||||
|
"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"),
|
||||||
"posting_time": args.posting_time or now.strftime("%H:%M:%S.%f"),
|
"posting_time": args.posting_time or now.strftime("%H:%M:%S.%f"),
|
||||||
|
@ -37,6 +37,12 @@ frappe.ui.form.on("Purchase Receipt", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query("wip_composite_asset", "items", function() {
|
||||||
|
return {
|
||||||
|
filters: {'is_composite_asset': 1, 'docstatus': 0 }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
frm.set_query("taxes_and_charges", function() {
|
frm.set_query("taxes_and_charges", function() {
|
||||||
return {
|
return {
|
||||||
filters: {'company': frm.doc.company }
|
filters: {'company': frm.doc.company }
|
||||||
|
@ -117,6 +117,7 @@
|
|||||||
"accounting_details_section",
|
"accounting_details_section",
|
||||||
"expense_account",
|
"expense_account",
|
||||||
"item_tax_rate",
|
"item_tax_rate",
|
||||||
|
"wip_composite_asset",
|
||||||
"column_break_102",
|
"column_break_102",
|
||||||
"provisional_expense_account",
|
"provisional_expense_account",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
@ -1056,12 +1057,18 @@
|
|||||||
"fieldname": "add_serial_batch_bundle",
|
"fieldname": "add_serial_batch_bundle",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
"label": "Add Serial / Batch No"
|
"label": "Add Serial / Batch No"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "wip_composite_asset",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "WIP Composite Asset",
|
||||||
|
"options": "Asset"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-08-11 16:16:16.504549",
|
"modified": "2023-10-03 21:11:50.547261",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Purchase Receipt Item",
|
"name": "Purchase Receipt Item",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user