From 9a2710b9d7f82e17f83303b2b382f11912f8fae3 Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Mon, 29 Dec 2025 15:40:46 +0530 Subject: [PATCH 1/8] fix(asset): handle partial asset sales by splitting remaining quantity --- .../doctype/sales_invoice/sales_invoice.py | 38 ++++++++++ erpnext/assets/doctype/asset/asset.js | 69 ++++++++++++++----- erpnext/assets/doctype/asset/asset.py | 4 +- 3 files changed, 92 insertions(+), 19 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 18a86434ef9..13413ad2ab7 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -33,6 +33,7 @@ from erpnext.accounts.utils import ( get_account_currency, update_voucher_outstanding, ) +from erpnext.assets.doctype.asset.asset import split_asset from erpnext.assets.doctype.asset.depreciation import ( depreciate_asset, get_gl_entries_on_asset_disposal, @@ -468,6 +469,8 @@ class SalesInvoice(SellingController): self.update_stock_reservation_entries() self.update_stock_ledger() + self.split_asset_based_on_sale_qty() + self.process_asset_depreciation() # this sequence because outstanding may get -ve @@ -1358,6 +1361,41 @@ class SalesInvoice(SellingController): ): throw(_("Delivery Note {0} is not submitted").format(d.delivery_note)) + def split_asset_based_on_sale_qty(self): + asset_qty_map = self.get_asset_qty() + for asset, qty in asset_qty_map.items(): + remaining_qty = qty["actual_qty"] - qty["sale_qty"] + if remaining_qty > 0: + split_asset(asset, remaining_qty) + + def get_asset_qty(self): + asset_qty_map = {} + + assets = {row.asset for row in self.items if row.is_fixed_asset and row.asset} + if not assets or self.is_return: + return asset_qty_map + + asset_actual_qty = dict( + frappe.db.get_all( + "Asset", + {"name": ["in", list(assets)]}, + ["name", "asset_quantity"], + as_list=True, + ) + ) + for row in self.items: + if row.is_fixed_asset and row.asset: + actual_qty = asset_actual_qty.get(row.asset) + asset_qty_map.setdefault( + row.asset, + { + "sale_qty": flt(row.qty), + "actual_qty": flt(actual_qty), + }, + ) + + return asset_qty_map + def process_asset_depreciation(self): if (self.is_return and self.docstatus == 2) or (not self.is_return and self.docstatus == 1): self.depreciate_asset_on_sale() diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index e0b4593416a..ec167fafb3b 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -111,7 +111,7 @@ frappe.ui.form.on("Asset", { frm.add_custom_button( __("Sell Asset"), function () { - frm.trigger("make_sales_invoice"); + frm.trigger("sell_asset"); }, __("Manage") ); @@ -484,22 +484,6 @@ frappe.ui.form.on("Asset", { frm.trigger("toggle_reference_doc"); }, - make_sales_invoice: function (frm) { - frappe.call({ - args: { - asset: frm.doc.name, - item_code: frm.doc.item_code, - company: frm.doc.company, - serial_no: frm.doc.serial_no, - }, - method: "erpnext.assets.doctype.asset.asset.make_sales_invoice", - callback: function (r) { - var doclist = frappe.model.sync(r.message); - frappe.set_route("Form", doclist[0].doctype, doclist[0].name); - }, - }); - }, - create_asset_maintenance: function (frm) { frappe.call({ args: { @@ -548,6 +532,57 @@ frappe.ui.form.on("Asset", { }); }, + sell_asset: function (frm) { + const make_sales_invoice = (sell_qty) => { + frappe.call({ + method: "erpnext.assets.doctype.asset.asset.make_sales_invoice", + args: { + asset: frm.doc.name, + item_code: frm.doc.item_code, + company: frm.doc.company, + serial_no: frm.doc.serial_no, + sell_qty: sell_qty, + }, + callback: function (r) { + var doclist = frappe.model.sync(r.message); + frappe.set_route("Form", doclist[0].doctype, doclist[0].name); + }, + }); + }; + + const dialog = new frappe.ui.Dialog({ + title: __("Sell Asset"), + fields: [ + { + fieldname: "sell_qty", + fieldtype: "Int", + label: __("Sell Qty"), + reqd: 1, + }, + ], + }); + + dialog.set_primary_action(__("Sell"), function () { + const dialog_data = dialog.get_values(); + const sell_qty = cint(dialog_data.sell_qty); + + if (sell_qty < cint(frm.doc.asset_quantity)) { + frappe.confirm( + __( + "The sell quantity is less than the total asset quantity. The remaining quantity will be split into a new asset. This action cannot be undone.
Do you want to continue?" + ), + () => make_sales_invoice(sell_qty) + ); + } else { + make_sales_invoice(sell_qty); + } + + dialog.hide(); + }); + + dialog.show(); + }, + split_asset: function (frm) { const title = __("Split Asset"); diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 701be98a0d6..1e64f74b372 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -1083,7 +1083,7 @@ def get_asset_naming_series(): @frappe.whitelist() -def make_sales_invoice(asset, item_code, company, serial_no=None, posting_date=None): +def make_sales_invoice(asset, item_code, company, sell_qty, serial_no=None): asset_doc = frappe.get_doc("Asset", asset) si = frappe.new_doc("Sales Invoice") si.company = company @@ -1098,7 +1098,7 @@ def make_sales_invoice(asset, item_code, company, serial_no=None, posting_date=N "income_account": disposal_account, "serial_no": serial_no, "cost_center": depreciation_cost_center, - "qty": 1, + "qty": sell_qty, }, ) From a88fe2ecab9d35ab4a483c63f4df3f6aa8eefc2c Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Mon, 29 Dec 2025 15:53:31 +0530 Subject: [PATCH 2/8] fix: refactor older testcases --- erpnext/assets/doctype/asset/test_asset.py | 8 ++++++-- erpnext/assets/doctype/asset_repair/test_asset_repair.py | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index c54c39ab7c8..d86e1836108 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -330,7 +330,9 @@ class TestAsset(AssetSetup): post_depreciation_entries(date=add_months(purchase_date, 2)) - si = make_sales_invoice(asset=asset.name, item_code="Macbook Pro", company="_Test Company") + si = make_sales_invoice( + asset=asset.name, item_code="Macbook Pro", company="_Test Company", sell_qty=asset.asset_quantity + ) si.customer = "_Test Customer" si.due_date = date si.get("items")[0].rate = 25000 @@ -458,7 +460,9 @@ class TestAsset(AssetSetup): post_depreciation_entries(date="2021-01-01") - si = make_sales_invoice(asset=asset.name, item_code="Macbook Pro", company="_Test Company") + si = make_sales_invoice( + asset=asset.name, item_code="Macbook Pro", company="_Test Company", sell_qty=asset.asset_quantity + ) si.customer = "_Test Customer" si.due_date = nowdate() si.get("items")[0].rate = 25000 diff --git a/erpnext/assets/doctype/asset_repair/test_asset_repair.py b/erpnext/assets/doctype/asset_repair/test_asset_repair.py index 15ceb51648b..d085a4c6e4b 100644 --- a/erpnext/assets/doctype/asset_repair/test_asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/test_asset_repair.py @@ -51,7 +51,9 @@ class TestAssetRepair(IntegrationTestCase): submit=1, ) - si = make_sales_invoice(asset=asset.name, item_code="Macbook Pro", company="_Test Company") + si = make_sales_invoice( + asset=asset.name, item_code="Macbook Pro", company="_Test Company", sell_qty=asset.asset_quantity + ) si.customer = "_Test Customer" si.due_date = date si.get("items")[0].rate = 25000 From 9eeccb765d715d4858dbb75c53d0a01bffcd1f56 Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Mon, 29 Dec 2025 22:14:26 +0530 Subject: [PATCH 3/8] test: validate asset partial sales --- erpnext/assets/doctype/asset/test_asset.py | 53 ++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index d86e1836108..4e46a809b7f 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -1695,6 +1695,59 @@ class TestDepreciationBasics(AssetSetup): pr.submit() self.assertTrue(get_gl_entries("Purchase Receipt", pr.name)) + def test_partial_asset_sale_for_existing_asset(self): + date = nowdate() + purchase_date = add_months(get_first_day(date), -2) + depreciation_start_date = add_months(get_last_day(date), -2) + + # create an asset + asset = create_asset( + item_code="Macbook Pro", + is_existing_asset=1, + calculate_depreciation=1, + available_for_use_date=purchase_date, + purchase_date=purchase_date, + depreciation_start_date=depreciation_start_date, + net_purchase_amount=1000000, + purchase_amount=1000000, + asset_quantity=10, + total_number_of_depreciations=12, + frequency_of_depreciation=1, + submit=1, + ) + asset_depr_schedule_before_sale = get_asset_depr_schedule_doc(asset.name, "Active") + post_depreciation_entries(date) + asset.reload() + + # check asset values before sale + self.assertEqual(asset.asset_quantity, 10) + self.assertEqual(asset.net_purchase_amount, 1000000) + self.assertEqual(asset.status, "Partially Depreciated") + self.assertEqual( + asset_depr_schedule_before_sale.depreciation_schedule[0].get("depreciation_amount"), 83333.33 + ) + + # make a partial sales againt the asset + si = make_sales_invoice( + asset=asset.name, item_code="Macbook Pro", company="_Test Company", sell_qty=5 + ) + si.customer = "_Test Customer" + si.due_date = date + si.get("items")[0].rate = 25000 + si.insert() + si.submit() + + asset.reload() + asset_depr_schedule_after_sale = get_asset_depr_schedule_doc(asset.name, "Active") + + # check asset values after sales + self.assertEqual(asset.asset_quantity, 5) + self.assertEqual(asset.net_purchase_amount, 500000) + self.assertEqual(asset.status, "Sold") + self.assertEqual( + asset_depr_schedule_after_sale.depreciation_schedule[0].get("depreciation_amount"), 41666.66 + ) + def get_gl_entries(doctype, docname): gl_entry = frappe.qb.DocType("GL Entry") From e7e656779299f9e339ffdd440d3e964762c1a03d Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Tue, 30 Dec 2025 12:09:37 +0530 Subject: [PATCH 4/8] fix(asset): skip purchase document validation while splitting existing asset --- erpnext/assets/doctype/asset/asset.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 1e64f74b372..b929eda7d6a 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -482,6 +482,9 @@ class Asset(AccountsController): frappe.throw(_("Available-for-use Date should be after purchase date")) def validate_linked_purchase_documents(self): + if self.flags.is_split_asset: + return + for fieldname, doctype in [ ("purchase_receipt", "Purchase Receipt"), ("purchase_invoice", "Purchase Invoice"), @@ -1378,6 +1381,7 @@ def process_asset_split(existing_asset, split_qty, splitted_asset=None, is_new_a scaling_factor = flt(split_qty) / flt(existing_asset.asset_quantity) new_asset = frappe.copy_doc(existing_asset) if is_new_asset else splitted_asset asset_doc = new_asset if is_new_asset else existing_asset + asset_doc.flags.is_split_asset = True set_split_asset_values(asset_doc, scaling_factor, split_qty, existing_asset, is_new_asset) log_asset_activity(existing_asset, asset_doc, splitted_asset, is_new_asset) From 23b094f151ab606f52142ff2789ad80fb97b574c Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Tue, 30 Dec 2025 14:47:28 +0530 Subject: [PATCH 5/8] fix(asset): handle same asset being sold in multiple line items in sales invoice --- .../doctype/sales_invoice/sales_invoice.py | 24 ++++++++++---- erpnext/assets/doctype/asset/asset.js | 32 +++++++++++++------ 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 13413ad2ab7..9ff85096bd6 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -1364,6 +1364,13 @@ class SalesInvoice(SellingController): def split_asset_based_on_sale_qty(self): asset_qty_map = self.get_asset_qty() for asset, qty in asset_qty_map.items(): + if qty["actual_qty"] < qty["sale_qty"]: + frappe.throw( + _( + "Sell quantity cannot exceed the asset quantity. Asset {0} has only {1} item(s)." + ).format(asset, qty["actual_qty"]) + ) + remaining_qty = qty["actual_qty"] - qty["sale_qty"] if remaining_qty > 0: split_asset(asset, remaining_qty) @@ -1386,13 +1393,16 @@ class SalesInvoice(SellingController): for row in self.items: if row.is_fixed_asset and row.asset: actual_qty = asset_actual_qty.get(row.asset) - asset_qty_map.setdefault( - row.asset, - { - "sale_qty": flt(row.qty), - "actual_qty": flt(actual_qty), - }, - ) + if row.asset in asset_qty_map.keys(): + asset_qty_map[row.asset]["sale_qty"] += flt(row.qty) + else: + asset_qty_map.setdefault( + row.asset, + { + "sale_qty": flt(row.qty), + "actual_qty": flt(actual_qty), + }, + ) return asset_qty_map diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index ec167fafb3b..264690872f2 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -550,7 +550,7 @@ frappe.ui.form.on("Asset", { }); }; - const dialog = new frappe.ui.Dialog({ + let dialog = new frappe.ui.Dialog({ title: __("Sell Asset"), fields: [ { @@ -565,18 +565,30 @@ frappe.ui.form.on("Asset", { dialog.set_primary_action(__("Sell"), function () { const dialog_data = dialog.get_values(); const sell_qty = cint(dialog_data.sell_qty); + const asset_qty = cint(frm.doc.asset_quantity); - if (sell_qty < cint(frm.doc.asset_quantity)) { - frappe.confirm( - __( - "The sell quantity is less than the total asset quantity. The remaining quantity will be split into a new asset. This action cannot be undone.
Do you want to continue?" - ), - () => make_sales_invoice(sell_qty) - ); - } else { - make_sales_invoice(sell_qty); + if (sell_qty <= 0) { + frappe.throw(__("Sell quantity must be greater than zero")); } + if (sell_qty > asset_qty) { + frappe.throw(__("Sell quantity cannot exceed the asset quantity")); + } + + if (sell_qty < asset_qty) { + frappe.confirm( + __( + "The sell quantity is less than the total asset quantity. The remaining quantity will be split into a new asset. This action cannot be undone.

Do you want to continue?" + ), + () => { + make_sales_invoice(sell_qty); + dialog.hide(); + } + ); + return; + } + + make_sales_invoice(sell_qty); dialog.hide(); }); From 4adeaedfde19abe617e63c22a2bfd4dcc34b621b Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Tue, 30 Dec 2025 16:29:46 +0530 Subject: [PATCH 6/8] test: validate asset split for auto created asset from purchase voucher --- erpnext/assets/doctype/asset/test_asset.py | 176 ++++++++++++++------- 1 file changed, 123 insertions(+), 53 deletions(-) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 4e46a809b7f..f81b06129cb 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -702,6 +702,129 @@ class TestAsset(AssetSetup): frappe.db.set_value("Asset Category Account", name, "capital_work_in_progress_account", cwip_acc) frappe.db.get_value("Company", "_Test Company", "capital_work_in_progress_account", cwip_acc) + def test_partial_asset_sale(self): + date = nowdate() + purchase_date = add_months(get_first_day(date), -2) + depreciation_start_date = add_months(get_last_day(date), -2) + + # create an asset + asset = create_asset( + item_code="Macbook Pro", + is_existing_asset=1, + calculate_depreciation=1, + available_for_use_date=purchase_date, + purchase_date=purchase_date, + depreciation_start_date=depreciation_start_date, + net_purchase_amount=1000000.0, + purchase_amount=1000000.0, + asset_quantity=10, + total_number_of_depreciations=12, + frequency_of_depreciation=1, + submit=1, + ) + asset_depr_schedule_before_sale = get_asset_depr_schedule_doc(asset.name, "Active") + post_depreciation_entries(date) + asset.reload() + + # check asset values before sale + self.assertEqual(asset.asset_quantity, 10) + self.assertEqual(asset.net_purchase_amount, 1000000) + self.assertEqual(asset.status, "Partially Depreciated") + self.assertEqual( + asset_depr_schedule_before_sale.depreciation_schedule[0].get("depreciation_amount"), 83333.33 + ) + + # make a partial sales againt the asset + si = make_sales_invoice( + asset=asset.name, item_code="Macbook Pro", company="_Test Company", sell_qty=5 + ) + si.customer = "_Test Customer" + si.due_date = date + si.get("items")[0].rate = 25000 + si.insert() + si.submit() + + asset.reload() + asset_depr_schedule_after_sale = get_asset_depr_schedule_doc(asset.name, "Active") + + # check asset values after sales + self.assertEqual(asset.asset_quantity, 5) + self.assertEqual(asset.net_purchase_amount, 500000) + self.assertEqual(asset.status, "Sold") + self.assertEqual( + asset_depr_schedule_after_sale.depreciation_schedule[0].get("depreciation_amount"), 41666.66 + ) + + def test_asset_splitting_for_non_existing_asset(self): + date = nowdate() + purchase_date = add_months(get_first_day(date), -2) + depreciation_start_date = add_months(get_last_day(date), -2) + + asset_qty = 10 + asset_rate = 100000.0 + asset_item = "Macbook Pro" + asset_location = "Test Location" + + frappe.db.set_value("Item", asset_item, "is_grouped_asset", 1) + + # Inward asset via Purchase Receipt + pr = make_purchase_receipt( + item_code="Macbook Pro", + posting_date=purchase_date, + qty=asset_qty, + rate=asset_rate, + location=asset_location, + supplier="_Test Supplier", + ) + pr.submit() + + asset = frappe.db.get_value("Asset", {"purchase_receipt": pr.name, "docstatus": 0}, "name") + asset_doc = frappe.get_doc("Asset", asset) + asset_doc.calculate_depreciation = 1 + asset_doc.available_for_use_date = purchase_date + asset_doc.location = asset_location + asset_doc.append( + "finance_books", + { + "expected_value_after_useful_life": 0, + "depreciation_method": "Straight Line", + "total_number_of_depreciations": 12, + "frequency_of_depreciation": 1, + "depreciation_start_date": depreciation_start_date, + }, + ) + asset_doc.submit() + + # check asset values before splitting + asset_depr_schedule_before_splitting = get_asset_depr_schedule_doc(asset_doc.name, "Active") + self.assertEqual(asset_doc.asset_quantity, 10) + self.assertEqual(asset_doc.net_purchase_amount, 1000000) + self.assertEqual( + asset_depr_schedule_before_splitting.depreciation_schedule[0].get("depreciation_amount"), 83333.33 + ) + + # initate asset split + new_asset = split_asset(asset_doc.name, 5) + asset_doc.reload() + asset_depr_schedule_after_sale = get_asset_depr_schedule_doc(asset_doc.name, "Active") + new_asset_depr_schedule = get_asset_depr_schedule_doc(new_asset.name, "Active") + + # check asset values after splitting + self.assertEqual(asset_doc.asset_quantity, 5) + self.assertEqual(asset_doc.net_purchase_amount, 500000) + self.assertEqual( + asset_depr_schedule_after_sale.depreciation_schedule[0].get("depreciation_amount"), 41666.66 + ) + + # check new asset values after splitting + self.assertEqual(asset_doc.asset_quantity, 5) + self.assertEqual(asset_doc.net_purchase_amount, 500000) + self.assertEqual( + new_asset_depr_schedule.depreciation_schedule[0].get("depreciation_amount"), 41666.66 + ) + + frappe.db.set_value("Item", asset_item, "is_grouped_asset", 0) + class TestDepreciationMethods(AssetSetup): def test_schedule_for_straight_line_method(self): @@ -1695,59 +1818,6 @@ class TestDepreciationBasics(AssetSetup): pr.submit() self.assertTrue(get_gl_entries("Purchase Receipt", pr.name)) - def test_partial_asset_sale_for_existing_asset(self): - date = nowdate() - purchase_date = add_months(get_first_day(date), -2) - depreciation_start_date = add_months(get_last_day(date), -2) - - # create an asset - asset = create_asset( - item_code="Macbook Pro", - is_existing_asset=1, - calculate_depreciation=1, - available_for_use_date=purchase_date, - purchase_date=purchase_date, - depreciation_start_date=depreciation_start_date, - net_purchase_amount=1000000, - purchase_amount=1000000, - asset_quantity=10, - total_number_of_depreciations=12, - frequency_of_depreciation=1, - submit=1, - ) - asset_depr_schedule_before_sale = get_asset_depr_schedule_doc(asset.name, "Active") - post_depreciation_entries(date) - asset.reload() - - # check asset values before sale - self.assertEqual(asset.asset_quantity, 10) - self.assertEqual(asset.net_purchase_amount, 1000000) - self.assertEqual(asset.status, "Partially Depreciated") - self.assertEqual( - asset_depr_schedule_before_sale.depreciation_schedule[0].get("depreciation_amount"), 83333.33 - ) - - # make a partial sales againt the asset - si = make_sales_invoice( - asset=asset.name, item_code="Macbook Pro", company="_Test Company", sell_qty=5 - ) - si.customer = "_Test Customer" - si.due_date = date - si.get("items")[0].rate = 25000 - si.insert() - si.submit() - - asset.reload() - asset_depr_schedule_after_sale = get_asset_depr_schedule_doc(asset.name, "Active") - - # check asset values after sales - self.assertEqual(asset.asset_quantity, 5) - self.assertEqual(asset.net_purchase_amount, 500000) - self.assertEqual(asset.status, "Sold") - self.assertEqual( - asset_depr_schedule_after_sale.depreciation_schedule[0].get("depreciation_amount"), 41666.66 - ) - def get_gl_entries(doctype, docname): gl_entry = frappe.qb.DocType("GL Entry") From ca97f340923fb53cf1c078bc349cbdc170f5c8bc Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Mon, 12 Jan 2026 16:36:34 +0530 Subject: [PATCH 7/8] fix: use new_asset instead of asset_doc when checking values after splitting --- erpnext/assets/doctype/asset/test_asset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index f81b06129cb..46edf701c74 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -817,8 +817,8 @@ class TestAsset(AssetSetup): ) # check new asset values after splitting - self.assertEqual(asset_doc.asset_quantity, 5) - self.assertEqual(asset_doc.net_purchase_amount, 500000) + self.assertEqual(new_asset.asset_quantity, 5) + self.assertEqual(new_asset.net_purchase_amount, 500000) self.assertEqual( new_asset_depr_schedule.depreciation_schedule[0].get("depreciation_amount"), 41666.66 ) From eeb6d0e9bf1e6a2d202996bf80a5a37194fc9a18 Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Mon, 12 Jan 2026 16:45:04 +0530 Subject: [PATCH 8/8] fix: remove the redundant purchase receipt submit --- erpnext/assets/doctype/asset/test_asset.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 46edf701c74..600f6126f61 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -734,7 +734,7 @@ class TestAsset(AssetSetup): asset_depr_schedule_before_sale.depreciation_schedule[0].get("depreciation_amount"), 83333.33 ) - # make a partial sales againt the asset + # make a partial sales against the asset si = make_sales_invoice( asset=asset.name, item_code="Macbook Pro", company="_Test Company", sell_qty=5 ) @@ -776,7 +776,6 @@ class TestAsset(AssetSetup): location=asset_location, supplier="_Test Supplier", ) - pr.submit() asset = frappe.db.get_value("Asset", {"purchase_receipt": pr.name, "docstatus": 0}, "name") asset_doc = frappe.get_doc("Asset", asset)