fix: option to pick serial / batch for asset repair

This commit is contained in:
Rohit Waghchaure
2025-06-27 14:50:49 +05:30
parent a571a5bf70
commit ae77c609ff
6 changed files with 96 additions and 10 deletions

View File

@@ -3,6 +3,8 @@
frappe.ui.form.on("Asset Repair", {
setup: function (frm) {
frm.ignore_doctypes_on_cancel_all = ["Serial and Batch Bundle"];
frm.fields_dict.cost_center.get_query = function (doc) {
return {
filters: {
@@ -177,4 +179,37 @@ frappe.ui.form.on("Asset Repair Consumed Item", {
var row = locals[cdt][cdn];
frappe.model.set_value(cdt, cdn, "total_value", row.consumed_quantity * row.valuation_rate);
},
pick_serial_and_batch(frm, cdt, cdn) {
let item = locals[cdt][cdn];
let doc = frm.doc;
frappe.db.get_value("Item", item.item_code, ["has_batch_no", "has_serial_no"]).then((r) => {
if (r.message && (r.message.has_batch_no || r.message.has_serial_no)) {
item.has_serial_no = r.message.has_serial_no;
item.has_batch_no = r.message.has_batch_no;
item.qty = item.consumed_quantity;
item.type_of_transaction = item.consumed_quantity > 0 ? "Outward" : "Inward";
item.title = item.has_serial_no ? __("Select Serial No") : __("Select Batch No");
if (item.has_serial_no && item.has_batch_no) {
item.title = __("Select Serial and Batch");
}
frm.doc.posting_date = frappe.datetime.get_today();
frm.doc.posting_time = frappe.datetime.now_time();
new erpnext.SerialBatchPackageSelector(frm, item, (r) => {
if (r) {
frappe.model.set_value(item.doctype, item.name, {
serial_and_batch_bundle: r.name,
use_serial_batch_fields: 0,
valuation_rate: r.avg_rate,
consumed_quantity: Math.abs(r.total_qty),
});
}
});
}
});
},
});

View File

@@ -156,6 +156,13 @@ class AssetRepair(AccountsController):
self.make_gl_entries()
def cancel_sabb(self):
for row in self.stock_items:
if sabb := row.serial_and_batch_bundle:
row.db_set("serial_and_batch_bundle", None)
doc = frappe.get_doc("Serial and Batch Bundle", sabb)
doc.cancel()
def on_cancel(self):
self.asset_doc = frappe.get_doc("Asset", self.asset)
if self.get("capitalize_repair_cost"):
@@ -167,6 +174,8 @@ class AssetRepair(AccountsController):
reschedule_depreciation(self.asset_doc, depreciation_note)
self.add_asset_activity()
self.cancel_sabb()
def after_delete(self):
frappe.get_doc("Asset", self.asset).set_status()

View File

@@ -11,6 +11,8 @@
"consumed_quantity",
"total_value",
"serial_no",
"column_break_xzfr",
"pick_serial_and_batch",
"serial_and_batch_bundle"
],
"fields": [
@@ -61,19 +63,29 @@
"label": "Warehouse",
"options": "Warehouse",
"reqd": 1
},
{
"fieldname": "pick_serial_and_batch",
"fieldtype": "Button",
"label": "Pick Serial / Batch"
},
{
"fieldname": "column_break_xzfr",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-06-13 12:01:47.147333",
"modified": "2025-06-27 14:52:56.311166",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Repair Consumed Item",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -8,7 +8,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
let me = this;
this.set_fields_onload_for_line_item();
this.frm.ignore_doctypes_on_cancel_all = ['Serial and Batch Bundle'];
this.frm.ignore_doctypes_on_cancel_all = ["Serial and Batch Bundle"];
frappe.flags.hide_serial_batch_dialog = true;
frappe.ui.form.on(this.frm.doctype + " Item", "rate", function(frm, cdt, cdn) {

View File

@@ -270,6 +270,7 @@ class StockEntry(StockController):
self.set_material_request_transfer_status("Completed")
def on_cancel(self):
self.delink_asset_repair_sabb()
self.validate_closed_subcontracting_order()
self.update_subcontract_order_supplied_items()
self.update_subcontracting_order_status()
@@ -380,6 +381,27 @@ class StockEntry(StockController):
):
frappe.delete_doc("Stock Entry", d.name)
def delink_asset_repair_sabb(self):
if not self.asset_repair:
return
for row in self.items:
if row.serial_and_batch_bundle:
voucher_detail_no = frappe.db.get_value(
"Asset Repair Consumed Item",
{"parent": self.asset_repair, "serial_and_batch_bundle": row.serial_and_batch_bundle},
"name",
)
doc = frappe.get_doc("Serial and Batch Bundle", row.serial_and_batch_bundle)
doc.db_set(
{
"voucher_type": "Asset Repair",
"voucher_no": self.asset_repair,
"voucher_detail_no": voucher_detail_no,
}
)
def set_transfer_qty(self):
self.validate_qty_is_not_zero()
for item in self.get("items"):

View File

@@ -285,7 +285,7 @@ class SerialBatchBundle:
frappe.throw(_(msg))
def delink_serial_and_batch_bundle(self):
if self.is_pos_transaction():
if self.is_pos_or_asset_repair_transaction():
return
update_values = {
@@ -338,21 +338,29 @@ class SerialBatchBundle:
self.cancel_serial_and_batch_bundle()
def cancel_serial_and_batch_bundle(self):
if self.is_pos_transaction():
if self.is_pos_or_asset_repair_transaction():
return
doc = frappe.get_cached_doc("Serial and Batch Bundle", self.sle.serial_and_batch_bundle)
if doc.docstatus == 1:
doc.cancel()
def is_pos_transaction(self):
def is_pos_or_asset_repair_transaction(self):
voucher_type = frappe.get_cached_value(
"Serial and Batch Bundle", self.sle.serial_and_batch_bundle, "voucher_type"
)
if (
self.sle.voucher_type == "Sales Invoice"
and self.sle.serial_and_batch_bundle
and frappe.get_cached_value(
"Serial and Batch Bundle", self.sle.serial_and_batch_bundle, "voucher_type"
)
== "POS Invoice"
and voucher_type == "POS Invoice"
):
return True
if (
self.sle.voucher_type == "Stock Entry"
and self.sle.serial_and_batch_bundle
and voucher_type == "Asset Repair"
):
return True