Merge pull request #3530 from anandpdoshi/anand-june-29

[fix] Item Variant Attribute autocomplete appearance. Fixes #3488, #3515, #3525
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.json b/erpnext/accounts/doctype/journal_entry/journal_entry.json
index 6eb395d..249fcc4 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.json
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.json
@@ -53,7 +53,7 @@
    "fieldname": "posting_date", 
    "fieldtype": "Date", 
    "in_filter": 1, 
-   "in_list_view": 1, 
+   "in_list_view": 0, 
    "label": "Posting Date", 
    "no_copy": 1, 
    "oldfieldname": "posting_date", 
@@ -445,7 +445,7 @@
  "icon": "icon-file-text", 
  "idx": 1, 
  "is_submittable": 1, 
- "modified": "2015-04-27 20:32:31.655580", 
+ "modified": "2015-06-29 15:28:12.529019", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Journal Entry", 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 3e16a31..d404851 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -224,3 +224,4 @@
 	else
 		cur_frm.pformat.print_heading = __("Purchase Invoice");
 }
+
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index e192e76..dcbc605 100755
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -926,12 +926,21 @@
    "no_copy": 1, 
    "permlevel": 0, 
    "print_hide": 1
+  }, 
+  {
+   "depends_on": "eval:doc.is_recurring==1", 
+   "fieldname": "recurring_print_format", 
+   "fieldtype": "Link", 
+   "label": "Recurring Print Format", 
+   "options": "Print Format", 
+   "permlevel": 0, 
+   "precision": ""
   }
  ], 
  "icon": "icon-file-text", 
  "idx": 1, 
  "is_submittable": 1, 
- "modified": "2015-06-16 16:46:47.308287", 
+ "modified": "2015-06-22 07:30:06.743438", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Purchase Invoice", 
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index b35fa8a..3bb9aa0 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -392,8 +392,6 @@
 	}
 }
 
-
-
 cur_frm.set_query("debit_to", function(doc) {
 	return{
 		filters: [
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index a021be4..045678d 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -1228,6 +1228,15 @@
    "read_only": 0
   }, 
   {
+   "depends_on": "eval:doc.is_recurring==1", 
+   "fieldname": "recurring_print_format", 
+   "fieldtype": "Link", 
+   "label": "Recurring Print Format", 
+   "options": "Print Format", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "against_income_account", 
    "fieldtype": "Small Text", 
    "hidden": 1, 
@@ -1244,7 +1253,7 @@
  "icon": "icon-file-text", 
  "idx": 1, 
  "is_submittable": 1, 
- "modified": "2015-06-16 16:45:06.618286", 
+ "modified": "2015-06-22 06:39:22.072544", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Invoice", 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index dc1dfa4..f65ba40 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -868,12 +868,21 @@
    "no_copy": 1, 
    "permlevel": 0, 
    "print_hide": 1
+  }, 
+  {
+   "depends_on": "eval:doc.is_recurring==1", 
+   "fieldname": "recurring_print_format", 
+   "fieldtype": "Link", 
+   "label": "Recurring Print Format", 
+   "options": "Print Format", 
+   "permlevel": 0, 
+   "precision": ""
   }
  ], 
  "icon": "icon-file-text", 
  "idx": 1, 
  "is_submittable": 1, 
- "modified": "2015-06-15 15:38:56.794601", 
+ "modified": "2015-06-22 07:30:36.259753", 
  "modified_by": "Administrator", 
  "module": "Buying", 
  "name": "Purchase Order", 
diff --git a/erpnext/controllers/recurring_document.py b/erpnext/controllers/recurring_document.py
index a46fa32..8c8af23 100644
--- a/erpnext/controllers/recurring_document.py
+++ b/erpnext/controllers/recurring_document.py
@@ -124,7 +124,7 @@
 	frappe.sendmail(new_rv.notification_email_address,
 		subject=  _("New {0}: #{1}").format(new_rv.doctype, new_rv.name),
 		message = _("Please find attached {0} #{1}").format(new_rv.doctype, new_rv.name),
-		attachments = [frappe.attach_print(new_rv.doctype, new_rv.name, file_name=new_rv.name)])
+		attachments = [frappe.attach_print(new_rv.doctype, new_rv.name, file_name=new_rv.name, print_format=new_rv.recurring_print_format)])
 
 def notify_errors(doc, doctype, party, owner):
 	from frappe.utils.user import get_system_managers
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index b523416..12de2e5 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -75,8 +75,7 @@
 		return frappe.db.get_value("Customer", {"lead_name": self.name})
 
 	def has_opportunity(self):
-		return frappe.db.get_value("Opportunity", {"lead": self.name, "docstatus": 1,
-			"status": ["!=", "Lost"]})
+		return frappe.db.get_value("Opportunity", {"lead": self.name, "status": ["!=", "Lost"]})
 
 @frappe.whitelist()
 def make_customer(source_name, target_doc=None):
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index ca0a6cb..91601a4 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -37,6 +37,16 @@
 		if(this.frm.fields_dict["items"]) {
 			this["items_remove"] = this.calculate_taxes_and_totals;
 		}
+		
+		if(this.frm.fields_dict["recurring_print_format"]) {
+			this.frm.set_query("recurring_print_format", function(doc) {
+				return{
+					filters: [
+						['Print Format', 'doc_type', '=', cur_frm.doctype],
+					]
+				}
+			});
+		}
 	},
 
 	onload_post_render: function() {
@@ -782,3 +792,5 @@
 	cur_frm.cscript.set_dynamic_labels();
 	cur_frm.cscript.calculate_taxes_and_totals();
 })
