From 26b39ac7f4c1df651b6b7aff36a787d0a603959d Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 6 Apr 2023 01:36:18 +0530 Subject: [PATCH] fix: travis for asset capitalization and asset repair --- .../asset_capitalization.js | 1 + .../asset_capitalization.json | 2 +- .../asset_capitalization.py | 15 +++++--- .../test_asset_capitalization.py | 27 ++++++++++++-- .../asset_capitalization_stock_item.json | 24 ++++++++++--- .../doctype/asset_repair/asset_repair.py | 21 ++++++++++- .../doctype/asset_repair/test_asset_repair.py | 35 +++++++++++++++---- .../asset_repair_consumed_item.json | 16 +++++++-- .../serial_and_batch_bundle.json | 4 +-- .../serial_and_batch_bundle.py | 3 ++ erpnext/stock/serial_batch_bundle.py | 6 ++++ 11 files changed, 131 insertions(+), 23 deletions(-) diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js index 9c7f70b0e5..5a3768585a 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.js @@ -6,6 +6,7 @@ frappe.provide("erpnext.assets"); erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.stock.StockController { setup() { + this.frm.ignore_doctypes_on_cancel_all = ['Serial and Batch Bundle']; this.setup_posting_date_time_check(); } diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json index d1be5752d6..01b35f64ab 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.json @@ -334,7 +334,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2022-09-12 15:09:40.771332", + "modified": "2022-10-12 15:09:40.771332", "modified_by": "Administrator", "module": "Assets", "name": "Asset Capitalization", diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py index b5e780bcbe..6841c56b10 100644 --- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py @@ -65,6 +65,10 @@ class AssetCapitalization(StockController): self.calculate_totals() self.set_title() + def on_update(self): + if self.stock_items: + self.set_serial_and_batch_bundle(table_name="stock_items") + def before_submit(self): self.validate_source_mandatory() @@ -74,7 +78,12 @@ class AssetCapitalization(StockController): self.update_target_asset() def on_cancel(self): - self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Repost Item Valuation") + self.ignore_linked_doctypes = ( + "GL Entry", + "Stock Ledger Entry", + "Repost Item Valuation", + "Serial and Batch Bundle", + ) self.update_stock_ledger() self.make_gl_entries() self.update_target_asset() @@ -316,9 +325,7 @@ class AssetCapitalization(StockController): for d in self.stock_items: sle = self.get_sl_entries( d, - { - "actual_qty": -flt(d.stock_qty), - }, + {"actual_qty": -flt(d.stock_qty), "serial_and_batch_bundle": d.serial_and_batch_bundle}, ) sl_entries.append(sle) diff --git a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py index 4d519a60be..5345d0e7f2 100644 --- a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py +++ b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py @@ -16,6 +16,11 @@ from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_sched get_asset_depr_schedule_doc, ) from erpnext.stock.doctype.item.test_item import create_item +from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import ( + get_batch_from_bundle, + get_serial_nos_from_bundle, + make_serial_batch_bundle, +) class TestAssetCapitalization(unittest.TestCase): @@ -371,14 +376,32 @@ def create_asset_capitalization(**args): asset_capitalization.set_posting_time = 1 if flt(args.stock_rate): + bundle = None + if args.stock_batch_no or args.stock_serial_no: + bundle = make_serial_batch_bundle( + frappe._dict( + { + "item_code": args.stock_item, + "warehouse": source_warehouse, + "company": frappe.get_cached_value("Warehouse", source_warehouse, "company"), + "qty": (flt(args.stock_qty) or 1) * -1, + "voucher_type": "Asset Capitalization", + "type_of_transaction": "Outward", + "serial_nos": args.stock_serial_no, + "posting_date": asset_capitalization.posting_date, + "posting_time": asset_capitalization.posting_time, + "do_not_submit": True, + } + ) + ).name + asset_capitalization.append( "stock_items", { "item_code": args.stock_item or "Capitalization Source Stock Item", "warehouse": source_warehouse, "stock_qty": flt(args.stock_qty) or 1, - "batch_no": args.stock_batch_no, - "serial_no": args.stock_serial_no, + "serial_and_batch_bundle": bundle, }, ) diff --git a/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json b/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json index 14eb0f6ef2..26e1c3c270 100644 --- a/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json +++ b/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json @@ -17,8 +17,9 @@ "valuation_rate", "amount", "batch_and_serial_no_section", - "batch_no", + "serial_and_batch_bundle", "column_break_13", + "batch_no", "serial_no", "accounting_dimensions_section", "cost_center", @@ -41,7 +42,10 @@ "fieldname": "batch_no", "fieldtype": "Link", "label": "Batch No", - "options": "Batch" + "no_copy": 1, + "options": "Batch", + "print_hide": 1, + "read_only": 1 }, { "fieldname": "section_break_6", @@ -100,7 +104,10 @@ { "fieldname": "serial_no", "fieldtype": "Small Text", - "label": "Serial No" + "hidden": 1, + "label": "Serial No", + "print_hide": 1, + "read_only": 1 }, { "fieldname": "item_code", @@ -139,12 +146,20 @@ { "fieldname": "dimension_col_break", "fieldtype": "Column Break" + }, + { + "fieldname": "serial_and_batch_bundle", + "fieldtype": "Link", + "label": "Serial and Batch Bundle", + "no_copy": 1, + "options": "Serial and Batch Bundle", + "print_hide": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-08 15:56:20.230548", + "modified": "2023-04-06 01:10:17.947952", "modified_by": "Administrator", "module": "Assets", "name": "Asset Capitalization Stock Item", @@ -152,5 +167,6 @@ "permissions": [], "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index a913ee4630..f649e510f9 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -147,6 +147,8 @@ class AssetRepair(AccountsController): ) for stock_item in self.get("stock_items"): + self.validate_serial_no(stock_item) + stock_entry.append( "items", { @@ -154,7 +156,7 @@ class AssetRepair(AccountsController): "item_code": stock_item.item_code, "qty": stock_item.consumed_quantity, "basic_rate": stock_item.valuation_rate, - "serial_no": stock_item.serial_no, + "serial_no": stock_item.serial_and_batch_bundle, "cost_center": self.cost_center, "project": self.project, }, @@ -165,6 +167,23 @@ class AssetRepair(AccountsController): self.db_set("stock_entry", stock_entry.name) + def validate_serial_no(self, stock_item): + if not stock_item.serial_and_batch_bundle and frappe.get_cached_value( + "Item", stock_item.item_code, "has_serial_no" + ): + msg = f"Serial No Bundle is mandatory for Item {stock_item.item_code}" + frappe.throw(msg, title=_("Missing Serial No Bundle")) + + if stock_item.serial_and_batch_bundle: + values_to_update = { + "type_of_transaction": "Outward", + "voucher_type": "Stock Entry", + } + + frappe.db.set_value( + "Serial and Batch Bundle", stock_item.serial_and_batch_bundle, values_to_update + ) + def increase_stock_quantity(self): if self.stock_entry: stock_entry = frappe.get_doc("Stock Entry", self.stock_entry) diff --git a/erpnext/assets/doctype/asset_repair/test_asset_repair.py b/erpnext/assets/doctype/asset_repair/test_asset_repair.py index 90be568b3c..c537143dcf 100644 --- a/erpnext/assets/doctype/asset_repair/test_asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/test_asset_repair.py @@ -4,7 +4,7 @@ import unittest import frappe -from frappe.utils import flt, nowdate +from frappe.utils import flt, nowdate, nowtime, today from erpnext.assets.doctype.asset.asset import ( get_asset_account, @@ -19,6 +19,10 @@ from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_sched get_asset_depr_schedule_doc, ) from erpnext.stock.doctype.item.test_item import create_item +from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import ( + get_serial_nos_from_bundle, + make_serial_batch_bundle, +) class TestAssetRepair(unittest.TestCase): @@ -88,8 +92,8 @@ class TestAssetRepair(unittest.TestCase): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item stock_entry = make_serialized_item() - bundle_id = stock_entry.get("items")[0].serial_no - serial_nos = frappe.get_doc("Serial and Batch Bundle", bundle_id).get_serial_nos() + bundle_id = stock_entry.get("items")[0].serial_and_batch_bundle + serial_nos = get_serial_nos_from_bundle(bundle_id) serial_no = serial_nos[0] # should not raise any error @@ -97,7 +101,7 @@ class TestAssetRepair(unittest.TestCase): stock_consumption=1, item_code=stock_entry.get("items")[0].item_code, warehouse="_Test Warehouse - _TC", - serial_no=serial_no, + serial_no=[serial_no], submit=1, ) @@ -109,7 +113,7 @@ class TestAssetRepair(unittest.TestCase): ) asset_repair.repair_status = "Completed" - self.assertRaises(SerialNoRequiredError, asset_repair.submit) + self.assertRaises(frappe.ValidationError, asset_repair.submit) def test_increase_in_asset_value_due_to_stock_consumption(self): asset = create_asset(calculate_depreciation=1, submit=1) @@ -291,13 +295,32 @@ def create_asset_repair(**args): asset_repair.warehouse = args.warehouse or create_warehouse( "Test Warehouse", company=asset.company ) + + bundle = None + if args.serial_no: + bundle = make_serial_batch_bundle( + frappe._dict( + { + "item_code": args.item_code, + "warehouse": asset_repair.warehouse, + "company": frappe.get_cached_value("Warehouse", asset_repair.warehouse, "company"), + "qty": (flt(args.stock_qty) or 1) * -1, + "voucher_type": "Asset Repair", + "type_of_transaction": "Asset Repair", + "serial_nos": args.serial_no, + "posting_date": today(), + "posting_time": nowtime(), + } + ) + ).name + asset_repair.append( "stock_items", { "item_code": args.item_code or "_Test Stock Item", "valuation_rate": args.rate if args.get("rate") is not None else 100, "consumed_quantity": args.qty or 1, - "serial_no": args.serial_no, + "serial_and_batch_bundle": bundle, }, ) diff --git a/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.json b/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.json index 4685a09db6..6910c2eebf 100644 --- a/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.json +++ b/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.json @@ -9,7 +9,8 @@ "valuation_rate", "consumed_quantity", "total_value", - "serial_no" + "serial_no", + "serial_and_batch_bundle" ], "fields": [ { @@ -34,7 +35,9 @@ { "fieldname": "serial_no", "fieldtype": "Small Text", - "label": "Serial No" + "hidden": 1, + "label": "Serial No", + "print_hide": 1 }, { "fieldname": "item_code", @@ -42,12 +45,18 @@ "in_list_view": 1, "label": "Item", "options": "Item" + }, + { + "fieldname": "serial_and_batch_bundle", + "fieldtype": "Link", + "label": "Serial and Batch Bundle", + "options": "Serial and Batch Bundle" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2022-02-08 17:37:20.028290", + "modified": "2023-04-06 02:24:20.375870", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair Consumed Item", @@ -55,5 +64,6 @@ "permissions": [], "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json index 18d8a72e15..77ba13a0ef 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json @@ -185,7 +185,7 @@ "fieldname": "type_of_transaction", "fieldtype": "Select", "label": "Type of Transaction", - "options": "\nInward\nOutward\nMaintenance", + "options": "\nInward\nOutward\nMaintenance\nAsset Repair", "reqd": 1 }, { @@ -243,7 +243,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2023-04-03 16:22:30.767805", + "modified": "2023-04-06 02:35:38.404537", "modified_by": "Administrator", "module": "Stock", "name": "Serial and Batch Bundle", diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index 3139da89ab..0b7eda90d5 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -110,6 +110,9 @@ class SerialandBatchBundle(Document): frappe.throw(_(message), exception, title=_("Error")) def set_incoming_rate(self, row=None, save=False): + if self.type_of_transaction not in ["Inward", "Outward"]: + return + if self.type_of_transaction == "Outward": self.set_incoming_rate_for_outward_transaction(row, save) else: diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py index 53b3043dbf..0081ccf6eb 100644 --- a/erpnext/stock/serial_batch_bundle.py +++ b/erpnext/stock/serial_batch_bundle.py @@ -125,6 +125,12 @@ class SerialBatchBundle: if self.sle.voucher_type == "Stock Entry": child_doctype = "Stock Entry Detail" + if self.sle.voucher_type == "Asset Capitalization": + child_doctype = "Asset Capitalization Stock Item" + + if self.sle.voucher_type == "Asset Repair": + child_doctype = "Asset Repair Consumed Item" + return child_doctype def is_rejected_entry(self):