Merge pull request #12638 from adityaduggal/develop

Resolves Issue #12630 -Added Filters to AR
diff --git "a/erpnext/docs/user/manual/en/regional/france/fichier_des_\303\251critures_comptables.md" b/erpnext/docs/user/manual/en/regional/france/fichier_des_ecritures_comptables.md
similarity index 100%
rename from "erpnext/docs/user/manual/en/regional/france/fichier_des_\303\251critures_comptables.md"
rename to erpnext/docs/user/manual/en/regional/france/fichier_des_ecritures_comptables.md
diff --git a/erpnext/docs/user/manual/en/regional/france/index.txt b/erpnext/docs/user/manual/en/regional/france/index.txt
new file mode 100644
index 0000000..2edf323
--- /dev/null
+++ b/erpnext/docs/user/manual/en/regional/france/index.txt
@@ -0,0 +1 @@
+fichier_des_ecritures_comptables
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index ed051b0..b4433fb 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -489,4 +489,5 @@
 erpnext.patches.v10_0.fichier_des_ecritures_comptables_for_france
 erpnext.patches.v10_0.update_assessment_plan
 erpnext.patches.v10_0.update_assessment_result
-erpnext.patches.v10_0.workflow_leave_application
\ No newline at end of file
+erpnext.patches.v10_0.added_extra_gst_custom_field
+erpnext.patches.v10_0.workflow_leave_application #2018-01-24
diff --git a/erpnext/patches/v10_0/added_extra_gst_custom_field.py b/erpnext/patches/v10_0/added_extra_gst_custom_field.py
new file mode 100644
index 0000000..a1512ed
--- /dev/null
+++ b/erpnext/patches/v10_0/added_extra_gst_custom_field.py
@@ -0,0 +1,9 @@
+import frappe
+from erpnext.regional.india.setup  import make_custom_fields
+
+def execute():
+	company = frappe.get_all('Company', filters = {'country': 'India'})
+	if not company:
+		return
+
+	make_custom_fields()
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/workflow_leave_application.py b/erpnext/patches/v10_0/workflow_leave_application.py
index 5db5dd9..8a68f89 100644
--- a/erpnext/patches/v10_0/workflow_leave_application.py
+++ b/erpnext/patches/v10_0/workflow_leave_application.py
@@ -3,49 +3,11 @@
 
 from __future__ import unicode_literals
 import frappe
+from erpnext.setup.install import leave_application_workflow
 
 def execute():
 	frappe.reload_doc("hr", "doctype", "leave_application")
 	frappe.reload_doc("workflow", "doctype", "workflow")
-
-	if not frappe.db.exists("Workflow State", "Open"):
-		frappe.get_doc({
-			'doctype': 'Workflow State',
-			'workflow_state_name': 'Open',
-			'style': 'Warning'
-		}).insert(ignore_permissions=True)
-
-	frappe.get_doc({
-		'doctype': 'Workflow',
-		'workflow_name': 'Leave Approval',
-		'document_type': 'Leave Application',
-		'is_active': 1,
-		'workflow_state_field': 'workflow_state',
-		'states': [{
-			"state": 'Open',
-			"doc_status": 0,
-			"allow_edit": 'Employee'
-		}, {
-			"state": 'Approved',
-			"doc_status": 1,
-			"allow_edit": 'Leave Approver'
-		}, {
-			"state": 'Rejected',
-			"doc_status": 1,
-			"allow_edit": 'Leave Approver'
-		}],
-		'transitions': [{
-			"state": 'Open',
-			"action": 'Approve',
-			"next_state": 'Approved',
-			"allowed": 'Leave Approver'
-		},
-		{
-			"state": 'Open',
-			"action": 'Reject',
-			"next_state": 'Rejected',
-			"allowed": 'Leave Approver'
-		}]
-	}).insert(ignore_permissions=True)
-
-	frappe.db.sql("""update `tabLeave Application` set workflow_state = status""")
+	leave_application_workflow()
+	if frappe.db.has_column("Leave Application", "status"):
+		frappe.db.sql("""update `tabLeave Application` set workflow_state = status""")
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 7143bd3..e9d91ab 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -103,7 +103,20 @@
 			depends_on='eval:in_list(["SEZ", "Export", "Deemed Export"], doc.invoice_type)',
 			options='\nWith Payment of Tax\nWithout Payment of Tax'),
 		dict(fieldname='ecommerce_gstin', label='E-commerce GSTIN',
-			fieldtype='Data', insert_after='export_type', print_hide=1)
+			fieldtype='Data', insert_after='export_type', print_hide=1),
+		dict(fieldname='reason_for_issuing_document', label='Reason For Issuing document',
+			fieldtype='Select', insert_after='ecommerce_gstin', print_hide=1,
+			depends_on='eval:doc.is_return==1',
+			options='\n01-Sales Return\n02-Post Sale Discount\n03-Deficiency in services\n04-Correction in Invoice\n05-Change in POS\n06-Finalization of Provisional assessment\n07-Others'),
+		dict(fieldname='port_code', label='Port Code',
+			fieldtype='Data', insert_after='reason_for_issuing_document', print_hide=1,
+			depends_on="eval:doc.invoice_type=='Export' "),
+		dict(fieldname='shipping_bill_number', label=' Shipping Bill Number',
+			fieldtype='Data', insert_after='port_code', print_hide=1,
+			depends_on="eval:doc.invoice_type=='Export' "),
+		dict(fieldname='shipping_bill_date', label='Shipping Bill Date',
+			fieldtype='Date', insert_after='shipping_bill_number', print_hide=1,
+			depends_on="eval:doc.invoice_type=='Export' "),
 	]
 
 	purchase_invoice_gst_fields = [
diff --git a/erpnext/regional/report/gstr_1/gstr_1.js b/erpnext/regional/report/gstr_1/gstr_1.js
index 9437786..3a63527 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.js
+++ b/erpnext/regional/report/gstr_1/gstr_1.js
@@ -31,7 +31,7 @@
 			"label": __("Type of Business"),
 			"fieldtype": "Select",
 			"reqd": 1,
-			"options": ["B2B", "B2C Large", "B2C Small"],
+			"options": ["B2B", "B2C Large", "B2C Small","CDNR", "EXPORT"],
 			"default": "B2B"
 		}
 	]
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 65b1b89..b6df878 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -4,6 +4,7 @@
 from __future__ import unicode_literals
 import frappe, json
 from frappe import _
+from datetime import date
 
 def execute(filters=None):
 	return Gstr1Report(filters).run()
@@ -12,7 +13,7 @@
 	def __init__(self, filters=None):
 		self.filters = frappe._dict(filters or {})
 		self.customer_type = "Company" if self.filters.get("type_of_business") ==  "B2B" else "Individual"
-		
+
 	def run(self):
 		self.get_columns()
 		self.get_data()
@@ -35,13 +36,15 @@
 			for rate, items in items_based_on_rate.items():
 				row = []
 				for fieldname in invoice_fields:
