Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index 6871b1e..c17654a 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -351,7 +351,7 @@
 			
 			if ret.get("warehouse"):
 				ret["actual_qty"] = flt(webnotes.conn.get_value("Bin",
-					{"item_code": args.get("item_code"), "warehouse": args.get("warehouse")},
+					{"item_code": args.get("item_code"), "warehouse": ret.get("warehouse")},
 					"actual_qty"))
 		return ret
 
@@ -433,17 +433,6 @@
 			from accounts.utils import reconcile_against_document
 			reconcile_against_document(lst)
 			
-	def validate_customer(self):
-		"""	Validate customer name with SO and DN"""
-		for d in getlist(self.doclist,'entries'):
-			dt = d.delivery_note and 'Delivery Note' or d.sales_order and 'Sales Order' or ''
-			if dt:
-				dt_no = d.delivery_note or d.sales_order
-				cust = webnotes.conn.sql("select customer from `tab%s` where name = %s" % (dt, '%s'), dt_no)
-				if cust and cstr(cust[0][0]) != cstr(self.doc.customer):
-					msgprint("Customer %s does not match with customer of %s: %s." %(self.doc.customer, dt, dt_no), raise_exception=1)
-			
-
 	def validate_customer_account(self):
 		"""Validates Debit To Account and Customer Matches"""
 		if self.doc.customer and self.doc.debit_to and not cint(self.doc.is_pos):
@@ -453,6 +442,19 @@
 				(not acc_head and (self.doc.debit_to != cstr(self.doc.customer) + " - " + self.get_company_abbr())):
 				msgprint("Debit To: %s do not match with Customer: %s for Company: %s.\n If both correctly entered, please select Master Type \
 					and Master Name in account master." %(self.doc.debit_to, self.doc.customer,self.doc.company), raise_exception=1)
+			
+
+	def validate_customer(self):
+		"""	Validate customer name with SO and DN"""
+		if self.doc.customer:
+			for d in getlist(self.doclist,'entries'):
+				dt = d.delivery_note and 'Delivery Note' or d.sales_order and 'Sales Order' or ''
+				if dt:
+					dt_no = d.delivery_note or d.sales_order
+					cust = webnotes.conn.get_value(dt, dt_no, "customer")
+					if cust and cstr(cust) != cstr(self.doc.customer):
+						msgprint("Customer %s does not match with customer of %s: %s." 
+							%(self.doc.customer, dt, dt_no), raise_exception=1)
 
 
 	def validate_debit_acc(self):
diff --git a/accounts/report/customer_account_head/__init__.py b/accounts/report/customer_account_head/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/accounts/report/customer_account_head/__init__.py
diff --git a/accounts/report/customer_account_head/customer_account_head.py b/accounts/report/customer_account_head/customer_account_head.py
new file mode 100644
index 0000000..61f8cb2
--- /dev/null
+++ b/accounts/report/customer_account_head/customer_account_head.py
@@ -0,0 +1,49 @@
+# ERPNext - web based ERP (http://erpnext.com)
+# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import unicode_literals
+import webnotes
+
+def execute(filters=None):
+	account_map = get_account_map()
+	columns = get_columns(account_map)
+	data = []
+	customers = webnotes.conn.sql("select name from tabCustomer where docstatus < 2")
+	for cust in customers:
+		row = [cust[0]]
+		for company in sorted(account_map):
+			row.append(account_map[company].get(cust[0], ''))
+		data.append(row)
+
+	return columns, data
+
+def get_account_map():
+	accounts = webnotes.conn.sql("""select name, company, master_name 
+		from `tabAccount` where master_type = 'Customer' 
+		and ifnull(master_name, '') != '' and docstatus < 2""", as_dict=1)
+
+	account_map = {}
+	for acc in accounts:
+		account_map.setdefault(acc.company, {}).setdefault(acc.master_name, {})
+		account_map[acc.company][acc.master_name] = acc.name
+
+	return account_map
+
+def get_columns(account_map):
+	columns = ["Customer:Link/Customer:120"] + \
+		[(company + ":Link/Account:120") for company in sorted(account_map)]
+
+	return columns
\ No newline at end of file
diff --git a/accounts/report/customer_account_head/customer_account_head.txt b/accounts/report/customer_account_head/customer_account_head.txt
new file mode 100644
index 0000000..d258fac
--- /dev/null
+++ b/accounts/report/customer_account_head/customer_account_head.txt
@@ -0,0 +1,21 @@
+[
+ {
+  "creation": "2013-06-03 16:17:34", 
+  "docstatus": 0, 
+  "modified": "2013-06-03 16:17:34", 
+  "modified_by": "Administrator", 
+  "owner": "Administrator"
+ }, 
+ {
+  "doctype": "Report", 
+  "is_standard": "Yes", 
+  "name": "__common__", 
+  "ref_doctype": "Account", 
+  "report_name": "Customer Account Head", 
+  "report_type": "Script Report"
+ }, 
+ {
+  "doctype": "Report", 
+  "name": "Customer Account Head"
+ }
+]
\ No newline at end of file
diff --git a/accounts/utils.py b/accounts/utils.py
index 382a337..31e6221 100644
--- a/accounts/utils.py
+++ b/accounts/utils.py
@@ -273,36 +273,45 @@
 			jv = webnotes.bean([
 				{
 					"doctype": "Journal Voucher",
-					"naming_series": "_PATCH-",
+					"naming_series": "JV-AUTO-",
 					"company": company,
 					"posting_date": today,
 					"fiscal_year": fiscal_year,
 					"voucher_type": "Journal Entry",
-					"user_remark": "Accounting Entry for Stock: \
-						Initial booking of stock received but not billed account"
+					"user_remark": (_("Auto Inventory Accounting") + ": " +
+						(_("Disabled") if reverse else _("Enabled")) + ". " +
+						_("Journal Entry for inventory that is received but not yet invoiced"))
 				},
 				{
 					"doctype": "Journal Voucher Detail",
 					"parentfield": "entries",
 					"account": get_company_default(company, "stock_received_but_not_billed"),
-					(stock_rbnb_value > 0 and "credit" or "debit"): abs(stock_rbnb_value)
+						(stock_rbnb_value > 0 and "credit" or "debit"): abs(stock_rbnb_value)
 				},
 				{
 					"doctype": "Journal Voucher Detail",
 					"parentfield": "entries",
 					"account": get_company_default(company, "stock_adjustment_account"),
-					(stock_rbnb_value > 0 and "debit" or "credit"): abs(stock_rbnb_value),
+						(stock_rbnb_value > 0 and "debit" or "credit"): abs(stock_rbnb_value),
 					"cost_center": get_company_default(company, "stock_adjustment_cost_center")
 				},
 			])
 			jv.insert()
-			jv.submit()
 			
 			jv_list.append(jv.doc.name)
 	
 	if jv_list:
-		webnotes.msgprint("""Folowing Journal Vouchers has been created automatically: 
-			%s""" % '\n'.join(jv_list))
+		msgprint(_("Following Journal Vouchers have been created automatically") + \
+			":\n%s" % ("\n".join([("<a href=\"#Form/Journal Voucher/%s\">%s</a>" % (jv, jv)) for jv in jv_list]),))
+		
+		msgprint(_("""These adjustment vouchers book the difference between \
+			the total value of received items and the total value of invoiced items, \
+			as a required step to use Auto Inventory Accounting.
+			This is an approximation to get you started.
+			You will need to submit these vouchers after checking if the values are correct.
+			For more details, read: \
+			<a href="http://erpnext.com/auto-inventory-accounting" target="_blank">\
+			Auto Inventory Accounting</a>"""))
 			
 	webnotes.msgprint("""Please refresh the system to get effect of Auto Inventory Accounting""")
 			
diff --git a/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/manufacturing/doctype/production_planning_tool/production_planning_tool.py
index 1686478..d4e41ac 100644
--- a/manufacturing/doctype/production_planning_tool/production_planning_tool.py
+++ b/manufacturing/doctype/production_planning_tool/production_planning_tool.py
@@ -317,9 +317,9 @@
 		
 		items_to_be_requested = webnotes._dict()
 		for item in self.item_dict:
-			if flt(self.item_dict[item][0]) > item_projected_qty[item]:
+			if flt(self.item_dict[item][0]) > item_projected_qty.get(item, 0):
 				# shortage
