fix: serial no status (#38391)
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 137c352..9465574 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -1247,6 +1247,25 @@
dn.reload()
self.assertFalse(dn.items[0].target_warehouse)
+ def test_serial_no_status(self):
+ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
+
+ item = make_item(
+ "Test Serial Item For Status",
+ {"has_serial_no": 1, "is_stock_item": 1, "serial_no_series": "TESTSERIAL.#####"},
+ )
+
+ item_code = item.name
+ pi = make_purchase_receipt(qty=1, item_code=item.name)
+ pi.reload()
+ serial_no = get_serial_nos_from_bundle(pi.items[0].serial_and_batch_bundle)
+
+ self.assertEqual(frappe.db.get_value("Serial No", serial_no, "status"), "Active")
+
+ dn = create_delivery_note(qty=1, item_code=item_code, serial_no=serial_no)
+ dn.reload()
+ self.assertEqual(frappe.db.get_value("Serial No", serial_no, "status"), "Delivered")
+
def create_delivery_note(**args):
dn = frappe.new_doc("Delivery Note")
diff --git a/erpnext/stock/doctype/serial_no/serial_no.js b/erpnext/stock/doctype/serial_no/serial_no.js
index 9d5555e..1cb9fd1 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.js
+++ b/erpnext/stock/doctype/serial_no/serial_no.js
@@ -18,3 +18,22 @@
frappe.ui.form.on("Serial No", "refresh", function(frm) {
frm.toggle_enable("item_code", frm.doc.__islocal);
});
+
+
+frappe.ui.form.on("Serial No", {
+ refresh(frm) {
+ frm.trigger("view_ledgers")
+ },
+
+ view_ledgers(frm) {
+ frm.add_custom_button(__("View Ledgers"), () => {
+ frappe.route_options = {
+ "item_code": frm.doc.item_code,
+ "serial_no": frm.doc.name,
+ "posting_date": frappe.datetime.now_date(),
+ "posting_time": frappe.datetime.now_time()
+ };
+ frappe.set_route("query-report", "Serial No Ledger");
+ }).addClass('btn-primary');
+ }
+})
\ No newline at end of file
diff --git a/erpnext/stock/doctype/serial_no/serial_no.json b/erpnext/stock/doctype/serial_no/serial_no.json
index ed1b0af..b4ece00 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.json
+++ b/erpnext/stock/doctype/serial_no/serial_no.json
@@ -269,7 +269,7 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Status",
- "options": "\nActive\nInactive\nExpired",
+ "options": "\nActive\nInactive\nDelivered\nExpired",
"read_only": 1
},
{
@@ -280,7 +280,7 @@
"icon": "fa fa-barcode",
"idx": 1,
"links": [],
- "modified": "2023-04-16 15:58:46.139887",
+ "modified": "2023-11-28 15:37:59.489945",
"modified_by": "Administrator",
"module": "Stock",
"name": "Serial No",
diff --git a/erpnext/stock/report/serial_no_ledger/serial_no_ledger.py b/erpnext/stock/report/serial_no_ledger/serial_no_ledger.py
index 7212b92..ae12fbb 100644
--- a/erpnext/stock/report/serial_no_ledger/serial_no_ledger.py
+++ b/erpnext/stock/report/serial_no_ledger/serial_no_ledger.py
@@ -36,21 +36,27 @@
"fieldtype": "Link",
"fieldname": "company",
"options": "Company",
- "width": 150,
+ "width": 120,
},
{
"label": _("Warehouse"),
"fieldtype": "Link",
"fieldname": "warehouse",
"options": "Warehouse",
- "width": 150,
+ "width": 120,
+ },
+ {
+ "label": _("Status"),
+ "fieldtype": "Data",
+ "fieldname": "status",
+ "width": 120,
},
{
"label": _("Serial No"),
"fieldtype": "Link",
"fieldname": "serial_no",
"options": "Serial No",
- "width": 150,
+ "width": 130,
},
{
"label": _("Valuation Rate"),
@@ -58,6 +64,12 @@
"fieldname": "valuation_rate",
"width": 150,
},
+ {
+ "label": _("Qty"),
+ "fieldtype": "Float",
+ "fieldname": "qty",
+ "width": 150,
+ },
]
return columns
@@ -83,12 +95,16 @@
"posting_time": row.posting_time,
"voucher_type": row.voucher_type,
"voucher_no": row.voucher_no,
+ "status": "Active" if row.actual_qty > 0 else "Delivered",
"company": row.company,
"warehouse": row.warehouse,
+ "qty": 1 if row.actual_qty > 0 else -1,
}
)
- serial_nos = bundle_wise_serial_nos.get(row.serial_and_batch_bundle, [])
+ serial_nos = [{"serial_no": row.serial_no, "valuation_rate": row.valuation_rate}]
+ if row.serial_and_batch_bundle:
+ serial_nos = bundle_wise_serial_nos.get(row.serial_and_batch_bundle, [])
for index, bundle_data in enumerate(serial_nos):
if index == 0:
diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py
index da98455..de28be1 100644
--- a/erpnext/stock/serial_batch_bundle.py
+++ b/erpnext/stock/serial_batch_bundle.py
@@ -255,11 +255,15 @@
if not serial_nos:
return
+ status = "Inactive"
+ if self.sle.actual_qty < 0:
+ status = "Delivered"
+
sn_table = frappe.qb.DocType("Serial No")
(
frappe.qb.update(sn_table)
.set(sn_table.warehouse, warehouse)
- .set(sn_table.status, "Active" if warehouse else "Inactive")
+ .set(sn_table.status, "Active" if warehouse else status)
.where(sn_table.name.isin(serial_nos))
).run()