-					if fieldname == "invoice_value":
+					if self.filters.get("type_of_business") ==  "CDNR" and fieldname == "invoice_value":
+						row.append(abs(invoice_details.base_rounded_total) or abs(invoice_details.base_grand_total))
+					elif fieldname == "invoice_value":
 						row.append(invoice_details.base_rounded_total or invoice_details.base_grand_total)
 					else:
 						row.append(invoice_details.get(fieldname))
 
 				row += [rate,
-					sum([net_amount for item_code, net_amount in self.invoice_items.get(inv).items()
+					sum([abs(net_amount) for item_code, net_amount in self.invoice_items.get(inv).items()
 						if item_code in items]),
 					self.invoice_cess.get(inv)
 				]
@@ -49,6 +52,10 @@
 				if self.filters.get("type_of_business") ==  "B2C Small":
 					row.append("E" if invoice_details.ecommerce_gstin else "OE")
 
+				if self.filters.get("type_of_business") ==  "CDNR":
+					row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N")
+					row.append("C" if invoice_details.return_against else "R")
+
 				self.data.append(row)
 
 	def get_invoice_data(self):
@@ -66,7 +73,15 @@
 				place_of_supply,
 				ecommerce_gstin,
 				reverse_charge,
-				invoice_type
+				invoice_type,
+				return_against,
+				is_return,
+				invoice_type,
+				export_type,
+				port_code,
+				shipping_bill_number,
+				shipping_bill_date,
+				reason_for_issuing_document
 			from `tabSales Invoice`
 			where docstatus = 1 %s
 			order by posting_date desc
@@ -85,18 +100,27 @@
 					conditions += opts[1]
 
 		customers = frappe.get_all("Customer", filters={"customer_type": self.customer_type})
-		conditions += " and customer in ('{0}')".format("', '".join([frappe.db.escape(c.name)
-			for c in customers]))
+
+		if self.filters.get("type_of_business") ==  "B2B":
+			conditions += " and invoice_type != 'Export' and is_return != 1 and customer in ('{0}')".\
+				format("', '".join([frappe.db.escape(c.name) for c in customers]))
 
 		if self.filters.get("type_of_business") ==  "B2C Large":
 			conditions += """ and SUBSTR(place_of_supply, 1, 2) != SUBSTR(company_gstin, 1, 2)
-				and grand_total > 250000"""
+				and grand_total > 250000 and is_return != 1 and customer in ('{0}')""".\
+					format("', '".join([frappe.db.escape(c.name) for c in customers]))
+
 		elif self.filters.get("type_of_business") ==  "B2C Small":
 			conditions += """ and (
 				SUBSTR(place_of_supply, 1, 2) = SUBSTR(company_gstin, 1, 2)
-				or grand_total <= 250000
-			)"""
+					or grand_total <= 250000 ) and is_return != 1 and customer in ('{0}')""".\
+						format("', '".join([frappe.db.escape(c.name) for c in customers]))
 
+		elif self.filters.get("type_of_business") ==  "CDNR":
+			conditions += """ and is_return = 1 """
+
+		elif self.filters.get("type_of_business") ==  "EXPORT":
+			conditions += """ and is_return !=1 and invoice_type = 'Export' """
 		return conditions
 
 	def get_invoice_items(self):
@@ -118,7 +142,7 @@
 			where
 				parenttype = 'Sales Invoice' and docstatus = 1
 				and parent in (%s)
-				and tax_amount_after_discount_amount > 0
+
 			order by account_head
 		""" % (', '.join(['%s']*len(self.invoices.keys()))), tuple(self.invoices.keys()))
 
@@ -152,7 +176,6 @@
 								.setdefault(tax_rate, [])
 							if item_code not in rate_based_dict:
 								rate_based_dict.append(item_code)
-
 					except ValueError:
 						continue
 		if unidentified_gst_accounts:
@@ -185,12 +208,6 @@
 				"label": "Taxable Value",
 				"fieldtype": "Currency",
 				"width": 100
-			},
-			{
-				"fieldname": "cess_amount",
-				"label": "Cess Amount",
-				"fieldtype": "Currency",
-				"width": 100
 			}
 		]
 		self.other_columns = []
@@ -200,33 +217,39 @@
 				{
 					"fieldname": "customer_gstin",
 					"label": "GSTIN/UIN of Recipient",
-					"fieldtype": "Data"
+					"fieldtype": "Data",
+					"width": 150
 				},
 				{
 					"fieldname": "customer_name",
 					"label": "Receiver Name",
-					"fieldtype": "Data"
+					"fieldtype": "Data",
+					"width":100
 				},
 				{
 					"fieldname": "invoice_number",
 					"label": "Invoice Number",
 					"fieldtype": "Link",
-					"options": "Sales Invoice"
+					"options": "Sales Invoice",
+					"width":100
 				},
 				{
 					"fieldname": "posting_date",
 					"label": "Invoice date",
-					"fieldtype": "Date"
+					"fieldtype": "Date",
+					"width":80
 				},
 				{
 					"fieldname": "invoice_value",
 					"label": "Invoice Value",
-					"fieldtype": "Currency"
+					"fieldtype": "Currency",
+					"width":100
 				},
 				{
 					"fieldname": "place_of_supply",
 					"label": "Place of Supply",
-					"fieldtype": "Data"
+					"fieldtype": "Data",
+					"width":100
 				},
 				{
 					"fieldname": "reverse_charge",
@@ -241,9 +264,19 @@
 				{
 					"fieldname": "ecommerce_gstin",
 					"label": "E-Commerce GSTIN",
-					"fieldtype": "Data"
+					"fieldtype": "Data",
+					"width":120
 				}
 			]
+			self.other_columns = [
+					{
+						"fieldname": "cess_amount",
+						"label": "Cess Amount",
+						"fieldtype": "Currency",
+						"width": 100
+					}
+				]
+
 		elif self.filters.get("type_of_business") ==  "B2C Large":
 			self.invoice_columns = [
 				{
@@ -278,6 +311,93 @@
 					"width": 130
 				}
 			]
+			self.other_columns = [
+					{
+						"fieldname": "cess_amount",
+						"label": "Cess Amount",
+						"fieldtype": "Currency",
+						"width": 100
+					}
+				]
+		elif self.filters.get("type_of_business") ==  "CDNR":
+			self.invoice_columns = [
+				{
+					"fieldname": "customer_gstin",
+					"label": "GSTIN/UIN of Recipient",
+					"fieldtype": "Data",
+					"width": 150
+				},
+				{
+					"fieldname": "customer_name",
+					"label": "Receiver Name",
+					"fieldtype": "Data",
+					"width": 120
+				},
+				{
+					"fieldname": "return_against",
+					"label": "Invoice/Advance Receipt Number",
+					"fieldtype": "Link",
+					"options": "Sales Invoice",
+					"width": 120
+				},
+				{
+					"fieldname": "posting_date",
+					"label": "Invoice/Advance Receipt date",
+					"fieldtype": "Date",
+					"width": 120
+				},
+				{
+					"fieldname": "invoice_number",
+					"label": "Invoice/Advance Receipt Number",
+					"fieldtype": "Link",
+					"options": "Sales Invoice",
+					"width":120
+				},
+				{
+					"fieldname": "posting_date",
+					"label": "Invoice/Advance Receipt date",
+					"fieldtype": "Date",
+					"width": 120
+				},
+				{
+					"fieldname": "reason_for_issuing_document",
+					"label": "Reason For Issuing document",
+					"fieldtype": "Data",
+					"width": 140
+				},
+				{
+					"fieldname": "place_of_supply",
+					"label": "Place of Supply",
+					"fieldtype": "Data",
+					"width": 120
+				},
+				{
+					"fieldname": "invoice_value",
+					"label": "Invoice Value",
+					"fieldtype": "Currency",
+					"width": 120
+				}
+			]
+			self.other_columns = [
+				{
+						"fieldname": "cess_amount",
+						"label": "Cess Amount",
+						"fieldtype": "Currency",
+						"width": 100
+				},
+				{
+					"fieldname": "pre_gst",
+					"label": "PRE GST",
+					"fieldtype": "Data",
+					"width": 80
+				},
+				{
+					"fieldname": "document_type",
+					"label": "Document Type",
+					"fieldtype": "Data",
+					"width": 80
+				}
+			]
 		elif self.filters.get("type_of_business") ==  "B2C Small":
 			self.invoice_columns = [
 				{
@@ -295,10 +415,62 @@
 			]
 			self.other_columns = [
 				{
+						"fieldname": "cess_amount",
+						"label": "Cess Amount",
+						"fieldtype": "Currency",
+						"width": 100
+				},
+				{
 					"fieldname": "type",
 					"label": "Type",
 					"fieldtype": "Data",
 					"width": 50
 				}
 			]
-		self.columns = self.invoice_columns + self.tax_columns + self.other_columns
\ No newline at end of file
+		elif self.filters.get("type_of_business") ==  "EXPORT":
+			self.invoice_columns = [
+				{
+					"fieldname": "export_type",
+					"label": "Export Type",
+					"fieldtype": "Data",
+					"width":120
+				},
+				{
+					"fieldname": "invoice_number",
+					"label": "Invoice Number",
+					"fieldtype": "Link",
+					"options": "Sales Invoice",
+					"width":120
+				},
+				{
+					"fieldname": "posting_date",
+					"label": "Invoice date",
+					"fieldtype": "Date",
+					"width": 120
+				},
+				{
+					"fieldname": "invoice_value",
+					"label": "Invoice Value",
+					"fieldtype": "Currency",
+					"width": 120
+				},
+				{
+					"fieldname": "port_code",
+					"label": "Port Code",
+					"fieldtype": "Data",
+					"width": 120
+				},
+				{
+					"fieldname": "shipping_bill_number",
+					"label": "Shipping Bill Number",
+					"fieldtype": "Data",
+					"width": 120
+				},
+				{
+					"fieldname": "shipping_bill_date",
+					"label": "Shipping Bill Date",
+					"fieldtype": "Date",
+					"width": 120
+				}
+			]
+		self.columns = self.invoice_columns + self.tax_columns + self.other_columns
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 1c3354c..5bacf28 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -567,10 +567,12 @@
 		target.base_amount = target.amount * flt(source_parent.conversion_rate)
 		target.qty = target.amount / flt(source.rate) if (source.rate and source.billed_amt) else source.qty
 
-		item = frappe.db.get_value("Item", target.item_code, ["item_group", "selling_cost_center"], as_dict=1)
-		target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
-			or item.selling_cost_center \
-			or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+		if source_parent.project:
+			target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center")
+		if not target.cost_center and target.item_code:
+			item = frappe.db.get_value("Item", target.item_code, ["item_group", "selling_cost_center"], as_dict=1)
+			target.cost_center = item.selling_cost_center \
+				or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
 
 	doclist = get_mapped_doc("Sales Order", source_name, {
 		"Sales Order": {
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 81f909a..2cc280f 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -12,6 +12,7 @@
 	<a style="color: #888" href="http://erpnext.org">ERPNext</a></div>"""
 
 def after_install():
+	leave_application_workflow()
 	frappe.get_doc({'doctype': "Role", "role_name": "Analytics"}).insert()
 	set_single_defaults()
 	create_compact_item_print_custom_field()
@@ -19,6 +20,58 @@
 	add_all_roles_to("Administrator")
 	frappe.db.commit()
 
+def leave_application_workflow():
+	states = {'Approved': 'Success', 'Rejected': 'Danger', 'Open': 'Warning'}
+
+	for state, style in states.items():
+		if not frappe.db.exists("Workflow State", state):
+			frappe.get_doc({
+				'doctype': 'Workflow State',
+				'workflow_state_name': state,
+				'style': style
+			}).insert(ignore_permissions=True)
+
+	for action in ['Approve', 'Reject']:
+		if not frappe.db.exists("Workflow Action", action):
+			frappe.get_doc({
+				'doctype': 'Workflow Action',
+				'workflow_action_name': action
+			}).insert(ignore_permissions=True)
+
+	if not frappe.db.exists("Workflow", "Leave Approval"):
+		frappe.get_doc({
+			'doctype': 'Workflow',
+			'workflow_name': 'Leave Approval',
+			'document_type': 'Leave Application',
+			'is_active': 1,
+			'workflow_state_field': 'workflow_state',
+			'states': [{
+				"state": 'Open',
+				"doc_status": 0,
+				"allow_edit": 'Employee'
+			}, {
+				"state": 'Approved',
+				"doc_status": 1,
+				"allow_edit": 'Leave Approver'
+			}, {
+				"state": 'Rejected',
+				"doc_status": 1,
+				"allow_edit": 'Leave Approver'
+			}],
+			'transitions': [{
+				"state": 'Open',
+				"action": 'Approve',
+				"next_state": 'Approved',
+				"allowed": 'Leave Approver'
+			},
+			{
+				"state": 'Open',
+				"action": 'Reject',
+				"next_state": 'Rejected',
+				"allowed": 'Leave Approver'
+			}]
+		}).insert(ignore_permissions=True)
+
 def check_setup_wizard_not_completed():
 	if frappe.db.get_default('desktop:home_page') == 'desktop':
 		print()
diff --git a/erpnext/startup/notifications.py b/erpnext/startup/notifications.py
index eb06f27..b8fce6e 100644
--- a/erpnext/startup/notifications.py
+++ b/erpnext/startup/notifications.py
@@ -30,7 +30,7 @@
 				"docstatus": ("<", 2)
 			},
 			"Payment Entry": {"docstatus": 0},
-			"Leave Application": {"status": "Open"},
+			"Leave Application": {"docstatus": 0},
 			"Expense Claim": {"approval_status": "Draft"},
 			"Job Applicant": {"status": "Open"},
 			"Delivery Note": {
diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index 42e2cef..03ce7b6 100644
--- a/erpnext/stock/doctype/batch/batch.py
+++ b/erpnext/stock/doctype/batch/batch.py
@@ -5,24 +5,31 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.model.naming import make_autoname
+from frappe.model.naming import make_autoname, revert_series_if_last
 from frappe.utils import flt, cint
 
 
-class UnableToSelectBatchError(frappe.ValidationError): pass
+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 + '.#####')
+	"""
+	Get a name generated for a Batch from the Batch's naming series.
+	:return: The string that was generated.
+	"""
+	naming_series_prefix = _get_batch_prefix()
+	key = _make_naming_series_key(naming_series_prefix)
+	name = make_autoname(key)
 
 	return name
 
 
 def get_name_from_hash():
+	"""
+	Get a name for a Batch by generating a unique hash.
+	:return: The hash that was generated.
+	"""
 	temp = None
 	while not temp:
 		temp = frappe.generate_hash()[:7].upper()
@@ -32,13 +39,66 @@
 	return temp
 
 
+def batch_uses_naming_series():
+	"""
+	Verify if the Batch is to be named using a naming series
+	:return: bool
+	"""
+	use_naming_series = cint(frappe.db.get_single_value('Stock Settings', 'use_naming_series'))
+	return bool(use_naming_series)
+
+
+def _get_batch_prefix():
+	"""
+	Get the naming series prefix set in Stock Settings.
+
+	It does not do any sanity checks so make sure to use it after checking if the Batch
+	is set to use naming series.
+	:return: The naming series.
+	"""
+	naming_series_prefix = frappe.db.get_single_value('Stock Settings', 'naming_series_prefix')
+	if not naming_series_prefix:
+		naming_series_prefix = 'BATCH-'
+
+	return naming_series_prefix
+
+
+def _make_naming_series_key(prefix):
+	"""
+	Make naming series key for a Batch.
+
+	Naming series key is in the format [prefix].[#####]
+	:param prefix: Naming series prefix gotten from Stock Settings
+	:return: The derived key. If no prefix is given, an empty string is returned
+	"""
+	if not unicode(prefix):
+		return ''
+	else:
+		return prefix.upper() + '.#####'
+
+
+def get_batch_naming_series():
+	"""
+	Get naming series key for a Batch.
+
+	Naming series key is in the format [prefix].[#####]
+	:return: The naming series or empty string if not available
+	"""
+	series = ''
+	if batch_uses_naming_series():
+		prefix = _get_batch_prefix()
+		key = _make_naming_series_key(prefix)
+		series = key
+
+	return series
+
+
 class Batch(Document):
 	def autoname(self):
 		"""Generate random ID for batch if not specified"""
 		if not self.batch_id:
 			if frappe.db.get_value('Item', self.item, 'create_new_batch'):
-				use_naming_series = frappe.db.get_single_value('Stock Settings', 'use_naming_series')
-				if use_naming_series:
+				if batch_uses_naming_series():
 					self.batch_id = get_name_from_naming_series()
 				else:
 					self.batch_id = get_name_from_hash()
@@ -50,13 +110,17 @@
 	def onload(self):
 		self.image = frappe.db.get_value('Item', self.item, 'image')
 
+	def after_delete(self):
+		revert_series_if_last(get_batch_naming_series(), self.name)
+
 	def validate(self):
 		self.item_has_batch_enabled()
 
 	def item_has_batch_enabled(self):
-		if frappe.db.get_value("Item",self.item,"has_batch_no") == 0:
+		if frappe.db.get_value("Item", self.item, "has_batch_no") == 0:
 			frappe.throw(_("The selected item cannot have Batch"))
 
+
 @frappe.whitelist()
 def get_batch_qty(batch_no=None, warehouse=None, item_code=None):
 	"""Returns batch actual qty if warehouse is passed,
@@ -89,16 +153,18 @@
 
 	return out
 
+
 @frappe.whitelist()
 def get_batches_by_oldest(item_code, 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 = 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])
 	return batches_dates
 
+
 @frappe.whitelist()
-def split_batch(batch_no, item_code, warehouse, qty, new_batch_id = None):
+def split_batch(batch_no, item_code, warehouse, qty, new_batch_id=None):
 	"""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(
@@ -106,16 +172,16 @@
 		purpose='Repack',
 		items=[
 			dict(
-				item_code = item_code,
-				qty = float(qty or 0),
-				s_warehouse = warehouse,
-				batch_no = batch_no
+				item_code=item_code,
+				qty=float(qty or 0),
+				s_warehouse=warehouse,
+				batch_no=batch_no
 			),
 			dict(
-				item_code = item_code,
-				qty = float(qty or 0),
-				t_warehouse = warehouse,
-				batch_no = batch.name
+				item_code=item_code,
+				qty=float(qty or 0),
+				t_warehouse=warehouse,
+				batch_no=batch.name
 			),
 		]
 	))
