From e1e38a4bb91965536c6843b6f983b93dfe66675e Mon Sep 17 00:00:00 2001 From: tundebabzy Date: Fri, 12 Jan 2018 12:00:02 +0100 Subject: [PATCH] Autoname for Batch DocType #12302 (#12461) * add new fields: check: use naming series data: series prefix * refactor autoname: use new function - get_name_from_hash * add new function - get_name_from_naming_series * refactor autoname to generate name from naming series * PEP 8 compliance --- erpnext/stock/doctype/batch/batch.py | 46 ++++++--- .../stock_settings/stock_settings.json | 96 ++++++++++++++++++- 2 files changed, 128 insertions(+), 14 deletions(-) diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py index 760643c4ec..42e2ceff68 100644 --- a/erpnext/stock/doctype/batch/batch.py +++ b/erpnext/stock/doctype/batch/batch.py @@ -5,23 +5,43 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.model.document import Document +from frappe.model.naming import make_autoname from frappe.utils import flt, cint class UnableToSelectBatchError(frappe.ValidationError): pass + +def get_name_from_naming_series(): + naming_series_prefix = frappe.db.get_single_value('Stock Settings', 'naming_series_prefix') + if not naming_series_prefix: + naming_series_prefix = 'BATCH-' + + name = make_autoname(naming_series_prefix + '.#####') + + return name + + +def get_name_from_hash(): + temp = None + while not temp: + temp = frappe.generate_hash()[:7].upper() + if frappe.db.exists('Batch', temp): + temp = None + + return temp + + class Batch(Document): def autoname(self): - '''Generate random ID for batch if not specified''' + """Generate random ID for batch if not specified""" if not self.batch_id: if frappe.db.get_value('Item', self.item, 'create_new_batch'): - temp = None - while not temp: - temp = frappe.generate_hash()[:7].upper() - if frappe.db.exists('Batch', temp): - temp = None - - self.batch_id = temp + use_naming_series = frappe.db.get_single_value('Stock Settings', 'use_naming_series') + if use_naming_series: + self.batch_id = get_name_from_naming_series() + else: + self.batch_id = get_name_from_hash() else: frappe.throw(_('Batch ID is mandatory'), frappe.MandatoryError) @@ -39,14 +59,14 @@ class Batch(Document): @frappe.whitelist() def get_batch_qty(batch_no=None, warehouse=None, item_code=None): - '''Returns batch actual qty if warehouse is passed, + """Returns batch actual qty if warehouse is passed, or returns dict of qty by warehouse if warehouse is None The user must pass either batch_no or batch_no + warehouse or item_code + warehouse :param batch_no: Optional - give qty for this batch no :param warehouse: Optional - give qty for this warehouse - :param item_code: Optional - give qty for this item''' + :param item_code: Optional - give qty for this item""" frappe.has_permission('Batch', throw=True) out = 0 if batch_no and warehouse: @@ -71,7 +91,7 @@ def get_batch_qty(batch_no=None, warehouse=None, item_code=None): @frappe.whitelist() def get_batches_by_oldest(item_code, warehouse): - '''Returns the oldest batch and qty for the given item_code and warehouse''' + """Returns the oldest batch and qty for the given item_code and warehouse""" batches = get_batch_qty(item_code = item_code, warehouse = warehouse) batches_dates = [[batch, frappe.get_value('Batch', batch.batch_no, 'expiry_date')] for batch in batches] batches_dates.sort(key=lambda tup: tup[1]) @@ -79,7 +99,7 @@ def get_batches_by_oldest(item_code, warehouse): @frappe.whitelist() def split_batch(batch_no, item_code, warehouse, qty, new_batch_id = None): - '''Split the batch into a new batch''' + """Split the batch into a new batch""" batch = frappe.get_doc(dict(doctype='Batch', item=item_code, batch_id=new_batch_id)).insert() stock_entry = frappe.get_doc(dict( doctype='Stock Entry', @@ -105,7 +125,7 @@ def split_batch(batch_no, item_code, warehouse, qty, new_batch_id = None): return batch.name def set_batch_nos(doc, warehouse_field, throw = False): - '''Automatically select `batch_no` for outgoing items in item table''' + """Automatically select `batch_no` for outgoing items in item table""" for d in doc.items: qty = d.get('stock_qty') or d.get('transfer_qty') or d.get('qty') or 0 has_batch_no = frappe.db.get_value('Item', d.item_code, 'has_batch_no') diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json index 761f807a2d..48f89ec20f 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.json +++ b/erpnext/stock/doctype/stock_settings/stock_settings.json @@ -3,6 +3,7 @@ "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, + "autoname": "", "beta": 0, "creation": "2013-06-24 16:37:54", "custom": 0, @@ -666,6 +667,99 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "batch_id_sb", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Batch Identification", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "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, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "use_naming_series", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Use Naming Series", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "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, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "BATCH-", + "depends_on": "eval:doc.use_naming_series==1", + "fieldname": "naming_series_prefix", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Naming Series Prefix", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "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, + "unique": 0 } ], "has_web_view": 0, @@ -679,7 +773,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2017-11-17 01:35:49.562613", + "modified": "2018-01-12 09:38:58.200950", "modified_by": "Administrator", "module": "Stock", "name": "Stock Settings",