diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index c70cfcd811..31a3f6c5a5 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -198,7 +198,6 @@ class AccountsController(TransactionBase): if self.get("is_subcontracted"): args["is_subcontracted"] = self.is_subcontracted - ret = get_item_details(args) for fieldname, value in ret.items(): diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 1551b1dfc3..102090b812 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -296,7 +296,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ 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; @@ -305,7 +304,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ this.frm.doc.doctype === 'Delivery Note') { show_batch_dialog = 1; } - // clear barcode if setting item (else barcode will take priority) if(!from_barcode) { item.barcode = null; diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 0e6017987a..a9ac8c4e61 100644 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -69,7 +69,7 @@ $.extend(erpnext, { "get_query": function () { return { filters: { - item_code:grid_row.doc.item_code , + item_code:grid_row.doc.item_code, warehouse:cur_frm.doc.is_return ? null : grid_row.doc.warehouse } } diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index aa5b3ba498..d6f4677f8e 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -186,25 +186,32 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ 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 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ 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 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ }, 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 5487193284..ebf7ea170e 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,9 +1709,42 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "150px" }, + { + "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 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -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/doctype/serial_no/serial_no.json b/erpnext/stock/doctype/serial_no/serial_no.json index b37713be96..1ff0332476 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.json +++ b/erpnext/stock/doctype/serial_no/serial_no.json @@ -41,6 +41,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -69,6 +70,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -100,6 +102,7 @@ "reqd": 1, "search_index": 1, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -132,6 +135,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -165,6 +169,38 @@ "reqd": 0, "search_index": 1, "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "batch_no", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Batch No", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -193,6 +229,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -222,6 +259,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -253,6 +291,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "300px" }, @@ -287,6 +326,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -319,6 +359,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -348,6 +389,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -376,6 +418,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "50%" }, @@ -407,6 +450,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -437,6 +481,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -468,6 +513,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -497,6 +543,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -529,6 +576,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -557,6 +605,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "50%" }, @@ -588,6 +637,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -617,6 +667,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -647,6 +698,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -677,6 +729,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -707,6 +760,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -738,6 +792,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -767,6 +822,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -799,6 +855,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -827,6 +884,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "50%" }, @@ -860,6 +918,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -891,6 +950,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -921,6 +981,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -952,6 +1013,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -981,6 +1043,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1009,6 +1072,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "50%" }, @@ -1042,6 +1106,7 @@ "reqd": 0, "search_index": 1, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "150px" }, @@ -1074,6 +1139,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "150px" }, @@ -1103,6 +1169,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "50%" }, @@ -1135,6 +1202,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "150px" }, @@ -1167,6 +1235,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "150px" }, @@ -1197,6 +1266,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1226,6 +1296,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1256,6 +1327,7 @@ "reqd": 1, "search_index": 1, "set_only_once": 0, + "translatable": 0, "unique": 0 } ], @@ -1270,7 +1342,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-05-15 18:22:23.685286", + "modified": "2018-04-13 11:51:38.163506", "modified_by": "Administrator", "module": "Stock", "name": "Serial No", @@ -1278,7 +1350,6 @@ "permissions": [ { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 1, "delete": 1, @@ -1298,7 +1369,6 @@ }, { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 0, "delete": 0, @@ -1318,7 +1388,6 @@ }, { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 0, "delete": 0, diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 98f15a831a..a6d2a0b06f 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -16,6 +16,7 @@ class SerialNoRequiredError(ValidationError): pass class SerialNoQtyError(ValidationError): pass class SerialNoItemError(ValidationError): pass class SerialNoWarehouseError(ValidationError): pass +class SerialNoBatchError(ValidationError): pass class SerialNoNotExistsError(ValidationError): pass class SerialNoDuplicateError(ValidationError): pass @@ -187,6 +188,7 @@ def process_serial_no(sle): update_serial_nos(sle, item_det) def validate_serial_no(sle, item_det): + if item_det.has_serial_no==0: if sle.serial_no: frappe.throw(_("Item {0} is not setup for Serial Nos. Column must be blank").format(sle.item_code), @@ -228,8 +230,13 @@ def validate_serial_no(sle, item_det): frappe.throw(_("Serial No {0} does not belong to Warehouse {1}").format(serial_no, sle.warehouse), SerialNoWarehouseError) - if sle.voucher_type in ("Delivery Note", "Sales Invoice") \ - and sle.is_cancelled=="No" and not sr.warehouse: + if sle.voucher_type in ("Delivery Note", "Sales Invoice"): + + if sr.batch_no and sr.batch_no != sle.batch_no: + frappe.throw(_("Serial No {0} does not belong to Batch {1}").format(serial_no, + sle.batch_no), SerialNoBatchError) + + if sle.is_cancelled=="No" and not sr.warehouse: frappe.throw(_("Serial No {0} does not belong to any Warehouse") .format(serial_no), SerialNoWarehouseError) @@ -291,6 +298,7 @@ def update_serial_nos(sle, item_det): sr.via_stock_ledger = True sr.item_code = sle.item_code sr.warehouse = sle.warehouse if sle.actual_qty > 0 else None + sr.batch_no = sle.batch_no sr.save(ignore_permissions=True) elif sle.actual_qty > 0: make_serial_no(serial_no, sle) @@ -313,6 +321,7 @@ def make_serial_no(serial_no, sle): sr.serial_no = serial_no sr.item_code = sle.item_code sr.company = sle.company + sr.batch_no = sle.batch_no sr.via_stock_ledger = True sr.insert() diff --git a/erpnext/stock/doctype/serial_no/test_serial_no.js b/erpnext/stock/doctype/serial_no/test_serial_no.js new file mode 100644 index 0000000000..bf8293257c --- /dev/null +++ b/erpnext/stock/doctype/serial_no/test_serial_no.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Serial No", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Serial No + () => frappe.tests.make('Serial No', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 7e456dd3d3..b36cd39ad7 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -76,20 +76,23 @@ def get_item_details(args): args[key] = value out.update(get_pricing_rule_for_item(args)) - if (args.get("doctype") == "Delivery Note" or (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 and args.get('batch_no'): + out.batch_no = args.get('batch_no') + out.serial_no = get_serial_no(out, args.serial_no) + + elif 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, item.lead_time_days) @@ -465,6 +468,17 @@ def get_serial_nos_by_fifo(args): "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 or batch_no is NULL) + 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,13 +506,30 @@ def get_serial_no_details(item_code, warehouse, stock_qty, serial_no): 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 @@ -659,8 +690,10 @@ def get_serial_no(args, serial_nos=None): return "" if args.get('warehouse') and args.get('stock_qty') and args.get('item_code'): - - if frappe.get_value('Item', {'item_code': args.item_code}, "has_serial_no") == 1: + has_serial_no = frappe.get_value('Item', {'item_code': args.item_code}, "has_serial_no") + if args.get('batch_no') and has_serial_no == 1: + 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)