@@ -124,7 +190,8 @@
 
 	return batch.name
 
-def set_batch_nos(doc, warehouse_field, throw = False):
+
+def set_batch_nos(doc, warehouse_field, throw=False):
 	"""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
@@ -138,6 +205,7 @@
 				if flt(batch_qty) < flt(qty):
 					frappe.throw(_("Row #{0}: The batch {1} has only {2} qty. Please select another batch which has {3} qty available or split the row into multiple rows, to deliver/issue from multiple batches").format(d.idx, d.batch_no, batch_qty, d.qty))
 
+
 @frappe.whitelist()
 def get_batch_no(item_code, warehouse, qty=1, throw=False):
 	"""
diff --git a/erpnext/stock/doctype/batch/test_batch.py b/erpnext/stock/doctype/batch/test_batch.py
index a327b2d..9538781 100644
--- a/erpnext/stock/doctype/batch/test_batch.py
+++ b/erpnext/stock/doctype/batch/test_batch.py
@@ -7,6 +7,8 @@
 import unittest
 
 from erpnext.stock.doctype.batch.batch import get_batch_qty, UnableToSelectBatchError, get_batch_no
+from frappe.utils import cint
+
 
 class TestBatch(unittest.TestCase):
 
@@ -21,7 +23,7 @@
 	def make_batch_item(cls, item_name):
 		from erpnext.stock.doctype.item.test_item import make_item
 		if not frappe.db.exists(item_name):
