on item, warehouse and batch triggers, fetch serial nos based on batch
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 1551b1d..3da28a8 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -296,7 +296,6 @@
var me = this;
var item = frappe.get_doc(cdt, cdn);
var update_stock = 0, show_batch_dialog = 0;
-
if(['Sales Invoice'].includes(this.frm.doc.doctype)) {
update_stock = cint(me.frm.doc.update_stock);
show_batch_dialog = update_stock;
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index aa5b3ba..d6f4677 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -186,25 +186,32 @@
warehouse: function(doc, cdt, cdn) {
var me = this;
var item = frappe.get_doc(cdt, cdn);
-
- if(item.item_code && item.warehouse) {
- return this.frm.call({
- method: "erpnext.stock.get_item_details.get_bin_details_and_serial_nos",
- child: item,
- args: {
- item_code: item.item_code,
- warehouse: item.warehouse,
- stock_qty: item.stock_qty,
- serial_no: item.serial_no || ""
- },
- callback:function(r){
- if (in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
- me.set_batch_number(cdt, cdn);
- me.batch_no(doc, cdt, cdn);
- }
- }
- });
+ if (item.serial_no && !item.batch_no) {
+ item.serial_no = null;
}
+ var has_batch_no;
+ frappe.db.get_value('Item', {'item_code': item.item_code}, 'has_batch_no', (r) => {
+ has_batch_no = r && r.has_batch_no;
+ if(item.item_code && item.warehouse) {
+ return this.frm.call({
+ method: "erpnext.stock.get_item_details.get_bin_details_and_serial_nos",
+ child: item,
+ args: {
+ item_code: item.item_code,
+ warehouse: item.warehouse,
+ has_batch_no: has_batch_no,
+ stock_qty: item.stock_qty,
+ serial_no: item.serial_no || "",
+ },
+ callback:function(r){
+ if (in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
+ me.set_batch_number(cdt, cdn);
+ me.batch_no(doc, cdt, cdn);
+ }
+ }
+ });
+ }
+ })
},
toggle_editable_price_list_rate: function() {
@@ -245,19 +252,25 @@
batch_no: function(doc, cdt, cdn) {
var me = this;
var item = frappe.get_doc(cdt, cdn);
-
- if(item.warehouse && item.item_code && item.batch_no) {
- return this.frm.call({
- method: "erpnext.stock.get_item_details.get_batch_qty",
- child: item,
- args: {
- "batch_no": item.batch_no,
- "warehouse": item.warehouse,
- "item_code": item.item_code
- },
- "fieldname": "actual_batch_qty"
- });
- }
+ item.serial_no = null;
+ var has_serial_no;
+ frappe.db.get_value('Item', {'item_code': item.item_code}, 'has_serial_no', (r) => {
+ has_serial_no = r && r.has_serial_no;
+ if(item.warehouse && item.item_code && item.batch_no) {
+ return this.frm.call({
+ method: "erpnext.stock.get_item_details.get_batch_qty_and_serial_no",
+ child: item,
+ args: {
+ "batch_no": item.batch_no,
+ "stock_qty": item.stock_qty,
+ "warehouse": item.warehouse,
+ "item_code": item.item_code,
+ "has_serial_no": has_serial_no
+ },
+ "fieldname": "actual_batch_qty"
+ });
+ }
+ })
},
set_dynamic_labels: function() {
@@ -348,7 +361,7 @@
},
qty: function(doc, cdt, cdn) {
- this._super(doc, cdt, cdn);
+ this._super(doc, cdt, cdn);
this.set_batch_number(cdt, cdn);
},
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
index 5487193..ebf7ea1 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
@@ -40,6 +40,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -73,6 +74,7 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -106,6 +108,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -135,6 +138,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -164,6 +168,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -194,6 +199,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -226,6 +232,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "300px"
},
@@ -256,6 +263,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -286,6 +294,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -317,6 +326,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -346,6 +356,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -378,6 +389,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
@@ -412,6 +424,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "50px"
},
@@ -441,6 +454,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -472,6 +486,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -502,6 +517,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -532,6 +548,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -561,6 +578,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -594,6 +612,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
@@ -628,6 +647,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
@@ -659,6 +679,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -691,6 +712,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -722,6 +744,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -754,6 +777,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -783,6 +807,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -816,6 +841,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
@@ -849,6 +875,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -877,6 +904,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -910,6 +938,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -944,6 +973,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
@@ -973,6 +1003,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1006,6 +1037,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -1040,6 +1072,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
@@ -1071,6 +1104,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1100,6 +1134,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1131,6 +1166,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1162,6 +1198,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1191,6 +1228,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1222,6 +1260,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1253,6 +1292,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1283,6 +1323,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1313,6 +1354,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1343,6 +1385,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1372,6 +1415,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1403,6 +1447,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1432,6 +1477,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1465,6 +1511,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
@@ -1499,6 +1546,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1531,6 +1579,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1560,37 +1609,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "serial_no",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Serial No",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "serial_no",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1623,6 +1642,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1655,6 +1675,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -1688,6 +1709,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -1697,6 +1719,38 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "serial_no",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Serial No",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "serial_no",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"description": "",
"fieldname": "item_group",
"fieldtype": "Link",
@@ -1722,6 +1776,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1755,6 +1810,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -1787,6 +1843,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1815,6 +1872,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1845,6 +1903,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "120px"
},
@@ -1877,6 +1936,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "120px"
},
@@ -1908,6 +1968,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1938,6 +1999,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1968,6 +2030,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -2000,6 +2063,7 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -2031,6 +2095,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -2063,6 +2128,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -2095,6 +2161,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -2126,6 +2193,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -2139,7 +2207,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-11-30 14:07:12.217563",
+ "modified": "2018-04-11 14:05:39.905947",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note Item",
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 7e456dd..e361711 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -81,14 +81,14 @@
(args.get("doctype") == "Sales Invoice" and args.get('update_stock'))) \
and out.warehouse and out.stock_qty > 0:
- if out.has_serial_no:
- out.serial_no = get_serial_no(out, args.serial_no)
-
if out.has_batch_no and not args.get("batch_no"):
out.batch_no = get_batch_no(out.item_code, out.warehouse, out.qty)
actual_batch_qty = get_batch_qty(out.batch_no, out.warehouse, out.item_code)
if actual_batch_qty:
out.update(actual_batch_qty)
+
+ if out.has_serial_no:
+ out.serial_no = get_serial_no(out, args.serial_no)
if args.transaction_date and item.lead_time_days:
out.schedule_date = out.lead_time_date = add_days(args.transaction_date,
@@ -465,6 +465,17 @@
"qty": abs(cint(args.stock_qty))
}))
+def get_serial_no_batchwise(args):
+ if frappe.db.get_single_value("Stock Settings", "automatically_set_serial_nos_based_on_fifo"):
+ return "\n".join(frappe.db.sql_list("""select name from `tabSerial No`
+ where item_code=%(item_code)s and warehouse=%(warehouse)s and batch_no=%(batch_no)s
+ order by timestamp(purchase_date, purchase_time) asc limit %(qty)s""", {
+ "item_code": args.item_code,
+ "warehouse": args.warehouse,
+ "batch_no": args.batch_no,
+ "qty": abs(cint(args.stock_qty))
+ }))
+
@frappe.whitelist()
def get_conversion_factor(item_code, uom):
variant_of = frappe.db.get_value("Item", item_code, "variant_of")
@@ -492,14 +503,31 @@
return {'serial_no': serial_no}
@frappe.whitelist()
-def get_bin_details_and_serial_nos(item_code, warehouse, stock_qty=None, serial_no=None):
+def get_bin_details_and_serial_nos(item_code, warehouse, has_batch_no, stock_qty=None, serial_no=None):
bin_details_and_serial_nos = {}
bin_details_and_serial_nos.update(get_bin_details(item_code, warehouse))
if stock_qty > 0:
+ if has_batch_no:
+ args = frappe._dict({"item_code":item_code, "warehouse":warehouse, "stock_qty":stock_qty})
+ serial_no = get_serial_no(args)
+ bin_details_and_serial_nos.update({'serial_no': serial_no})
+ return bin_details_and_serial_nos
+
bin_details_and_serial_nos.update(get_serial_no_details(item_code, warehouse, stock_qty, serial_no))
return bin_details_and_serial_nos
@frappe.whitelist()
+def get_batch_qty_and_serial_no(batch_no, stock_qty, warehouse, item_code, has_serial_no):
+ batch_qty_and_serial_no = {}
+ batch_qty_and_serial_no.update(get_batch_qty(batch_no, warehouse, item_code))
+
+ if (flt(batch_qty_and_serial_no.get('actual_batch_qty')) >= flt(stock_qty)) and has_serial_no:
+ args = frappe._dict({"item_code":item_code, "warehouse":warehouse, "stock_qty":stock_qty, "batch_no":batch_no})
+ serial_no = get_serial_no(args)
+ batch_qty_and_serial_no.update({'serial_no': serial_no})
+ return batch_qty_and_serial_no
+
+@frappe.whitelist()
def get_batch_qty(batch_no, warehouse, item_code):
from erpnext.stock.doctype.batch import batch
if batch_no:
@@ -659,8 +687,17 @@
return ""
if args.get('warehouse') and args.get('stock_qty') and args.get('item_code'):
+ has_serial_no = frappe.get_value('Item', {'item_code': args.item_code}, "has_serial_no")
- if frappe.get_value('Item', {'item_code': args.item_code}, "has_serial_no") == 1:
+ if args.get('batch_no') and has_serial_no == 1:
+ return get_serial_no_batchwise(args)
+ # elif (args.get('has_batch_no') == 1) and has_serial_no == 1 and not args.get(batch_no):
+ # args.batch_no = get_batch_no(args.item_code, args.warehouse, args.qty)
+ # actual_batch_qty = get_batch_qty(out.batch_no, out.warehouse, out.item_code)
+ # if actual_batch_qty:
+ # out.update(actual_batch_qty)
+ # return get_serial_no_batchwise(args)
+ elif has_serial_no == 1:
args = json.dumps({"item_code": args.get('item_code'),"warehouse": args.get('warehouse'),"stock_qty": args.get('stock_qty')})
args = process_args(args)
serial_no = get_serial_nos_by_fifo(args)