+
+
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 7ede9d4..7f0b386 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -183,5 +183,3 @@
 		cur_frm.email_doc(frappe.boot.notification_settings.sales_order_message);
 	}
 };
-
-;
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index ad62d57..59f54fb 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -1074,13 +1074,22 @@
    "no_copy": 1, 
    "permlevel": 0, 
    "print_hide": 1
+  }, 
+  {
+   "depends_on": "eval:doc.is_recurring==1", 
+   "fieldname": "recurring_print_format", 
+   "fieldtype": "Link", 
+   "label": "Recurring Print Format", 
+   "options": "Print Format", 
+   "permlevel": 0, 
+   "precision": ""
   }
  ], 
  "icon": "icon-file-text", 
  "idx": 1, 
  "is_submittable": 1, 
  "issingle": 0, 
- "modified": "2015-06-15 15:36:38.898462", 
+ "modified": "2015-06-22 07:29:24.379272", 
  "modified_by": "Administrator", 
  "module": "Selling", 
  "name": "Sales Order", 
diff --git a/erpnext/selling/page/sales_browser/sales_browser.js b/erpnext/selling/page/sales_browser/sales_browser.js
index 3b9e25a..98d34be 100644
--- a/erpnext/selling/page/sales_browser/sales_browser.js
+++ b/erpnext/selling/page/sales_browser/sales_browser.js
@@ -122,7 +122,7 @@
 
 		if(me.ctype == "Sales Person") {
 			fields.splice(-1, 0, {fieldtype:'Link', fieldname:'employee', label:__('Employee'),
-				options:'Employee', description: __("Please enter Employee Id of this sales parson")});
+				options:'Employee', description: __("Please enter Employee Id of this sales person")});
 		}
 
 		// the dialog
diff --git a/erpnext/setup/doctype/global_defaults/global_defaults.json b/erpnext/setup/doctype/global_defaults/global_defaults.json
index 777ae3b..c7330d0 100644
--- a/erpnext/setup/doctype/global_defaults/global_defaults.json
+++ b/erpnext/setup/doctype/global_defaults/global_defaults.json
@@ -66,20 +66,6 @@
    "label": "Disable Rounded Total", 
    "permlevel": 0, 
    "read_only": 0