-				requested_qty = flt(self.item_dict[item][0]) - item_projected_qty[item]
+				requested_qty = flt(self.item_dict[item][0]) - item_projected_qty.get(item, 0)
 				# comsider minimum order qty
 				requested_qty = requested_qty > flt(self.item_dict[item][3]) and \
 					requested_qty or flt(self.item_dict[item][3])
@@ -379,4 +379,4 @@
 				webnotes.msgprint("Following Material Request created successfully: \n%s" % 
 					"\n".join(pur_req))
 		else:
-			webnotes.msgprint("Nothing to request")
\ No newline at end of file
+			webnotes.msgprint("Nothing to request")
diff --git a/patches/april_2013/p06_update_file_size.py b/patches/april_2013/p06_update_file_size.py
index 8709c7b..760c3cb 100644
--- a/patches/april_2013/p06_update_file_size.py
+++ b/patches/april_2013/p06_update_file_size.py
@@ -2,11 +2,13 @@
 
 def execute():
 	files_path = webnotes.utils.get_path("public", "files")
+	webnotes.conn.auto_commit_on_many_writes = 1
+
 	for f in webnotes.conn.sql("""select name, file_name from 
 		`tabFile Data`""", as_dict=True):
 		if f.file_name:
 			filepath = os.path.join(files_path, f.file_name)
 			if os.path.exists(filepath):
 				webnotes.conn.set_value("File Data", f.name, "file_size", os.stat(filepath).st_size)
-			
-		
\ No newline at end of file
+				
+	webnotes.conn.auto_commit_on_many_writes = 0
\ No newline at end of file
diff --git a/patches/april_2013/p07_update_file_data_2.py b/patches/april_2013/p07_update_file_data_2.py
index 0cb44d0..548ba6c 100644
--- a/patches/april_2013/p07_update_file_data_2.py
+++ b/patches/april_2013/p07_update_file_data_2.py
@@ -2,6 +2,8 @@
 def execute():
 	from patches.april_2013.p05_update_file_data import update_file_list, get_single_doctypes
 	
+	webnotes.conn.auto_commit_on_many_writes = 1
+	
 	singles = get_single_doctypes()
 	for doctype in webnotes.conn.sql_list("""select table_name from `information_schema`.`columns`
 		where table_schema=%s and column_name='file_list'""", webnotes.conn.cur_db_name):
@@ -13,4 +15,5 @@
 			
 			webnotes.conn.sql("""delete from `tabCustom Field` where fieldname='file_list'
 				and parent=%s""", doctype)
-	
\ No newline at end of file
+	
+	webnotes.conn.auto_commit_on_many_writes = 0
\ No newline at end of file
diff --git a/setup/doctype/naming_series/naming_series.py b/setup/doctype/naming_series/naming_series.py
index 3a6b36d..eb293f2 100644
--- a/setup/doctype/naming_series/naming_series.py
+++ b/setup/doctype/naming_series/naming_series.py
@@ -123,16 +123,9 @@
 			
 	def validate_series_name(self, n):
 		import re
-		if "." in n:
-			parts = n.split(".")
-			if len(parts) > 2:
-				msgprint("Only one dot (.) allowed in " + n, raise_exception=1)
-			if not re.match("#+$", parts[-1]):
-				msgprint("Numbering series must be in hashes (e.g. ####)", raise_exception=1)
-			n = n[0]
-		if not re.match("^[a-zA-Z0-9-/]*$", n):
-			msgprint('Special Characters except "-" and "/" not allowed in naming series')
-			raise Exception
+		if not re.match("^[a-zA-Z0-9-/.#]*$", n):
+			msgprint('Special Characters except "-" and "/" not allowed in naming series',
+				raise_exception=True)
 		
 	def get_options(self, arg=''):
 		sr = webnotes.model.doctype.get_property(self.doc.select_doc_for_series, 
diff --git a/setup/page/setup/setup.js b/setup/page/setup/setup.js
index 1ebd730..788021a 100644
--- a/setup/page/setup/setup.js
+++ b/setup/page/setup/setup.js
@@ -73,7 +73,7 @@
 			{
 				"route":"Form/Naming Series/Naming Series",
 				doctype: "Naming Series",
-				label: wn._("Manage numbering series"),
+				label: wn._("Manage Numbering Series"),
 				"description":wn._("Set multiple numbering series for transactions")
 			},
 			{