diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index f0e59ee115..f414930d72 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -332,7 +332,7 @@ frappe.ui.form.on('Asset', { const fields = [ { fieldname: 'split_qty', - fieldtype:'Int', + fieldtype: 'Int', label: __('Split Qty'), reqd: 1 } diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index 72f692c533..9dba17121e 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -24,7 +24,6 @@ "asset_category", "location", "split_from", - "qty", "custodian", "department", "disposal_date", @@ -37,6 +36,7 @@ "available_for_use_date", "column_break_23", "gross_purchase_amount", + "asset_quantity", "purchase_date", "section_break_23", "calculate_depreciation", @@ -483,17 +483,17 @@ "fieldtype": "Section Break", "label": "Finance Books" }, - { - "fieldname": "qty", - "fieldtype": "Int", - "label": "Qty" - }, { "fieldname": "split_from", "fieldtype": "Link", "label": "Split From", "options": "Asset", "read_only": 1 + }, + { + "fieldname": "asset_quantity", + "fieldtype": "Int", + "label": "Asset Quantity" } ], "idx": 72, @@ -516,7 +516,7 @@ "link_fieldname": "asset" } ], - "modified": "2022-01-18 09:15:34.238601", + "modified": "2022-01-19 01:36:51.361485", "modified_by": "Administrator", "module": "Assets", "name": "Asset", diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 3d51af80da..01c1f71649 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -913,51 +913,57 @@ def split_asset(asset_name, split_qty): asset = frappe.get_doc("Asset", asset_name) split_qty = cint(split_qty) - if split_qty >= asset.qty: + if split_qty >= asset.asset_quantity: frappe.throw(_("Split qty cannot be grater than or equal to asset qty")) - remaining_qty = asset.qty - split_qty + remaining_qty = asset.asset_quantity - split_qty - # Update gross purchase amount - new_gross_purchase_amount = flt((asset.gross_purchase_amount * split_qty) / asset.qty) - remaining_gross_purchase_amount = flt((asset.gross_purchase_amount * split_qty) / asset.qty) - - new_asset = create_new_asset_after_split(asset, new_gross_purchase_amount, split_qty) - update_existing_asset(asset, remaining_gross_purchase_amount, remaining_qty) + new_asset = create_new_asset_after_split(asset, split_qty) + update_existing_asset(asset, remaining_qty) return new_asset -def update_existing_asset(asset, remaingin_gross_purchase_amount, remaining_qty): +def update_existing_asset(asset, remaining_qty): + remaining_gross_purchase_amount = flt((asset.gross_purchase_amount * remaining_qty) / asset.asset_quantity) + opening_accumulated_depreciation = flt((asset.opening_accumulated_depreciation * remaining_qty) / asset.asset_quantity) + frappe.db.set_value("Asset", asset.name, { - 'gross_purchase_amount': remaingin_gross_purchase_amount, - 'qty': remaining_qty + 'opening_accumulated_depreciation': opening_accumulated_depreciation, + 'gross_purchase_amount': remaining_gross_purchase_amount, + 'asset_quantity': remaining_qty }) for finance_book in asset.get('finance_books'): - value_after_depreciation = flt((finance_book.value_after_depreciation * remaining_qty)/asset.qty) + value_after_depreciation = flt((finance_book.value_after_depreciation * remaining_qty)/asset.asset_quantity) + expected_value_after_useful_life = flt((finance_book.expected_value_after_useful_life * remaining_qty)/asset.asset_quantity) frappe.db.set_value('Asset Finance Book', finance_book.name, 'value_after_depreciation', value_after_depreciation) + frappe.db.set_value('Asset Finance Book', finance_book.name, 'expected_value_after_useful_life', expected_value_after_useful_life) accumulated_depreciation = 0 for term in asset.get('schedules'): - depreciation_amount = flt((term.depreciation_amount * remaining_qty)/asset.qty) + depreciation_amount = flt((term.depreciation_amount * remaining_qty)/asset.asset_quantity) frappe.db.set_value('Depreciation Schedule', term.name, 'depreciation_amount', depreciation_amount) accumulated_depreciation += depreciation_amount - frappe.db.set_value('Depreciation Schedule', term.name, 'accumulated_depreciation_amount', depreciation_amount) + frappe.db.set_value('Depreciation Schedule', term.name, 'accumulated_depreciation_amount', accumulated_depreciation) -def create_new_asset_after_split(asset, new_gross_purchase_amount, split_qty): +def create_new_asset_after_split(asset, split_qty): new_asset = frappe.copy_doc(asset) + new_gross_purchase_amount = flt((asset.gross_purchase_amount * split_qty) / asset.asset_quantity) + opening_accumulated_depreciation = flt((asset.opening_accumulated_depreciation * split_qty) / asset.asset_quantity) new_asset.gross_purchase_amount = new_gross_purchase_amount - new_asset.qty = split_qty + new_asset.opening_accumulated_depreciation = opening_accumulated_depreciation + new_asset.asset_quantity = split_qty new_asset.split_from = asset.name accumulated_depreciation = 0 for finance_book in new_asset.get('finance_books'): - finance_book.value_after_depreciation = flt((finance_book.value_after_depreciation * split_qty)/asset.qty) + finance_book.value_after_depreciation = flt((finance_book.value_after_depreciation * split_qty)/asset.asset_quantity) + finance_book.expected_value_after_useful_life = flt((finance_book.expected_value_after_useful_life * split_qty)/asset.asset_quantity) for term in new_asset.get('schedules'): - depreciation_amount = flt((term.depreciation_amount * split_qty)/asset.qty) + depreciation_amount = flt((term.depreciation_amount * split_qty)/asset.asset_quantity) term.depreciation_amount = depreciation_amount accumulated_depreciation += depreciation_amount term.accumulated_depreciation_amount = accumulated_depreciation @@ -975,6 +981,7 @@ def create_new_asset_after_split(asset, new_gross_purchase_amount, split_qty): def add_reference_in_jv_on_split(entry_name, new_asset_name, old_asset_name, depreciation_amount): journal_entry = frappe.get_doc('Journal Entry', entry_name) entries_to_add = [] + idx = len(journal_entry.get('accounts')) + 1 for account in journal_entry.get('accounts'): if account.reference_name == old_asset_name: @@ -997,6 +1004,9 @@ def add_reference_in_jv_on_split(entry_name, new_asset_name, old_asset_name, dep entry.debit = depreciation_amount entry.debit_in_account_currency = entry.exchange_rate * depreciation_amount + entry.idx = idx + idx += 1 + journal_entry.append('accounts', entry) journal_entry.flags.ignore_validate_update_after_submit = True diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 283b2ea161..7fdcb0dd3b 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -28,9 +28,9 @@ class AssetSetup(unittest.TestCase): make_purchase_receipt(item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location") frappe.db.sql("delete from `tabTax Rule`") - # @classmethod - # def tearDownClass(cls): - # frappe.db.rollback() + @classmethod + def tearDownClass(cls): + frappe.db.rollback() class TestAsset(AssetSetup): def test_asset_category_is_fetched(self): @@ -225,18 +225,53 @@ class TestAsset(AssetSetup): def test_asset_splitting(self): asset = create_asset( calculate_depreciation = 1, - qty=10, + asset_quantity=10, available_for_use_date = '2020-01-01', purchase_date = '2020-01-01', expected_value_after_useful_life = 0, - total_number_of_depreciations = 5, + total_number_of_depreciations = 6, + number_of_depreciations_booked = 1, frequency_of_depreciation = 10, depreciation_start_date = '2021-01-01', + opening_accumulated_depreciation=20000, + gross_purchase_amount=120000, submit = 1 ) post_depreciation_entries(date="2021-01-01") - split_asset(asset.name, 5) + + self.assertEqual(asset.asset_quantity, 10) + self.assertEqual(asset.gross_purchase_amount, 120000) + self.assertEqual(asset.opening_accumulated_depreciation, 20000) + + new_asset = split_asset(asset.name, 2) + asset.load_from_db() + + self.assertEqual(new_asset.asset_quantity, 2) + self.assertEqual(new_asset.gross_purchase_amount, 24000) + self.assertEqual(new_asset.opening_accumulated_depreciation, 4000) + self.assertEqual(new_asset.split_from, asset.name) + self.assertEqual(new_asset.schedules[0].depreciation_amount, 4000) + self.assertEqual(new_asset.schedules[1].depreciation_amount, 4000) + + self.assertEqual(asset.asset_quantity, 8) + self.assertEqual(asset.gross_purchase_amount, 96000) + self.assertEqual(asset.opening_accumulated_depreciation, 16000) + self.assertEqual(asset.schedules[0].depreciation_amount, 16000) + self.assertEqual(asset.schedules[1].depreciation_amount, 16000) + + journal_entry = asset.schedules[0].journal_entry + + jv = frappe.get_doc('Journal Entry', journal_entry) + self.assertEqual(jv.accounts[0].credit_in_account_currency, 16000) + self.assertEqual(jv.accounts[1].debit_in_account_currency, 16000) + self.assertEqual(jv.accounts[2].credit_in_account_currency, 4000) + self.assertEqual(jv.accounts[3].debit_in_account_currency, 4000) + + self.assertEqual(jv.accounts[0].reference_name, asset.name) + self.assertEqual(jv.accounts[1].reference_name, asset.name) + self.assertEqual(jv.accounts[2].reference_name, new_asset.name) + self.assertEqual(jv.accounts[3].reference_name, new_asset.name) def test_expense_head(self): pr = make_purchase_receipt(item_code="Macbook Pro", @@ -1181,7 +1216,7 @@ def create_asset(**args): "location": args.location or "Test Location", "asset_owner": args.asset_owner or "Company", "is_existing_asset": args.is_existing_asset or 1, - "qty": args.get("qty") or 1 + "asset_quantity": args.get("asset_quantity") or 1 }) if asset.calculate_depreciation: