Merge branch 'develop' of https://github.com/frappe/erpnext into develop
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 7b1f135..a3264a4 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -180,10 +180,20 @@
 	get_items_from_open_material_requests: function() {
 		erpnext.utils.map_current_doc({
 			method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order_based_on_supplier",
+			args: {
+				supplier: this.frm.doc.supplier
+			},
+			source_doctype: "Material Request",
 			source_name: this.frm.doc.supplier,
+			target: this.frm,
+			setters: {
+				company: me.frm.doc.company
+			},
 			get_query_filters: {
 				docstatus: ["!=", 2],
-			}
+				supplier: this.frm.doc.supplier
+			},
+			get_query_method: "erpnext.stock.doctype.material_request.material_request.get_material_requests_based_on_supplier"
 		});
 	},
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index d82e128..4d83690 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -12,8 +12,8 @@
   "supplier",
   "get_items_from_open_material_requests",
   "supplier_name",
-  "company",
   "column_break1",
+  "company",
   "transaction_date",
   "schedule_date",
   "order_confirmation_no",
@@ -170,6 +170,7 @@
    "search_index": 1
   },
   {
+   "description": "Fetch items based on Default Supplier.",
    "depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))",
    "fieldname": "get_items_from_open_material_requests",
    "fieldtype": "Button",
diff --git a/erpnext/buying/doctype/supplier/supplier_dashboard.py b/erpnext/buying/doctype/supplier/supplier_dashboard.py
index 887a093..b3b294d 100644
--- a/erpnext/buying/doctype/supplier/supplier_dashboard.py
+++ b/erpnext/buying/doctype/supplier/supplier_dashboard.py
@@ -9,7 +9,8 @@
 		'heatmap_message': _('This is based on transactions against this Supplier. See timeline below for details'),
 		'fieldname': 'supplier',
 		'non_standard_fieldnames': {
-			'Payment Entry': 'party_name'
+			'Payment Entry': 'party_name',
+			'Bank Account': 'party'
 		},
 		'transactions': [
 			{
@@ -25,6 +26,10 @@
 				'items': ['Payment Entry']
 			},
 			{
+				'label': _('Bank'),
+				'items': ['Bank Account']
+			},
+			{
 				'label': _('Pricing'),
 				'items': ['Pricing Rule']
 			}
diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py
index 99c4c0e..ae8f3a2 100644
--- a/erpnext/education/doctype/student/student.py
+++ b/erpnext/education/doctype/student/student.py
@@ -25,6 +25,9 @@
 		if self.date_of_birth and getdate(self.date_of_birth) >= getdate(today()):
 			frappe.throw(_("Date of Birth cannot be greater than today."))
 
+		if self.date_of_birth and getdate(self.date_of_birth) >= getdate(self.joining_date):
+			frappe.throw(_("Date of Birth cannot be greater than Joining Date."))
+
 		if self.joining_date and self.date_of_leaving and getdate(self.joining_date) > getdate(self.date_of_leaving):
 			frappe.throw(_("Joining Date can not be greater than Leaving Date"))
 
diff --git a/erpnext/education/doctype/student_group/student_group.js b/erpnext/education/doctype/student_group/student_group.js
index 4165ce0..1372440 100644
--- a/erpnext/education/doctype/student_group/student_group.js
+++ b/erpnext/education/doctype/student_group/student_group.js
@@ -70,6 +70,16 @@
 	group_based_on: function(frm) {
 		if (frm.doc.group_based_on == "Batch") {
 			frm.doc.course = null;
+			frm.set_df_property('program', 'reqd', 1);
+			frm.set_df_property('course', 'reqd', 0);
+		}
+		else if (frm.doc.group_based_on == "Course") {
+			frm.set_df_property('program', 'reqd', 0);
+			frm.set_df_property('course', 'reqd', 1);
+		}
+		else if (frm.doc.group_based_on == "Activity") {
+			frm.set_df_property('program', 'reqd', 0);
+			frm.set_df_property('course', 'reqd', 0);
 		}
 	},
 
diff --git a/erpnext/education/doctype/student_leave_application/student_leave_application.py b/erpnext/education/doctype/student_leave_application/student_leave_application.py
index b3e71a2..410f0cc 100644
--- a/erpnext/education/doctype/student_leave_application/student_leave_application.py
+++ b/erpnext/education/doctype/student_leave_application/student_leave_application.py
@@ -7,9 +7,11 @@
 from frappe import _
 from frappe.utils import get_link_to_form
 from frappe.model.document import Document
+from frappe import throw, _
 
 class StudentLeaveApplication(Document):
 	def validate(self):
+		self.validate_dates()
 		self.validate_duplicate()
 
 	def validate_duplicate(self):
@@ -29,4 +31,8 @@
 		if data:
 			link = get_link_to_form("Student Leave Application", data[0].name)
 			frappe.throw(_("Leave application {0} already exists against the student {1}")
-				.format(link, self.student))
\ No newline at end of file
+				.format(link, self.student))
+
+	def validate_dates(self):
+		if self.to_date < self.from_date :
+			throw(_("To Date cannot be less than From Date"))
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project_user/project_user.json b/erpnext/projects/doctype/project_user/project_user.json
index f0a70dd..2f452cc 100644
--- a/erpnext/projects/doctype/project_user/project_user.json
+++ b/erpnext/projects/doctype/project_user/project_user.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "creation": "2016-03-25 02:52:19.283003",
  "doctype": "DocType",
  "editable_grid": 1,
@@ -46,6 +47,7 @@
    "fetch_from": "user.full_name",
    "fieldname": "full_name",
    "fieldtype": "Read Only",
+   "in_list_view": 1,
    "label": "Full Name"
   },
   {
@@ -55,7 +57,7 @@
    "label": "Welcome email sent"
   },
   {
-   "columns": 1,
+   "columns": 2,
    "default": "0",
    "fieldname": "view_attachments",
    "fieldtype": "Check",
@@ -74,7 +76,8 @@
   }
  ],
  "istable": 1,
