Merge remote-tracking branch 'upstream/develop' into club-mr-column
Merge remote-tracking branch 'upstream/develop' into club-mr-column
diff --git a/erpnext/accounts/doctype/item_tax_template/test_records.json b/erpnext/accounts/doctype/item_tax_template/test_records.json
index db540e8..4d9537d 100644
--- a/erpnext/accounts/doctype/item_tax_template/test_records.json
+++ b/erpnext/accounts/doctype/item_tax_template/test_records.json
@@ -2,6 +2,7 @@
  {
   "doctype": "Item Tax Template",
   "title": "_Test Account Excise Duty @ 10",
+  "company": "_Test Company",
   "taxes": [
    {
     "doctype": "Item Tax Template Detail",
@@ -14,6 +15,7 @@
  {
   "doctype": "Item Tax Template",
   "title": "_Test Account Excise Duty @ 12",
+  "company": "_Test Company",
   "taxes": [
    {
     "doctype": "Item Tax Template Detail",
@@ -26,6 +28,7 @@
  {
   "doctype": "Item Tax Template",
   "title": "_Test Account Excise Duty @ 15",
+  "company": "_Test Company",
   "taxes": [
    {
     "doctype": "Item Tax Template Detail",
@@ -38,6 +41,7 @@
  {
   "doctype": "Item Tax Template",
   "title": "_Test Account Excise Duty @ 20",
+  "company": "_Test Company",
   "taxes": [
    {
     "doctype": "Item Tax Template Detail",
@@ -50,6 +54,7 @@
  {
   "doctype": "Item Tax Template",
   "title": "_Test Item Tax Template 1",
+  "company": "_Test Company",
   "taxes": [
    {
     "doctype": "Item Tax Template Detail",
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 53115f9..ad98383 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -319,7 +319,9 @@
 	filtered_rules = []
 	for field in field_set:
 		if args.get(field):
-			filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules)
+			# filter function always returns a filter object even if empty
+			# list conversion is necessary to check for an empty result
+			filtered_rules = list(filter(lambda x: x.get(field)==args.get(field), pricing_rules))
 			if filtered_rules: break
 
 	return filtered_rules or pricing_rules
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
index 97aa922..5cd8e6f 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
@@ -1,4 +1,5 @@
 {
+ "actions": "",
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2016-02-25 01:24:07.224790",
@@ -28,7 +29,6 @@
   "letter_head",
   "more_info",
   "status",
-  "fiscal_year",
   "column_break3",
   "amended_from"
  ],
@@ -219,17 +219,6 @@
    "search_index": 1
   },
   {
-   "fieldname": "fiscal_year",
-   "fieldtype": "Link",
-   "label": "Fiscal Year",
-   "oldfieldname": "fiscal_year",
-   "oldfieldtype": "Select",
-   "options": "Fiscal Year",
-   "print_hide": 1,
-   "reqd": 1,
-   "search_index": 1
-  },
-  {
    "fieldname": "column_break3",
    "fieldtype": "Column Break"
   },
@@ -245,7 +234,8 @@
  ],
  "icon": "fa fa-shopping-cart",
  "is_submittable": 1,
- "modified": "2019-09-24 15:08:32.750661",
+ "links": [],
+ "modified": "2020-06-25 14:37:21.140194",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Request for Quotation",
diff --git a/erpnext/controllers/tests/test_mapper.py b/erpnext/controllers/tests/test_mapper.py
index 8839e00..66459fd 100644
--- a/erpnext/controllers/tests/test_mapper.py
+++ b/erpnext/controllers/tests/test_mapper.py
@@ -13,14 +13,12 @@
 		'''Test mapping of multiple source docs on a single target doc'''
 
 		make_test_records("Item")
-		items = frappe.get_all("Item", fields = ["name", "item_code"], filters = {'is_sales_item': 1, 'has_variants': 0, 'disabled': 0})
-		customers = frappe.get_all("Customer")
-		if items and customers:
-			# Make source docs (quotations) and a target doc (sales order)
-			customer = random.choice(customers).name
-			qtn1, item_list_1 = self.make_quotation(items, customer)
-			qtn2, item_list_2 = self.make_quotation(items, customer)
-			so, item_list_3 = self.make_sales_order()
+		items = ['_Test Item', '_Test Item 2', '_Test FG Item']
+
+		# Make source docs (quotations) and a target doc (sales order)
+		qtn1, item_list_1 = self.make_quotation(items, '_Test Customer')
+		qtn2, item_list_2 = self.make_quotation(items, '_Test Customer')
+		so, item_list_3 = self.make_sales_order()
 
 		# Map source docs to target with corresponding mapper method
 		method = "erpnext.selling.doctype.quotation.quotation.make_sales_order"
@@ -28,18 +26,12 @@
 
 		# Assert that all inserted items are present in updated sales order
 		src_items = item_list_1 + item_list_2 + item_list_3
-		self.assertEqual(set([d.item_code for d in src_items]),
+		self.assertEqual(set([d for d in src_items]),
 			set([d.item_code for d in updated_so.items]))
 
-	def get_random_items(self, items, limit):
-		'''Get a number of random items from a list of given items'''
-		random_items = []
-		for i in range(0, limit):
-			random_items.append(random.choice(items))
-		return random_items
 
-	def make_quotation(self, items, customer):
-		item_list = self.get_random_items(items, 3)
+	def make_quotation(self, item_list, customer):
+
 		qtn = frappe.get_doc({
 			"doctype": "Quotation",
 			"quotation_to": "Customer",
@@ -49,7 +41,7 @@
 			"valid_till" : add_months(nowdate(), 1)
 		})
 		for item in item_list:
-			qtn.append("items", {"qty": "2", "item_code": item.item_code})
+			qtn.append("items", {"qty": "2", "item_code": item})
 
 		qtn.submit()
 		return qtn, item_list
@@ -60,7 +52,7 @@
 			"base_rate": 100.0,
 			"description": "CPU",
 			"doctype": "Sales Order Item",
-			"item_code": "_Test Item Home Desktop 100",
+			"item_code": "_Test Item",
 			"item_name": "CPU",
 			"parentfield": "items",
 			"qty": 10.0,
@@ -72,4 +64,4 @@
 		})
 		so = frappe.get_doc(frappe.get_test_records('Sales Order')[0])
 		so.insert(ignore_permissions=True)
-		return so, [item]
+		return so, [item.item_code]
diff --git a/erpnext/controllers/tests/test_qty_based_taxes.py b/erpnext/controllers/tests/test_qty_based_taxes.py
index fd9936b..aaeac5d 100644
--- a/erpnext/controllers/tests/test_qty_based_taxes.py
+++ b/erpnext/controllers/tests/test_qty_based_taxes.py
@@ -30,6 +30,7 @@
         self.item_tax_template = frappe.get_doc({
             'doctype': 'Item Tax Template',
             'title': uuid4(),
+            'company': self.company.name,
             'taxes': [
                 {
                     'tax_type': self.account.name,
diff --git a/erpnext/projects/doctype/task/task.js b/erpnext/projects/doctype/task/task.js
index a044e1d..8c6a9cf 100644
--- a/erpnext/projects/doctype/task/task.js
+++ b/erpnext/projects/doctype/task/task.js
@@ -29,10 +29,16 @@
 				filters: filters
 			};
 		})
-	},
 
-	refresh: function (frm) {
-		frm.set_query("parent_task", { "is_group": 1 });
+		frm.set_query("parent_task", function () {
+			let filters = {
+				"is_group": 1
+			};
+			if (frm.doc.project) filters["project"] = frm.doc.project;
+			return {
+				filters: filters
+			}
+		});
 	},
 
 	is_group: function (frm) {
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 05ffa87..961b8c6 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -458,19 +458,23 @@
 
 @frappe.whitelist()
 def download_ewb_json():
-	data = frappe._dict(frappe.local.form_dict)
-
-	frappe.local.response.filecontent = json.dumps(data['data'], indent=4, sort_keys=True)
+	data = json.loads(frappe.local.form_dict.data)
+	frappe.local.response.filecontent = json.dumps(data, indent=4, sort_keys=True)
 	frappe.local.response.type = 'download'
 
-	billList = json.loads(data['data'])['billLists']
+	filename_prefix = 'Bulk'
+	docname = frappe.local.form_dict.docname
+	if docname:
+		if docname.startswith('['):
+			docname = json.loads(docname)
+			if len(docname) == 1:
+				docname = docname[0]
 
-	if len(billList) > 1:
-		doc_name = 'Bulk'
-	else:
-		doc_name = data['docname']
+		if not isinstance(docname, list):
+			# removes characters not allowed in a filename (https://stackoverflow.com/a/38766141/4767738)
+			filename_prefix = re.sub('[^\w_.)( -]', '', docname)
 
-	frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(doc_name, frappe.utils.random_string(5))
+	frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(filename_prefix, frappe.utils.random_string(5))
 
 @frappe.whitelist()
 def get_gstins_for_company(company):
diff --git a/erpnext/regional/report/datev/datev.js b/erpnext/regional/report/datev/datev.js
index d8638ab..55f12cf 100644
--- a/erpnext/regional/report/datev/datev.js
+++ b/erpnext/regional/report/datev/datev.js
@@ -30,7 +30,7 @@
 		}
 	],
 	onload: function(query_report) {
-		query_report.page.add_inner_button("Download DATEV Export", () => {
+		query_report.page.add_menu_item(__("Download DATEV File"), () => {
 			const filters = JSON.stringify(query_report.get_values());
 			window.open(`/api/method/erpnext.regional.report.datev.datev.download_datev_csv?filters=${filters}`);
 		});
diff --git a/erpnext/selling/doctype/sales_order/test_records.json b/erpnext/selling/doctype/sales_order/test_records.json
index 6cbd6c2..8a090e6 100644
--- a/erpnext/selling/doctype/sales_order/test_records.json
+++ b/erpnext/selling/doctype/sales_order/test_records.json
@@ -1,39 +1,39 @@
 [
  {
   "advance_paid": 0.0,
-  "company": "_Test Company", 
-  "conversion_rate": 1.0, 
-  "currency": "INR", 
-  "customer": "_Test Customer", 
-  "customer_group": "_Test Customer Group", 
-  "customer_name": "_Test Customer", 
-  "doctype": "Sales Order", 
-  "base_grand_total": 1000.0, 
-  "grand_total": 1000.0, 
-  "naming_series": "_T-Sales Order-", 
-  "order_type": "Sales", 
-  "plc_conversion_rate": 1.0, 
-  "price_list_currency": "INR", 
+  "company": "_Test Company",
+  "conversion_rate": 1.0,
+  "currency": "INR",
+  "customer": "_Test Customer",
+  "customer_group": "_Test Customer Group",
+  "customer_name": "_Test Customer",
+  "doctype": "Sales Order",
+  "base_grand_total": 1000.0,
+  "grand_total": 1000.0,
+  "naming_series": "_T-Sales Order-",
+  "order_type": "Sales",
+  "plc_conversion_rate": 1.0,
+  "price_list_currency": "INR",
   "items": [
    {
-    "base_amount": 1000.0, 
-    "base_rate": 100.0, 
-    "description": "CPU", 
-    "doctype": "Sales Order Item", 
-    "item_code": "_Test Item Home Desktop 100", 
-    "item_name": "CPU", 
-    "delivery_date": "2013-02-23", 
-    "parentfield": "items", 
-    "qty": 10.0, 
-    "rate": 100.0, 
+    "base_amount": 1000.0,
+    "base_rate": 100.0,
+    "description": "CPU",
+    "doctype": "Sales Order Item",
+    "item_code": "_Test Item",
+    "item_name": "_Test Item 1",
+    "delivery_date": "2013-02-23",
+    "parentfield": "items",
+    "qty": 10.0,
+    "rate": 100.0,
     "warehouse": "_Test Warehouse - _TC",
     "stock_uom": "_Test UOM",
 	"conversion_factor": 1.0,
 	"uom": "_Test UOM"
    }
-  ], 
-  "selling_price_list": "_Test Price List", 
-  "territory": "_Test Territory", 
+  ],
+  "selling_price_list": "_Test Price List",
+  "territory": "_Test Territory",
   "transaction_date": "2013-02-21"
  }
 ]
\ No newline at end of file
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 74ff0ec..aa9fbc0 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -29,12 +29,10 @@
 
 
 def check_setup_wizard_not_completed():
-	if frappe.db.get_default('desktop:home_page') == 'desktop':
-		print()
-		print("ERPNext can only be installed on a fresh site where the setup wizard is not completed")
-		print("You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall")
-		print()
-		return False
+	if frappe.db.get_default('desktop:home_page') != 'setup-wizard':
+		message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed. 
+You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall"""
+		frappe.throw(message)
 
 
 def set_single_defaults():
@@ -105,4 +103,3 @@
 		"ref_doctype": "Company"
 	})
 	settings.save()
-
diff --git a/erpnext/stock/doctype/item/test_records.json b/erpnext/stock/doctype/item/test_records.json
index 6c1a559..9ca887c 100644
--- a/erpnext/stock/doctype/item/test_records.json
+++ b/erpnext/stock/doctype/item/test_records.json
@@ -92,8 +92,7 @@
    {
     "doctype": "Item Tax",
     "parentfield": "taxes",
-    "item_tax_template": "_Test Account Excise Duty @ 10",
-    "tax_category": ""
+    "item_tax_template": "_Test Account Excise Duty @ 10"
    }
   ],
   "stock_uom": "_Test UOM 1"
@@ -371,8 +370,7 @@
    {
     "doctype": "Item Tax",
     "parentfield": "taxes",
-    "item_tax_template": "_Test Account Excise Duty @ 10",
-    "tax_category": ""
+    "item_tax_template": "_Test Account Excise Duty @ 10"
    },
    {
     "doctype": "Item Tax",
@@ -451,14 +449,13 @@
    {
     "doctype": "Item Tax",
     "parentfield": "taxes",
-    "item_tax_template": "_Test Account Excise Duty @ 20",
-    "tax_category": ""
+    "item_tax_template": "_Test Account Excise Duty @ 20"
    },
    {
     "doctype": "Item Tax",
     "parentfield": "taxes",
-    "item_tax_template": "_Test Item Tax Template 1",
-    "tax_category": "_Test Tax Category 1"
+    "tax_category": "_Test Tax Category 1",
+    "item_tax_template": "_Test Item Tax Template 1"
    }
   ]
  }
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 1f30f5a..b1a1614 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -638,7 +638,7 @@
 	if args.get('transaction_date'):
 		conditions += """ and %(transaction_date)s between
 			ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""
-		
+
 	if args.get('posting_date'):
 		conditions += """ and %(posting_date)s between
 			ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""
diff --git a/requirements.txt b/requirements.txt
index cfd0ab8..912d61f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,7 +2,7 @@
 frappe
 gocardless-pro==1.11.0
 googlemaps==3.1.1
-pandas==0.24.2
+pandas==1.0.5
 plaid-python==3.4.0
 pycountry==19.8.18
 PyGithub==1.44.1