Merge pull request #1290 from akhileshdarjee/price-list

Price List and Item Price : Valid for Buying and Selling as separate check box
diff --git a/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
index 7d81308..7d8a358 100644
--- a/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
+++ b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
@@ -12,7 +12,8 @@
 	
 	item_list = get_items(filters)
 	aii_account_map = get_aii_accounts()
-	item_tax, tax_accounts = get_tax_accounts(item_list, columns)
+	if item_list:
+		item_tax, tax_accounts = get_tax_accounts(item_list, columns)
 	
 	data = []
 	for d in item_list:
diff --git a/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/accounts/report/item_wise_sales_register/item_wise_sales_register.py
index dc5ecda..9f1fd87 100644
--- a/accounts/report/item_wise_sales_register/item_wise_sales_register.py
+++ b/accounts/report/item_wise_sales_register/item_wise_sales_register.py
@@ -11,7 +11,8 @@
 	last_col = len(columns)
 
 	item_list = get_items(filters)
-	item_tax, tax_accounts = get_tax_accounts(item_list, columns)
+	if item_list:
+		item_tax, tax_accounts = get_tax_accounts(item_list, columns)
 	
 	data = []
 	for d in item_list:
@@ -39,7 +40,6 @@
 		"Qty:Float:120", "Rate:Currency:120", "Amount:Currency:120"
 	]
 	
-	
 def get_conditions(filters):
 	conditions = ""
 	
diff --git a/config.json b/config.json
index 536e5af..d88d224 100644
--- a/config.json
+++ b/config.json
@@ -1,6 +1,6 @@
 {
  "app_name": "ERPNext", 
- "app_version": "3.4.6", 
+ "app_version": "3.4.9", 
  "base_template": "app/portal/templates/base.html", 
  "modules": {
   "Accounts": {
@@ -74,5 +74,5 @@
    "type": "module"
   }
  }, 
- "requires_framework_version": "==3.4.3"
+ "requires_framework_version": "==3.4.4"
 }
\ No newline at end of file
diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py
index 6660a93..a65bf26 100644
--- a/controllers/accounts_controller.py
+++ b/controllers/accounts_controller.py
@@ -387,34 +387,38 @@
 		
 		for item in self.doclist.get({"parentfield": "entries"}):
 			if item.fields.get(item_ref_dn):