-  }, 
-  {
-   "fieldname": "section_break_8", 
-   "fieldtype": "Section Break", 
-   "permlevel": 0, 
-   "precision": ""
-  }, 
-  {
-   "description": "For automatic exchange rates go to jsonrates.com and signup for an API key", 
-   "fieldname": "jsonrates_api_key", 
-   "fieldtype": "Data", 
-   "label": "jsonrates.com API Key", 
-   "permlevel": 0, 
-   "precision": ""
   }
  ], 
  "hide_toolbar": 0, 
@@ -87,7 +73,7 @@
  "idx": 1, 
  "in_create": 1, 
  "issingle": 1, 
- "modified": "2015-05-07 05:43:49.760061", 
+ "modified": "2015-06-30 03:00:26.420003", 
  "modified_by": "Administrator", 
  "module": "Setup", 
  "name": "Global Defaults", 
diff --git a/erpnext/setup/doctype/global_defaults/global_defaults.py b/erpnext/setup/doctype/global_defaults/global_defaults.py
index a3fa3a9..efdc875 100644
--- a/erpnext/setup/doctype/global_defaults/global_defaults.py
+++ b/erpnext/setup/doctype/global_defaults/global_defaults.py
@@ -17,7 +17,6 @@
 	'hide_currency_symbol':'hide_currency_symbol',
 	'account_url':'account_url',
 	'disable_rounded_total': 'disable_rounded_total',
-	'jsonrates_api_key': 'jsonrates_api_key'
 }
 
 from frappe.model.document import Document
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index cef6079..f661edb 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -60,20 +60,21 @@
 
 @frappe.whitelist()
 def get_exchange_rate(from_currency, to_currency):
-	jsonrates_api_key = frappe.conf.jsonrates_api_key or frappe.db.get_default("jsonrates_api_key")
-
-	if jsonrates_api_key:
+	try:
 		cache = frappe.cache()
 		key = "currency_exchange_rate:{0}:{1}".format(from_currency, to_currency)
 		value = cache.get(key)
 		if not value:
 			import requests
-			response = requests.get("http://jsonrates.com/get/?from={0}&to={1}&apiKey={2}".format(from_currency,
-				to_currency, jsonrates_api_key))
+			response = requests.get("http://api.fixer.io/latest", params={
+				"base": from_currency,
+				"symbols": to_currency
+			})
 			# expire in 24 hours
-			value = response.json().get("rate")
+			response.raise_for_status()
+			value = response.json()["rates"][to_currency]
 			cache.setex(key, value, 24 * 60 * 60)
 		return flt(value)
-	else:
+	except:
 		exchange = "%s-%s" % (from_currency, to_currency)
 		return flt(frappe.db.get_value("Currency Exchange", exchange, "exchange_rate"))
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index 60889c5..be74aeb 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -22,16 +22,21 @@
 			self.posting_time = now_datetime().strftime('%H:%M:%S')
 
 	def add_calendar_event(self, opts, force=False):
-		if self.contact_by != cstr(self._prev.contact_by) or \
-				self.contact_date != cstr(self._prev.contact_date) or force:
+		if cstr(self.contact_by) != cstr(self._prev.contact_by) or \
+				cstr(self.contact_date) != cstr(self._prev.contact_date) or force:
 
 			self.delete_events()
 			self._add_calendar_event(opts)
 
 	def delete_events(self):
-		frappe.delete_doc("Event", frappe.db.sql_list("""select name from `tabEvent`
-			where ref_type=%s and ref_name=%s""", (self.doctype, self.name)),
-			ignore_permissions=True)
+		events = frappe.db.sql_list("""select name from `tabEvent`
+			where ref_type=%s and ref_name=%s""", (self.doctype, self.name))
+		if events:
+			frappe.db.sql("delete from `tabEvent` where name in (%s)"
+				.format(", ".join(['%s']*len(events))), tuple(events))
+				
+			frappe.db.sql("delete from `tabEvent Role` where parent in (%s)"
+				.format(", ".join(['%s']*len(events))), tuple(events))
 
 	def _add_calendar_event(self, opts):
 		opts = frappe._dict(opts)