Merge pull request #4091 from rmehta/repack-allow-low-rate

[fix] remove validation to disallow lower rate
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index ff5b37c..33192bd 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -826,17 +826,20 @@
 	if account_currency != company_currency:
 		if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name:
 			exchange_rate = frappe.db.get_value(reference_type, reference_name, "conversion_rate")
-		elif account_details.account_type == "Bank" and \
+
+		elif account_details and account_details.account_type == "Bank" and \
 			((account_details.root_type == "Asset" and flt(credit) > 0) or
 				(account_details.root_type == "Liability" and debit)):
 			exchange_rate = get_average_exchange_rate(account)
 
-		if not exchange_rate:
+		if not exchange_rate and account_currency:
 			exchange_rate = get_exchange_rate(account_currency, company_currency)
+
 	else:
 		exchange_rate = 1
 
-	return exchange_rate
+	# don't return None or 0 as it is multipled with a value and that value could be lost
+	return exchange_rate or 1
 
 def get_average_exchange_rate(account):
 	exchange_rate = 0
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 7d40d85..a747510 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -93,6 +93,16 @@
 	"Issue": "erpnext.support.doctype.issue.issue.has_website_permission"
 }
 
+permission_query_conditions = {
+	"Contact": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_contact",
+	"Address": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_address"
+}
+
+has_permission = {
+	"Contact": "erpnext.utilities.address_and_contact.has_permission",
+	"Address": "erpnext.utilities.address_and_contact.has_permission"
+}
+
 dump_report_map = "erpnext.startup.report_data_map.data_map"
 
 before_tests = "erpnext.setup.utils.before_tests"
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 640a79e..1191c47 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -37,40 +37,3 @@
 	"Sales Partner": "Selling",
 	"Brand": "Selling"
 });
-
-frappe.desk_home_buttons.push({label:"<i class='icon-facetime-video'></i> "+ __("Learn"),
-	route:"Module/Learn"})
-
-frappe.desk_home_flows.push({
-		title: __("Selling"),
-		sequence: [
-			{title: __("Opportunity"), route:"List/Opportunity"},
-			{title: __("Quotation"), route:"List/Quotation"},
-			{title: __("Sales Order"), route:"List/Sales Order"},
-			{title: __("Delivery Note"), route:"List/Delivery Note"},
-			{title: __("Sales Invoice"), route:"List/Sales Invoice"},
-			{title: __("Payment"), route:"List/Journal Entry"},
-		]
-	});
-
-frappe.desk_home_flows.push({
-		title: __("Buying"),
-		sequence: [
-			{title: __("Material Request"), route:"List/Material Request"},
-			{title: __("Supplier Quotation"), route:"List/Supplier Quotation"},
-			{title: __("Purchase Order"), route:"List/Purchase Order"},
-			{title: __("Purchase Receipt"), route:"List/Purchase Receipt"},
-			{title: __("Purchase Invoice"), route:"List/Purchase Invoice"},
-			{title: __("Payment"), route:"List/Journal Entry"},
-		]
-	});
-
-frappe.desk_home_flows.push({
-		title: __("Manufacturing"),
-		sequence: [
-			{title: __("BOM"), route:"List/BOM"},
-			{title: __("Production Planning Tool"), route:"Form/Production Planning Tool"},
-			{title: __("Production Order"), route:"List/Production Order"},
-			{title: __("Stock Entry"), route:"List/Stock Entry"},
-		]
-	});
diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
index f8146d1..ddb8236 100644
--- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
+++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
@@ -286,7 +286,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 1, 
+   "print_hide": 0, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -309,7 +309,7 @@
    "options": "image", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -909,7 +909,7 @@
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 1, 
- "modified": "2015-08-27 03:30:49.875635", 
+ "modified": "2015-09-30 02:11:55.081524", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Stock Entry Detail", 
diff --git a/erpnext/utilities/address_and_contact.py b/erpnext/utilities/address_and_contact.py
index d386d67..9341adf 100644
--- a/erpnext/utilities/address_and_contact.py
+++ b/erpnext/utilities/address_and_contact.py
@@ -17,3 +17,68 @@
 		doc.get("__onload").contact_list = frappe.get_all("Contact",
 			fields="*", filters={key: doc.name},
 			order_by="is_primary_contact desc, modified desc")
+
+def has_permission(doc, ptype, user):
+	links = get_permitted_and_not_permitted_links(doc.doctype)
+	if not links.get("not_permitted_links"):
+		# optimization: don't determine permissions based on link fields
+		return True
+
+	# True if any one is True or all are empty
+	names = []
+	for df in (links.get("permitted_links") + links.get("not_permitted_links")):
+		doctype = df.options
+		name = doc.get(df.fieldname)
+
+		names.append(name)
+
+		if name and frappe.has_permission(doctype, ptype, doc=name):
+			return True
+
+	if not any(names):
+		return True
+
+	else:
+		return False
+
+def get_permission_query_conditions_for_contact(user):
+	return get_permission_query_conditions("Contact")
+
+def get_permission_query_conditions_for_address(user):
+	return get_permission_query_conditions("Address")
+
+def get_permission_query_conditions(doctype):
+	links = get_permitted_and_not_permitted_links(doctype)
+
+	if not links.get("not_permitted_links"):
+		# when everything is permitted, don't add additional condition
+		return ""
+
+	else:
+		conditions = []
+
+		for df in links.get("permitted_links"):
+			# like ifnull(customer, '')!='' or ifnull(supplier, '')!=''
+			conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')!=''".format(doctype=doctype, fieldname=df.fieldname))
+
+		return "( " + " or ".join(conditions) + " )"
+
+def get_permitted_and_not_permitted_links(doctype):
+	permitted_links = []
+	not_permitted_links = []
+
+	meta = frappe.get_meta(doctype)
+
+	for df in meta.get_link_fields():
+		if df.options not in ("Customer", "Supplier", "Sales Partner"):
+			continue
+
+		if frappe.has_permission(df.options):
+			permitted_links.append(df)
+		else:
+			not_permitted_links.append(df)
+
+	return {
+		"permitted_links": permitted_links,
+		"not_permitted_links": not_permitted_links
+	}