-				already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s` 
-					where %s=%s and docstatus=1""" % (based_on, self.tname, item_ref_dn, '%s'), 
-					item.fields[item_ref_dn])[0][0]
-				
-				total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]), 
-					self.precision(based_on, item))
-				
 				ref_amt = flt(webnotes.conn.get_value(ref_dt + " Item", 
 					item.fields[item_ref_dn], based_on), self.precision(based_on, item))
+				if not ref_amt:
+					webnotes.msgprint(_("As amount for item") + ": " + item.item_code + _(" in ") + 
+						ref_dt + _(" is zero, system will not check for over-billed"))
+				else:
+					already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s` 
+						where %s=%s and docstatus=1 and parent != %s""" % 
+						(based_on, self.tname, item_ref_dn, '%s', '%s'), 
+						(item.fields[item_ref_dn], self.doc.name))[0][0]
 				
-				tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code, 
-					item_tolerance, global_tolerance)
-					
-				max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
+					total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]), 
+						self.precision(based_on, item))
 				
-				if total_billed_amt - max_allowed_amt > 0.01:
-					reduce_by = total_billed_amt - max_allowed_amt
+					tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code, 
+						item_tolerance, global_tolerance)
 					
-					webnotes.throw(_("Row #") + cstr(item.idx) + ": " + 
-						_(" Max amount allowed for Item ") + cstr(item.item_code) + 
-						_(" against ") + ref_dt + " " + 
-						cstr(item.fields[ref_dt.lower().replace(" ", "_")]) + _(" is ") + 
-						cstr(max_allowed_amt) + ". \n" + 
-						_("""If you want to increase your overflow tolerance, please increase \
-						tolerance % in Global Defaults or Item master. 				
-						Or, you must reduce the amount by """) + cstr(reduce_by) + "\n" + 
-						_("""Also, please check if the order item has already been billed \
-							in the Sales Order"""))
+					max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100)
+				
+					if total_billed_amt - max_allowed_amt > 0.01:
+						reduce_by = total_billed_amt - max_allowed_amt
+					
+						webnotes.throw(_("Row #") + cstr(item.idx) + ": " + 
+							_(" Max amount allowed for Item ") + cstr(item.item_code) + 
+							_(" against ") + ref_dt + " " + 
+							cstr(item.fields[ref_dt.lower().replace(" ", "_")]) + _(" is ") + 
+							cstr(max_allowed_amt) + ". \n" + 
+							_("""If you want to increase your overflow tolerance, please increase \
+							tolerance % in Global Defaults or Item master. 				
+							Or, you must reduce the amount by """) + cstr(reduce_by) + "\n" + 
+							_("""Also, please check if the order item has already been billed \
+								in the Sales Order"""))
 				
 	def get_company_default(self, fieldname):
 		from accounts.utils import get_company_default
diff --git a/install_erpnext.py b/install_erpnext.py
index c95a03d..e285d4b 100644
--- a/install_erpnext.py
+++ b/install_erpnext.py
@@ -5,6 +5,7 @@
 from __future__ import unicode_literals
 import os, sys
 import argparse
+import subprocess
 
 is_redhat = is_debian = None
 root_password = None
@@ -19,7 +20,7 @@
 	"jinja2", 
 	"markdown2", 
 	"markupsafe", 
-	"mysql-python", 
+	"mysql-python==1.2.4", 
 	"pygeoip", 
 	"python-dateutil", 
 	"python-memcached", 
@@ -80,7 +81,7 @@
 	return is_redhat, is_debian
 		
 def install_using_yum():
-	packages = "python python-setuptools gcc python-devel MySQL-python git memcached ntp vim-enhanced screen"
+	packages = "gcc MySQL-python git memcached ntp vim-enhanced screen"
 	
 	print "-"*80
 	print "Installing Packages: (This may take some time)"
@@ -88,7 +89,10 @@
 	print "-"*80
 	exec_in_shell("yum install -y %s" % packages)
 	
-	if not exec_in_shell("which mysql"):
+
+	try:
+		exec_in_shell("which mysql")
+	except subprocess.CalledProcessError:
 		packages = "mysql mysql-server mysql-devel"
 		print "Installing Packages:", packages
 		exec_in_shell("yum install -y %s" % packages)
@@ -101,26 +105,19 @@
 		exec_in_shell('mysqladmin -u root password "%s"' % (root_password,))
 		print "Root password set as", root_password
 	
-	# install htop
-	if not exec_in_shell("which htop"):
-		try:
-			exec_in_shell("cd /tmp && rpm -i --force http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm && yum install -y htop")
-		except:
-			pass
-	
 	update_config_for_redhat()
 	
 def update_config_for_redhat():
 	import re
 	
 	# set to autostart on startup
-	for service in ("mysqld", "memcached", "ntpd"):
+	for service in ("mysqld", "memcached"):
 		exec_in_shell("chkconfig --level 2345 %s on" % service)
 		exec_in_shell("service %s restart" % service)
 	
 def install_using_apt():
 	exec_in_shell("apt-get update")
-	packages = "python python-setuptools python-dev build-essential python-pip python-mysqldb git memcached ntp vim screen htop"
+	packages = "python python-setuptools python-dev build-essential python-mysqldb git memcached ntp vim screen htop"
 	print "-"*80
 	print "Installing Packages: (This may take some time)"
 	print packages
@@ -132,7 +129,9 @@
 	exec_in_shell("echo mysql-server mysql-server/root_password password %s | sudo debconf-set-selections" % root_password)
 	exec_in_shell("echo mysql-server mysql-server/root_password_again password %s | sudo debconf-set-selections" % root_password)
 	
-	if not exec_in_shell("which mysql"):
+	try:
+		exec_in_shell("which mysql")
+	except subprocess.CalledProcessError:
 		packages = "mysql-server libmysqlclient-dev"
 		print "Installing Packages:", packages
 		exec_in_shell("apt-get install -y %s" % packages)
@@ -140,7 +139,7 @@
 	update_config_for_debian()
 	
 def update_config_for_debian():
-	for service in ("mysql", "ntpd"):
+	for service in ("mysql",):
 		exec_in_shell("service %s restart" % service)
 	
 def install_python_modules():
@@ -148,13 +147,14 @@
 	print "Installing Python Modules: (This may take some time)"
 	print "-"*80
 	
-	if not exec_in_shell("which pip"):
-		exec_in_shell("easy_install pip")
+	try:
+		exec_in_shell("which pip2.7")	
+	except subprocess.CalledProcessError:
+		exec_in_shell("easy_install-2.7 pip")
 	
-	exec_in_shell("pip install --upgrade pip")
-	exec_in_shell("pip install --upgrade setuptools")
-	exec_in_shell("pip install --upgrade virtualenv")
-	exec_in_shell("pip install {}".format(' '.join(requirements)))
+	exec_in_shell("pip2.7 install --upgrade setuptools --no-use-wheel")
+	exec_in_shell("pip2.7 install --upgrade setuptools")
+	exec_in_shell("pip2.7 install {}".format(' '.join(requirements)))
 	
 def install_erpnext(install_path):
 	print
@@ -200,7 +200,7 @@
 	app = os.path.join(install_path, "app")
 	if not os.path.exists(app):
 		print "Cloning erpnext"
-		exec_in_shell("cd %s && git clone https://github.com/webnotes/erpnext.git app" % install_path)
+		exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/erpnext.git app" % install_path)
 		exec_in_shell("cd app && git config core.filemode false")
 		if not os.path.exists(app):
 			raise Exception, "Couldn't clone erpnext repository"
@@ -208,7 +208,7 @@
 	lib = os.path.join(install_path, "lib")
 	if not os.path.exists(lib):
 		print "Cloning wnframework"
-		exec_in_shell("cd %s && git clone https://github.com/webnotes/wnframework.git lib" % install_path)
+		exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/wnframework.git lib" % install_path)
 		exec_in_shell("cd lib && git config core.filemode false")
 		if not os.path.exists(lib):
 			raise Exception, "Couldn't clone wnframework repository"
@@ -243,28 +243,8 @@
 
 def exec_in_shell(cmd):
 	# using Popen instead of os.system - as recommended by python docs
-	from subprocess import Popen
-	import tempfile
-
-	with tempfile.TemporaryFile() as stdout:
-		with tempfile.TemporaryFile() as stderr:
-			p = Popen(cmd, shell=True, stdout=stdout, stderr=stderr)
-			p.wait()
-
-			stdout.seek(0)
-			out = stdout.read()
-			if out: out = out.decode('utf-8')
-
-			stderr.seek(0)
-			err = stderr.read()
-			if err: err = err.decode('utf-8')
-
-	if err and any((kw in err.lower() for kw in ["traceback", "error", "exception"])):
-		print out
-		raise Exception, err
-	else:
-		print "."
-
+	import subprocess
+	out = subprocess.check_output(cmd, shell=True)
 	return out
 
 def parse_args():