- "modified": "2019-07-15 19:37:26.942294",
+ "links": [],
+ "modified": "2020-02-09 23:26:50.321417",
  "modified_by": "Administrator",
  "module": "Projects",
  "name": "Project User",
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 3f444f8..35dc842 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -514,9 +514,18 @@
 }
 
 erpnext.utils.map_current_doc = function(opts) {
-	if(opts.get_query_filters) {
-		opts.get_query = function() {
-			return {filters: opts.get_query_filters};
+	let query_args = {};
+	if (opts.get_query_filters) {
+		query_args.filters = opts.get_query_filters;
+	}
+
+	if (opts.get_query_method) {
+		query_args.query = opts.get_query_method;
+	}
+
+	if (query_args.filters || query_args.query) {
+		opts.get_query = () => {
+			return query_args;
 		}
 	}
 	var _map = function() {
@@ -582,7 +591,7 @@
 				"method": opts.method,
 				"source_names": opts.source_name,
 				"target_doc": cur_frm.doc,
-				'args': opts.args
+				"args": opts.args
 			},
 			callback: function(r) {
 				if(!r.exc) {
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 941f904..4542847 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -6,6 +6,7 @@
 
 from __future__ import unicode_literals
 import frappe
+import json
 
 from frappe.utils import cstr, flt, getdate, new_line_sep, nowdate, add_days
 from frappe import msgprint, _
@@ -329,17 +330,13 @@
 	return doclist
 
 @frappe.whitelist()
-def make_purchase_order_based_on_supplier(source_name, target_doc=None):
-	if target_doc:
-		if isinstance(target_doc, string_types):
-			import json
-			target_doc = frappe.get_doc(json.loads(target_doc))
-		target_doc.set("items", [])
+def make_purchase_order_based_on_supplier(source_name, target_doc=None, args=None):
+	mr = source_name
 
-	material_requests, supplier_items = get_material_requests_based_on_supplier(source_name)
+	supplier_items = get_items_based_on_default_supplier(args.get("supplier"))
 
 	def postprocess(source, target_doc):
-		target_doc.supplier = source_name
+		target_doc.supplier = args.get("supplier")
 		if getdate(target_doc.schedule_date) < getdate(nowdate()):
 			target_doc.schedule_date = None
 		target_doc.set("items", [d for d in target_doc.get("items")
@@ -347,44 +344,64 @@
 
 		set_missing_values(source, target_doc)
 
-	for mr in material_requests:
-		target_doc = get_mapped_doc("Material Request", mr, 	{
-			"Material Request": {
-				"doctype": "Purchase Order",
-			},
-			"Material Request Item": {
-				"doctype": "Purchase Order Item",
-				"field_map": [
-					["name", "material_request_item"],
-					["parent", "material_request"],
-					["uom", "stock_uom"],
-					["uom", "uom"]
-				],
-				"postprocess": update_item,
-				"condition": lambda doc: doc.ordered_qty < doc.qty
-			}
-		}, target_doc, postprocess)
+	target_doc = get_mapped_doc("Material Request", mr, {
+		"Material Request": {
+			"doctype": "Purchase Order",
+		},
+		"Material Request Item": {
+			"doctype": "Purchase Order Item",
+			"field_map": [
+				["name", "material_request_item"],
+				["parent", "material_request"],
+				["uom", "stock_uom"],
+				["uom", "uom"]
+			],
+			"postprocess": update_item,
+			"condition": lambda doc: doc.ordered_qty < doc.qty
+		}
+	}, target_doc, postprocess)
 
 	return target_doc
 
-def get_material_requests_based_on_supplier(supplier):
+@frappe.whitelist()
+def get_items_based_on_default_supplier(supplier):
 	supplier_items = [d.parent for d in frappe.db.get_all("Item Default",
-		{"default_supplier": supplier}, 'parent')]
+		{"default_supplier": supplier, "parenttype": "Item"}, 'parent')]
+
+	return supplier_items
+
+@frappe.whitelist()
+def get_material_requests_based_on_supplier(doctype, txt, searchfield, start, page_len, filters):
+	conditions = ""
+	if txt:
+		conditions += "and mr.name like '%%"+txt+"%%' "
+
+	if filters.get("transaction_date"):
+		date = filters.get("transaction_date")[1]
+		conditions += "and mr.transaction_date between '{0}' and '{1}' ".format(date[0], date[1])
+
+	supplier = filters.get("supplier")
+	supplier_items = get_items_based_on_default_supplier(supplier)
+
 	if not supplier_items:
 		frappe.throw(_("{0} is not the default supplier for any items.").format(supplier))
 
-	material_requests = frappe.db.sql_list("""select distinct mr.name
+	material_requests = frappe.db.sql("""select distinct mr.name, transaction_date,company
 		from `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
 		where mr.name = mr_item.parent
-			and mr_item.item_code in (%s)
+			and mr_item.item_code in ({0})
 			and mr.material_request_type = 'Purchase'
 			and mr.per_ordered < 99.99
 			and mr.docstatus = 1
 			and mr.status != 'Stopped'
-		order by mr_item.item_code ASC""" % ', '.join(['%s']*len(supplier_items)),
-		tuple(supplier_items))
+			and mr.company = '{1}'
+			{2}
+		order by mr_item.item_code ASC
+		limit {3} offset {4} """ \
+		.format(', '.join(['%s']*len(supplier_items)), filters.get("company"), conditions, page_len, start),
+		tuple(supplier_items), as_dict=1)
 
-	return material_requests, supplier_items
+	return material_requests
 
 def get_default_supplier_query(doctype, txt, searchfield, start, page_len, filters):
 	doc = frappe.get_doc("Material Request", filters.get("doc"))
diff --git a/package.json b/package.json
index 13fcc0f..1b2dc9e 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,21 @@
 {
-  "devdependencies": {
+  "name": "erpnext",
+  "description": "Open Source ERP System powered by the Frappe Framework",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/frappe/erpnext.git"
+  },
+  "homepage": "https://erpnext.com",
+  "author": "Frappe Technologies Pvt. Ltd.",
+  "license": "GPL-3.0",
+  "bugs": {
+    "url": "https://github.com/frappe/erpnext/issues"
+  },
+  "devDependencies": {
     "snyk": "^1.290.1"
   },
+  "dependencies": {
+  },
   "scripts": {
     "snyk-protect": "snyk protect",
     "prepare": "yarn run snyk-protect"