-			make_item(item_name, dict(has_batch_no = 1, create_new_batch = 1))
+			return make_item(item_name, dict(has_batch_no = 1, create_new_batch = 1))
 
 	def test_purchase_receipt(self, batch_qty = 100):
 		'''Test automated batch creation from Purchase Receipt'''
@@ -192,3 +194,37 @@
 			]
 		)).insert()
 		stock_entry.submit()
+
+	def test_batch_name_with_naming_series(self):
+		stock_settings = frappe.get_single('Stock Settings')
+		use_naming_series = cint(stock_settings.use_naming_series)
+
+		if not use_naming_series:
+			frappe.set_value('Stock Settings', 'Stock Settings', 'use_naming_series', 1)
+
+		batch = self.make_new_batch('_Test Stock Item For Batch Test1')
+		batch_name = batch.name
+
+		self.assertTrue(batch_name.startswith('BATCH-'))
+
+		batch.delete()
+		batch = self.make_new_batch('_Test Stock Item For Batch Test2')
+
+		self.assertEqual(batch_name, batch.name)
+
+		# reset Stock Settings
+		if not use_naming_series:
+			frappe.set_value('Stock Settings', 'Stock Settings', 'use_naming_series', 0)
+
+	def make_new_batch(self, item_name, batch_id=None, do_not_insert=0):
+		batch = frappe.new_doc('Batch')
+		item = self.make_batch_item(item_name)
+		batch.item = item.name
+
+		if batch_id:
+			batch.batch_id = batch_id
+
+		if not do_not_insert:
+			batch.insert()
+
+		return batch