Merge branch 'staging-fixes' into gbm001-item-barcodes-pull
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index f19aaf8..8c7f3d8 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -335,7 +335,7 @@
 
 def validate_due_date(posting_date, due_date, party_type, party, company=None, bill_date=None, template_name=None):
 	if getdate(due_date) < getdate(posting_date):
-		frappe.throw(_("Due Date cannot be before Posting Date"))
+		frappe.throw(_("Due Date cannot be before Posting / Supplier Invoice Date"))
 	else:
 		if not template_name: return
 
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 51747f6..86ceb2e 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -57,6 +57,8 @@
 						_('{0} is blocked so this transaction cannot proceed'.format(supplier_name)), raise_exception=1)
 
 	def validate(self):
+
+		self.validate_qty_is_not_zero()
 		if self.get("_action") and self._action != "update_after_submit":
 			self.set_missing_values(for_validate=True)
 
@@ -179,7 +181,7 @@
 			validate_due_date(self.posting_date, self.due_date,
 				"Customer", self.customer, self.company, self.payment_terms_template)
 		elif self.doctype == "Purchase Invoice":
-			validate_due_date(self.posting_date, self.due_date,
+			validate_due_date(self.bill_date or self.posting_date, self.due_date,
 				"Supplier", self.supplier, self.company, self.bill_date, self.payment_terms_template)
 
 	def set_price_list_currency(self, buying_or_selling):
@@ -359,6 +361,11 @@
 
 		return gl_dict
 
+	def validate_qty_is_not_zero(self):
+		for item in self.items:
+			if not item.qty:
+				frappe.throw("Item quantity can not be zero")
+
 	def validate_account_currency(self, account, account_currency=None):
 		valid_currency = [self.company_currency]
 		if self.get("currency") and self.currency != self.company_currency:
@@ -405,7 +412,8 @@
 			if d.against_order:
 				allocated_amount = flt(d.amount)
 			else:
-				allocated_amount = min(self.grand_total - advance_allocated, d.amount)
+				amount = self.rounded_total or self.grand_total
+				allocated_amount = min(amount - advance_allocated, d.amount)
 			advance_allocated += flt(allocated_amount)
 
 			self.append("advances", {
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 719f4c7..7739592 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -41,6 +41,7 @@
 		self.validate_selling_price()
 		self.set_qty_as_per_stock_uom()
 		self.set_po_nos()
+		self.set_gross_profit()
 		set_default_income_account_for_item(self)
 
 	def set_missing_values(self, for_validate=False):
@@ -348,6 +349,12 @@
 				if po_nos and po_nos[0].get('po_no'):
 					self.po_no = ', '.join(list(set([d.po_no for d in po_nos if d.po_no])))
 
+	def set_gross_profit(self):
+		if self.doctype == "Sales Order":
+			for item in self.items:
+				item.gross_profit = flt(((item.base_rate - item.valuation_rate) * item.stock_qty), self.precision("amount", item))
+
+
 	def validate_items(self):
 		# validate items to see if they have is_sales_item enabled
 		from erpnext.controllers.buying_controller import validate_item_type
diff --git a/erpnext/education/doctype/fees/fees.json b/erpnext/education/doctype/fees/fees.json
index ac32717..2413967 100644
--- a/erpnext/education/doctype/fees/fees.json
+++ b/erpnext/education/doctype/fees/fees.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 0, 
@@ -999,39 +1000,6 @@
    "collapsible": 0, 
    "columns": 0, 
    "default": "0", 
-   "fieldname": "paid_amount", 
-   "fieldtype": "Currency", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Paid Amount", 
-   "length": 0, 
-   "no_copy": 1, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "0", 
    "fieldname": "outstanding_amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -1360,7 +1328,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-08-21 14:44:48.968839", 
+ "modified": "2018-11-26 20:42:14.467284", 
  "modified_by": "Administrator", 
  "module": "Education", 
  "name": "Fees", 
diff --git a/erpnext/education/doctype/fees/fees.py b/erpnext/education/doctype/fees/fees.py
index bfe6af4..aa616e6 100644
--- a/erpnext/education/doctype/fees/fees.py
+++ b/erpnext/education/doctype/fees/fees.py
@@ -112,7 +112,10 @@
 	user = frappe.session.user
 	student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user)
 	if student:
-		return frappe. db.sql('''select name, program, due_date, paid_amount, outstanding_amount, grand_total from `tabFees`
+		return frappe. db.sql('''
+			select name, program, due_date, grand_total - outstanding_amount as paid_amount,
+			outstanding_amount, grand_total, currency
+			from `tabFees`
 			where student= %s and docstatus=1
 			order by due_date asc limit {0} , {1}'''
 			.format(limit_start, limit_page_length), student, as_dict = True)
diff --git a/erpnext/hr/doctype/leave_application/leave_application_list.js b/erpnext/hr/doctype/leave_application/leave_application_list.js
index d7588da..f69b182 100644
--- a/erpnext/hr/doctype/leave_application/leave_application_list.js
+++ b/erpnext/hr/doctype/leave_application/leave_application_list.js
@@ -1,3 +1,10 @@
 frappe.listview_settings['Leave Application'] = {
-	add_fields: ["leave_type", "employee", "employee_name", "total_leave_days", "from_date", "to_date"]
+	add_fields: ["leave_type", "employee", "employee_name", "total_leave_days", "from_date", "to_date"],
+	get_indicator: function (doc) {
+		if (doc.status === "Approved") {
+			return [__("Approved"), "green", "status,=,Approved"];
+		} else if (doc.status === "Rejected") {
+			return [__("Rejected"), "red", "status,=,Rejected"];
+		}
+	}
 };
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.js b/erpnext/hr/doctype/salary_slip/salary_slip.js
index affbb55..86c50d0 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.js
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.js
@@ -177,7 +177,7 @@
 		if(cint(tbl[i].depends_on_lwp) == 1) {
 			tbl[i].amount =  Math.round(tbl[i].default_amount)*(flt(doc.payment_days) /
 				cint(doc.total_working_days)*100)/100;
-		} else if(reset_amount) {
+		} else if(reset_amount && tbl[i].default_amount) {
 			tbl[i].amount = tbl[i].default_amount;
 		}
 		if(!tbl[i].do_not_include_in_total) {
@@ -198,7 +198,7 @@
 	for(var i = 0; i < tbl.length; i++){
 		if(cint(tbl[i].depends_on_lwp) == 1) {
 			tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days)/cint(doc.total_working_days)*100)/100;
-		} else if(reset_amount) {
+		} else if(reset_amount && tbl[i].default_amount) {
 			tbl[i].amount = tbl[i].default_amount;
 		}
 		if(!tbl[i].do_not_include_in_total) {
diff --git a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py
index b80b0be..e88164f 100644
--- a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py
+++ b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.py
@@ -13,3 +13,11 @@
 def get_mins_between_operations():
 	return relativedelta(minutes=cint(frappe.db.get_single_value("Manufacturing Settings",
 		"mins_between_operations")) or 10)
+
+@frappe.whitelist()
+def is_material_consumption_enabled():
+	if not hasattr(frappe.local, 'material_consumption'):
+		frappe.local.material_consumption = cint(frappe.db.get_single_value('Manufacturing Settings',
+			'material_consumption'))
+
+	return frappe.local.material_consumption
\ No newline at end of file
diff --git a/erpnext/projects/doctype/task/task.js b/erpnext/projects/doctype/task/task.js
index b8f324a..c1a9c44 100644
--- a/erpnext/projects/doctype/task/task.js
+++ b/erpnext/projects/doctype/task/task.js
@@ -80,15 +80,15 @@
 		}
 	},
 
-	is_group: function(frm) {
+	is_group: function (frm) {
 		frappe.call({
-			method:"erpnext.projects.doctype.task.task.check_if_child_exists",
+			method: "erpnext.projects.doctype.task.task.check_if_child_exists",
 			args: {
 				name: frm.doc.name
 			},
-			callback: function(r){
-				if(r.message){
-					frappe.msgprint(__('Cannot convert it to non-group. Child Tasks exist.'));
+			callback: function (r) {
+				if (r.message.length > 0) {
+					frappe.msgprint(__(`Cannot convert it to non-group. The following child Tasks exist: ${r.message.join(", ")}.`));
 					frm.reload_doc();
 				}
 			}
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 3dc52d4..649d73a 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -2,12 +2,15 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe, json
 
-from frappe.utils import getdate, date_diff, add_days, cstr
+import json
+
+import frappe
 from frappe import _, throw
+from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate
 from frappe.utils.nestedset import NestedSet
 
+
 class CircularReferenceError(frappe.ValidationError): pass
 
 class Task(NestedSet):
@@ -157,8 +160,10 @@
 
 @frappe.whitelist()
 def check_if_child_exists(name):
-	return frappe.db.sql("""select name from `tabTask`
-		where parent_task = %s""", name)
+	child_tasks = frappe.get_all("Task", filters={"parent_task": name})
+	child_tasks = [get_link_to_form("Task", task.name) for task in child_tasks]
+	return child_tasks
+
 
 def get_project(doctype, txt, searchfield, start, page_len, filters):
 	from erpnext.controllers.queries import get_match_cond
@@ -237,4 +242,4 @@
 		new_task.insert()
 
 def on_doctype_update():
-	frappe.db.add_index("Task", ["lft", "rgt"])
\ No newline at end of file
+	frappe.db.add_index("Task", ["lft", "rgt"])
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 5f435ce..9a35aed 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -32,7 +32,6 @@
 
 	def validate(self):
 		super(SalesOrder, self).validate()
-
 		self.validate_order_type()
 		self.validate_delivery_date()
 		self.validate_proj_cust()
@@ -342,9 +341,11 @@
 
 			delivered_qty += item.delivered_qty
 			tot_qty += item.qty
-
-		self.db_set("per_delivered", flt(delivered_qty/tot_qty) * 100,
-			update_modified=False)
+		
+		if tot_qty != 0:
+			self.db_set("per_delivered", flt(delivered_qty/tot_qty) * 100,
+				update_modified=False)
+		
 
 	def set_indicator(self):
 		"""Set indicator for portal"""
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.js b/erpnext/selling/report/sales_analytics/sales_analytics.js
index 718f29c..7dc7c75 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.js
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.js
@@ -73,7 +73,8 @@
 			events: {
 				onCheckRow: function(data) {
 					row_name = data[2].content;
-					row_values = data.slice(4).map(function (column) {
+					length = data.length
+					row_values = data.slice(4,length-1).map(function (column) {
 						return column.content;
 					})
 					entry = {
@@ -102,12 +103,12 @@
 						labels: raw_data.labels,
 						datasets: new_datasets
 					}
-					
+
 					setTimeout(() => {
 						frappe.query_report.chart.update(new_data)
 					},200)
-					
-					
+
+
 					setTimeout(() => {
 						frappe.query_report.chart.draw(true);
 					}, 800)
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py
index 2cc2f70..8d99a9b 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.py
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.py
@@ -166,7 +166,7 @@
 		for entity, period_data in iteritems(self.entity_periodic_data):
 			row = {
 				"entity": entity,
-				"entity_name": self.entity_names.get(entity) 
+				"entity_name": self.entity_names.get(entity)
 			}
 			total = 0
 			for dummy, end_date in self.periodic_daterange:
@@ -177,7 +177,7 @@
 
 			row["total"] = total
 			self.data.append(row)
-	
+
 	def get_rows_by_group(self):
 		self.get_periodic_data()
 		out = []
@@ -185,7 +185,7 @@
 		for d in reversed(self.group_entries):
 			row = {
 				"entity": d.name,
-				"indent": self.depth_map.get(d.name) 
+				"indent": self.depth_map.get(d.name)
 			}
 			total = 0
 			for dummy, end_date in self.periodic_daterange:
@@ -275,7 +275,8 @@
 		self.parent_child_map = frappe._dict(frappe.db.sql(""" select name, supplier_group from `tabSupplier`"""))
 
 	def get_chart_data(self):
-		labels = [d.get("label") for d in self.columns[2:]]
+		length = len(self.columns)
+		labels = [d.get("label") for d in self.columns[2:length-1]]
 		self.chart = {
 			"data": {
 				'labels': labels,
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 0c58fb2..40bbc2c 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -363,7 +363,8 @@
 		for d in doc:
 			_rename_record(d)
 
-	for dt in ["Warehouse", "Account", "Cost Center"]:
+	for dt in ["Warehouse", "Account", "Cost Center", "Department", "Location",
+			"Sales Taxes and Charges Template", "Purchase Taxes and Charges Template"]:
 		_rename_records(dt)
 		frappe.db.commit()
 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index a26992a..ccd5f36 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -199,12 +199,15 @@
 	},
 
 	validate_purpose_consumption: function(frm) {
-		frappe.model.get_value('Manufacturing Settings', {'name': 'Manufacturing Settings'}, 'material_consumption', function(d) {
-			if (d.material_consumption==0 && frm.doc.purpose=="Material Consumption for Manufacture") {
+		frappe.call({
+			method: "erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings.is_material_consumption_enabled",
+		}).then(r => {
+			if (cint(r.message) == 0
+				&& frm.doc.purpose=="Material Consumption for Manufacture") {
 				frm.set_value("purpose", 'Manufacture');
 				frappe.throw(__('Material Consumption is not set in Manufacturing Settings.'));
 			}
-		})
+		});
 	},
 
 	company: function(frm) {
diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.js b/erpnext/stock/report/stock_analytics/stock_analytics.js
index 6010ea9..bebc84e 100644
--- a/erpnext/stock/report/stock_analytics/stock_analytics.js
+++ b/erpnext/stock/report/stock_analytics/stock_analytics.js
@@ -88,10 +88,9 @@
 			events: {
 				onCheckRow: function(data) {
 					row_name = data[2].content;
-					row_values = data.slice(6).map(function (column) {
+					row_values = data.slice(7).map(function (column) {
 						return column.content;
 					})
-
 					entry  = {
 						'name':row_name,
 						'values':row_values
@@ -118,12 +117,12 @@
 						labels: raw_data.labels,
 						datasets: new_datasets
 					}
-					
+
 					setTimeout(() => {
 						frappe.query_report.chart.update(new_data)
 					},200)
-					
-					
+
+
 					setTimeout(() => {
 						frappe.query_report.chart.draw(true);
 					}, 800)
diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.py b/erpnext/stock/report/stock_analytics/stock_analytics.py
index 5a8a672..dad8be1 100644
--- a/erpnext/stock/report/stock_analytics/stock_analytics.py
+++ b/erpnext/stock/report/stock_analytics/stock_analytics.py
@@ -167,13 +167,11 @@
 	return data
 
 def get_chart_data(columns):
-	labels = [d.get("label") for d in columns[4:]]
+	labels = [d.get("label") for d in columns[5:]]
 	chart = {
 		"data": {
 			'labels': labels,
-			'datasets':[
-				{ "values": ['0' for d in columns[4:]] }
-			]
+			'datasets':[]
 		}
 	}
 	chart["type"] = "line"
diff --git a/erpnext/templates/includes/fee/fee_row.html b/erpnext/templates/includes/fee/fee_row.html
index ac2b100..d5fd682 100644
--- a/erpnext/templates/includes/fee/fee_row.html
+++ b/erpnext/templates/includes/fee/fee_row.html
@@ -5,13 +5,13 @@
 				{{ doc.program }}
 			</div>
 			<div class="col-xs-2">
-				{{ doc.get_formatted("total_amount") }}
+				{{ frappe.utils.fmt_money(doc.grand_total, currency=doc.currency) }}
 			</div>
 			<div class="col-xs-2">
-				{{ doc.get_formatted("paid_amount") }}
+				{{ frappe.utils.fmt_money(doc.paid_amount, currency=doc.currency) }}
 			</div>
 			<div class="col-xs-2">
-				{{ doc.get_formatted("outstanding_amount") }}
+				{{ frappe.utils.fmt_money(doc.outstanding_amount, currency=doc.currency) }}
 			</div>
 		</div>
 	</a>