Merge pull request #15371 from pratu16x7/marketplace-fixes

[hub] add Item Manager permission to Hub Tracked Item
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index e040b61..b7eb786 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -302,6 +302,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "allow_cost_center_in_entry_of_bs_account", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Allow Cost Center In Entry of Balance Sheet Account", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "print_settings", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -543,6 +574,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -575,6 +607,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -589,7 +622,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-02-21 16:47:38.043115", 
+ "modified": "2018-05-14 15:58:27.638576", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Accounts Settings", 
@@ -597,7 +630,6 @@
  "permissions": [
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 1, 
    "delete": 0, 
@@ -617,7 +649,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 0, 
    "delete": 0, 
@@ -637,7 +668,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 0, 
    "delete": 0, 
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
index 4f1570c..b834a5f 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
@@ -17,6 +17,7 @@
 	def validate(self):
 		self.validate_stale_days()
 		self.enable_payment_schedule_in_print()
+		self.enable_fields_for_cost_center_settings()
 
 	def validate_stale_days(self):
 		if not self.allow_stale and cint(self.stale_days) <= 0:
@@ -28,4 +29,9 @@
 		show_in_print = cint(self.show_payment_schedule_in_print)
 		for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"):
 			make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check")
-			make_property_setter(doctype, "payment_schedule", "print_hide",  0 if show_in_print else 1, "Check")
\ No newline at end of file
+			make_property_setter(doctype, "payment_schedule", "print_hide",  0 if show_in_print else 1, "Check")
+
+	def enable_fields_for_cost_center_settings(self):
+		show_field = 0 if cint(self.allow_cost_center_in_entry_of_bs_account) else 1
+		for doctype in ("Sales Invoice", "Purchase Invoice", "Payment Entry"):
+			make_property_setter(doctype, "cost_center", "hidden", show_field, "Check")
diff --git a/erpnext/accounts/doctype/cashier_closing/__init__.py b/erpnext/accounts/doctype/cashier_closing/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/cashier_closing/__init__.py
diff --git a/erpnext/accounts/doctype/cashier_closing/cashier_closing.js b/erpnext/accounts/doctype/cashier_closing/cashier_closing.js
new file mode 100644
index 0000000..ce791e4
--- /dev/null
+++ b/erpnext/accounts/doctype/cashier_closing/cashier_closing.js
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+// License: GNU General Public License v3. See license.txt
+
+frappe.ui.form.on('Cashier Closing', {
+
+	setup: function(frm){
+		if (frm.doc.user == "" || frm.doc.user == null) {
+			frm.doc.user = frappe.session.user;
+		}
+	}
+});
diff --git a/erpnext/accounts/doctype/cashier_closing/cashier_closing.json b/erpnext/accounts/doctype/cashier_closing/cashier_closing.json
new file mode 100644
index 0000000..57a9c7a
--- /dev/null
+++ b/erpnext/accounts/doctype/cashier_closing/cashier_closing.json
@@ -0,0 +1,403 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "autoname": "naming_series:", 
+ "beta": 0, 
+ "creation": "2018-06-18 16:51:49.994750", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "Cashier-closing-", 
+   "fieldname": "naming_series", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 1, 
+   "in_list_view": 0, 
+   "in_standard_filter": 1, 
+   "label": "Series", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Cashier-closing-\n", 
+   "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, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "user", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 1, 
+   "label": "User", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "User", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "Today", 
+   "fieldname": "date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 1, 
+   "label": "Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "from_time", 
+   "fieldtype": "Time", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 1, 
+   "label": "From Time", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "", 
+   "fieldname": "time", 
+   "fieldtype": "Time", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 1, 
+   "label": "To Time", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "0.00", 
+   "fieldname": "expense", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Expense", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "2", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "0.00", 
+   "fieldname": "custody", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Custody", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "2", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "0.00", 
+   "fieldname": "outstanding_amount", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Outstanding Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "2", 
+   "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, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "0.0", 
+   "fieldname": "payments", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Payments", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Cashier Closing Payments", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "net_amount", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 1, 
+   "label": "Net Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "amended_from", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Amended From", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "Cashier Closing", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "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, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 1, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2018-09-03 10:59:54.500567", 
+ "modified_by": "Administrator", 
+ "module": "Accounts", 
+ "name": "Cashier Closing", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 0, 
+   "apply_user_permissions": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "System Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 0, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/cashier_closing/cashier_closing.py b/erpnext/accounts/doctype/cashier_closing/cashier_closing.py
new file mode 100644
index 0000000..906bc7f
--- /dev/null
+++ b/erpnext/accounts/doctype/cashier_closing/cashier_closing.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from frappe.utils import cint, flt, cstr
+from frappe import _, msgprint, throw
+
+class CashierClosing(Document):
+	def validate(self):
+		self.validate_time()
+
+	def before_save(self):
+		self.get_outstanding()
+		self.make_calculations()
+
+	def get_outstanding(self):
+		values = frappe.db.sql("""
+			select sum(outstanding_amount)
+			from `tabSales Invoice`
+			where posting_date=%s and posting_time>=%s and posting_time<=%s and owner=%s
+		""", (self.date, self.from_time, self.time, self.user))
+		self.outstanding_amount = flt(values[0][0] if values else 0)
+			
+	def make_calculations(self):
+		total = 0.00
+		for i in self.payments:
+			total += flt(i.amount)
+
+		self.net_amount = total + self.outstanding_amount + self.expense - self.custody
+
+	def validate_time(self):
+		if self.from_time >= self.time:
+			frappe.throw(_("From Time Should Be Less Than To Time"))	
diff --git a/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.js b/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.js
new file mode 100644
index 0000000..a7fcc8d
--- /dev/null
+++ b/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Cashier Closing", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Cashier Closing
+		() => frappe.tests.make('Cashier Closing', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.py b/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.py
new file mode 100644
index 0000000..3c489a7
--- /dev/null
+++ b/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestCashierClosing(unittest.TestCase):
+	pass
diff --git a/erpnext/accounts/doctype/cashier_closing_payments/__init__.py b/erpnext/accounts/doctype/cashier_closing_payments/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/doctype/cashier_closing_payments/__init__.py
diff --git a/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.json b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.json
new file mode 100644
index 0000000..bdfc70f
--- /dev/null
+++ b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.json
@@ -0,0 +1,103 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-09-02 14:45:36.303520", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "mode_of_payment", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 1, 
+   "label": "Mode of Payment", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Mode of Payment", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "0.00", 
+   "fieldname": "amount", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "2", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2018-09-02 14:45:36.303520", 
+ "modified_by": "Administrator", 
+ "module": "Accounts", 
+ "name": "Cashier Closing Payments", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py
new file mode 100644
index 0000000..f737031
--- /dev/null
+++ b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class CashierClosingPayments(Document):
+	pass
diff --git a/erpnext/accounts/doctype/cost_center/test_cost_center.py b/erpnext/accounts/doctype/cost_center/test_cost_center.py
index dab5028..c4fad75 100644
--- a/erpnext/accounts/doctype/cost_center/test_cost_center.py
+++ b/erpnext/accounts/doctype/cost_center/test_cost_center.py
@@ -4,4 +4,23 @@
 
 
 import frappe
-test_records = frappe.get_test_records('Cost Center')
\ No newline at end of file
+test_records = frappe.get_test_records('Cost Center')
+
+
+
+def create_cost_center(**args):
+	args = frappe._dict(args)
+	if args.cost_center_name:
+		company = args.company or "_Test Company"
+		company_abbr = frappe.db.get_value("Company", company, "abbr")
+		cc_name = args.cost_center_name + " - " + company_abbr
+		if not frappe.db.exists("Cost Center", cc_name):
+			cc = frappe.new_doc("Cost Center")
+			cc.company = args.company or "_Test Company"
+			cc.cost_center_name = args.cost_center_name
+			cc.is_group = args.is_group or 0
+			cc.parent_cost_center = args.parent_cost_center or "_Test Company - _TC"
+			cc.insert()
+
+
+
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 47e214e..e6fe6ca 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -67,7 +67,8 @@
 				frappe.throw(_("{0} {1}: Cost Center is required for 'Profit and Loss' account {2}. Please set up a default Cost Center for the Company.")
 					.format(self.voucher_type, self.voucher_no, self.account))
 		else:
-			if self.cost_center:
+			from erpnext.accounts.utils import get_allow_cost_center_in_entry_of_bs_account
+			if not get_allow_cost_center_in_entry_of_bs_account() and self.cost_center:
 				self.cost_center = None
 			if self.project:
 				self.project = None
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js
index 6ad1df5..6aec6e9 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.js
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js
@@ -414,37 +414,18 @@
 				args: {
 					company: frm.doc.company,
 					party_type: d.party_type,
-					party: d.party
+					party: d.party,
+					cost_center: d.cost_center
 				}
 			});
 		}
 	},
+	cost_center: function(frm, dt, dn) {
+		erpnext.journal_entry.set_account_balance(frm, dt, dn);
+	},
 
 	account: function(frm, dt, dn) {
-		var d = locals[dt][dn];
-		if(d.account) {
-			if(!frm.doc.company) frappe.throw(__("Please select Company first"));
-			if(!frm.doc.posting_date) frappe.throw(__("Please select Posting Date first"));
-
-			return frappe.call({
-				method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_account_balance_and_party_type",
-				args: {
-					account: d.account,
-					date: frm.doc.posting_date,
-					company: frm.doc.company,
-					debit: flt(d.debit_in_account_currency),
-					credit: flt(d.credit_in_account_currency),
-					exchange_rate: d.exchange_rate
-				},
-				callback: function(r) {
-					if(r.message) {
-						$.extend(d, r.message);
-						erpnext.journal_entry.set_debit_credit_in_company_currency(frm, dt, dn);
-						refresh_field('accounts');
-					}
-				}
-			});
-		}
+		erpnext.journal_entry.set_account_balance(frm, dt, dn);
 	},
 	
 	debit_in_account_currency: function(frm, cdt, cdn) {
@@ -637,3 +618,33 @@
 		cur_frm.reload_doc();
 	}
 });
+
+$.extend(erpnext.journal_entry, {
+	set_account_balance: function(frm, dt, dn) {
+		var d = locals[dt][dn];
+		if(d.account) {
+			if(!frm.doc.company) frappe.throw(__("Please select Company first"));
+			if(!frm.doc.posting_date) frappe.throw(__("Please select Posting Date first"));
+
+			return frappe.call({
+				method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_account_balance_and_party_type",
+				args: {
+					account: d.account,
+					date: frm.doc.posting_date,
+					company: frm.doc.company,
+					debit: flt(d.debit_in_account_currency),
+					credit: flt(d.credit_in_account_currency),
+					exchange_rate: d.exchange_rate,
+					cost_center: d.cost_center
+				},
+				callback: function(r) {
+					if(r.message) {
+						$.extend(d, r.message);
+						erpnext.journal_entry.set_debit_credit_in_company_currency(frm, dt, dn);
+						refresh_field('accounts');
+					}
+				}
+			});
+		}
+	},
+});
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 84c165f..259172e 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -716,7 +716,7 @@
 
 
 def get_payment_entry(ref_doc, args):
-	cost_center = frappe.get_cached_value('Company',  ref_doc.company,  "cost_center")
+	cost_center = ref_doc.get("cost_center") or frappe.get_cached_value('Company',  ref_doc.company,  "cost_center")
 	exchange_rate = 1
 	if args.get("party_account"):
 		# Modified to include the posting date for which the exchange rate is required.
@@ -849,14 +849,14 @@
 		}
 
 @frappe.whitelist()
-def get_party_account_and_balance(company, party_type, party):
+def get_party_account_and_balance(company, party_type, party, cost_center=None):
 	if not frappe.has_permission("Account"):
 		frappe.msgprint(_("No Permission"), raise_exception=1)
 
 	account = get_party_account(party_type, party, company)
 
-	account_balance = get_balance_on(account=account)
-	party_balance = get_balance_on(party_type=party_type, party=party, company=company)
+	account_balance = get_balance_on(account=account, cost_center=cost_center)
+	party_balance = get_balance_on(party_type=party_type, party=party, company=company, cost_center=cost_center)
 
 	return {
 		"account": account,
@@ -867,7 +867,7 @@
 
 
 @frappe.whitelist()
-def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None):
+def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None, cost_center=None):
 	"""Returns dict of account balance and party type to be set in Journal Entry on selection of account."""
 	if not frappe.has_permission("Account"):
 		frappe.msgprint(_("No Permission"), raise_exception=1)
@@ -886,7 +886,7 @@
 		party_type = ""
 
 	grid_values = {
-		"balance": get_balance_on(account, date),
+		"balance": get_balance_on(account, date, cost_center=cost_center),
 		"party_type": party_type,
 		"account_type": account_details.account_type,
 		"account_currency": account_details.account_currency or company_currency,
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
index 5495c93..6996c77 100644
--- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
@@ -204,12 +204,72 @@
 		self.assertEqual(jv.inter_company_journal_entry_reference, "")
 		self.assertEqual(jv1.inter_company_journal_entry_reference, "")
 
+	def test_jv_for_enable_allow_cost_center_in_entry_of_bs_account(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center for BS Account - _TC"
+		create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
+		jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, cost_center = cost_center, save=False)
+		jv.voucher_type = "Bank Entry"
+		jv.multi_currency = 0
+		jv.cheque_no = "112233"
+		jv.cheque_date = nowdate()
+		jv.insert()
+		jv.submit()
+
+		expected_values = {
+			"_Test Cash - _TC": {
+				"cost_center": cost_center
+			},
+			"_Test Bank - _TC": {
+				"cost_center": cost_center
+			}
+		}
+
+		gl_entries = frappe.db.sql("""select account, cost_center, debit, credit
+			from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
+			order by account asc""", jv.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		for gle in gl_entries:
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+
+	def test_jv_account_and_party_balance_for_enable_allow_cost_center_in_entry_of_bs_account(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+		from erpnext.accounts.utils import get_balance_on
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center for BS Account - _TC"
+		create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
+		jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, cost_center = cost_center, save=False)
+		account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=cost_center)
+		jv.voucher_type = "Bank Entry"
+		jv.multi_currency = 0
+		jv.cheque_no = "112233"
+		jv.cheque_date = nowdate()
+		jv.insert()
+		jv.submit()
+
+		expected_account_balance = account_balance - 100
+		account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=cost_center)
+		self.assertEqual(expected_account_balance, account_balance)
+
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+
 def make_journal_entry(account1, account2, amount, cost_center=None, posting_date=None, exchange_rate=1, save=True, submit=False, project=None):
 	if not cost_center:
 		cost_center = "_Test Cost Center - _TC"
 
 	jv = frappe.new_doc("Journal Entry")
-	jv.posting_date = posting_date or "2013-02-14"
+	jv.posting_date = posting_date or nowdate()
 	jv.company = "_Test Company"
 	jv.user_remark = "test"
 	jv.multi_currency = 1
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 490f2b4..9215e5f 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -245,7 +245,8 @@
 					company: frm.doc.company,
 					party_type: frm.doc.party_type,
 					party: frm.doc.party,
-					date: frm.doc.posting_date
+					date: frm.doc.posting_date,
+					cost_center: frm.doc.cost_center
 				},
 				callback: function(r, rt) {
 					if(r.message) {
@@ -317,7 +318,8 @@
 				method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_account_details",
 				args: {
 					"account": account,
-					"date": frm.doc.posting_date
+					"date": frm.doc.posting_date,
+					"cost_center": frm.doc.cost_center
 				},
 				callback: function(r, rt) {
 					if(r.message) {
@@ -505,7 +507,8 @@
 					"party_type": frm.doc.party_type,
 					"payment_type": frm.doc.payment_type,
 					"party": frm.doc.party,
-					"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to
+					"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to,
+					"cost_center": frm.doc.cost_center
 				}
 			},
 			callback: function(r, rt) {
@@ -859,3 +862,38 @@
 		frm.events.set_unallocated_amount(frm);
 	}
 })
+frappe.ui.form.on('Payment Entry', {
+	cost_center: function(frm){
+		if (frm.doc.posting_date && (frm.doc.paid_from||frm.doc.paid_to)) {
+			return frappe.call({
+				method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_party_and_account_balance",
+				args: {
+					company: frm.doc.company,
+					date: frm.doc.posting_date,
+					paid_from: frm.doc.paid_from,
+					paid_to: frm.doc.paid_to,
+					ptype: frm.doc.party_type,
+					pty: frm.doc.party,
+					cost_center: frm.doc.cost_center
+				},
+				callback: function(r, rt) {
+					if(r.message) {
+						frappe.run_serially([
+							() => {
+								frm.set_value("paid_from_account_balance", r.message.paid_from_account_balance);
+								frm.set_value("paid_to_account_balance", r.message.paid_to_account_balance);
+								frm.set_value("party_balance", r.message.party_balance);
+							},
+							() => {
+								if(frm.doc.payment_type != "Internal") {
+									frm.events.get_outstanding_documents(frm);
+								}
+							}
+						]);
+
+					}
+				}
+			});
+		}
+	},
+})
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
index bffe669..daf2f2f 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.json
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -215,6 +215,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "cost_center", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Cost Center", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Cost Center", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "mode_of_payment", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -1906,7 +1939,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 15:44:28.647566", 
+ "modified": "2018-09-07 15:44:28.647566", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Payment Entry", 
@@ -1962,4 +1995,4 @@
  "track_changes": 1, 
  "track_seen": 0, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 9ce7ecb..6c814ad 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -127,12 +127,12 @@
 				self.party_account = party_account
 
 		if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance):
-			acc = get_account_details(self.paid_from, self.posting_date)
+			acc = get_account_details(self.paid_from, self.posting_date, self.cost_center)
 			self.paid_from_account_currency = acc.account_currency
 			self.paid_from_account_balance = acc.account_balance
 
 		if self.paid_to and not (self.paid_to_account_currency or self.paid_to_account_balance):
-			acc = get_account_details(self.paid_to, self.posting_date)
+			acc = get_account_details(self.paid_to, self.posting_date, self.cost_center)
 			self.paid_to_account_currency = acc.account_currency
 			self.paid_to_account_balance = acc.account_balance
 
@@ -419,7 +419,8 @@
 				"party_type": self.party_type,
 				"party": self.party,
 				"against": against_account,
-				"account_currency": self.party_account_currency
+				"account_currency": self.party_account_currency,
+				"cost_center": self.cost_center
 			})
 
 			dr_or_cr = "credit" if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit"
@@ -462,7 +463,8 @@
 					"account_currency": self.paid_from_account_currency,
 					"against": self.party if self.payment_type=="Pay" else self.paid_to,
 					"credit_in_account_currency": self.paid_amount,
-					"credit": self.base_paid_amount
+					"credit": self.base_paid_amount,
+					"cost_center": self.cost_center
 				})
 			)
 		if self.payment_type in ("Receive", "Internal Transfer"):
@@ -472,7 +474,8 @@
 					"account_currency": self.paid_to_account_currency,
 					"against": self.party if self.payment_type=="Receive" else self.paid_from,
 					"debit_in_account_currency": self.received_amount,
-					"debit": self.base_received_amount
+					"debit": self.base_received_amount,
+					"cost_center": self.cost_center
 				})
 			)
 
@@ -549,6 +552,10 @@
 		condition = " and voucher_type='{0}' and voucher_no='{1}'"\
 			.format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"]))
 
+	# Add cost center condition
+	if args.get("cost_center"):
+		condition += " and cost_center='%s'" % args.get("cost_center")
+
 	outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
 		args.get("party_account"), condition=condition)
 
@@ -573,7 +580,7 @@
 	return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
 
 
-def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency):
+def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency, cost_center=None):
 	if party_type == "Customer":
 		voucher_type = 'Sales Order'
 	elif party_type == "Supplier":
@@ -581,6 +588,12 @@
 	elif party_type == "Employee":
 		voucher_type = None
 
+	# Add cost center condition
+	doc = frappe.get_doc({"doctype": voucher_type})
+	condition = ""
+	if doc and hasattr(doc, 'cost_center'):
+		condition = " and cost_center='%s'" % cost_center
+
 	orders = []
 	if voucher_type:
 		ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
@@ -599,12 +612,14 @@
 				and ifnull(status, "") != "Closed"
 				and {ref_field} > advance_paid
 				and abs(100 - per_billed) > 0.01
+				{condition}
 			order by
 				transaction_date, name
 		""".format(**{
 			"ref_field": ref_field,
 			"voucher_type": voucher_type,
-			"party_type": scrub(party_type)
+			"party_type": scrub(party_type),
+			"condition": condition
 		}), party, as_dict=True)
 
 	order_list = []
@@ -616,7 +631,7 @@
 
 	return order_list
 
-def get_negative_outstanding_invoices(party_type, party, party_account, party_account_currency, company_currency):
+def get_negative_outstanding_invoices(party_type, party, party_account, party_account_currency, company_currency, cost_center=None):
 	voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
 	supplier_condition = ""
 	if voucher_type == "Purchase Invoice":
@@ -647,22 +662,23 @@
 			"grand_total_field": grand_total_field,
 			"voucher_type": voucher_type,
 			"party_type": scrub(party_type),
-			"party_account": "debit_to" if party_type == "Customer" else "credit_to"
+			"party_account": "debit_to" if party_type == "Customer" else "credit_to",
+			"cost_center": cost_center
 		}), (party, party_account), as_dict=True)
 
 
 @frappe.whitelist()
-def get_party_details(company, party_type, party, date):
+def get_party_details(company, party_type, party, date, cost_center=None):
 	if not frappe.db.exists(party_type, party):
 		frappe.throw(_("Invalid {0}: {1}").format(party_type, party))
 
 	party_account = get_party_account(party_type, party, company)
 
 	account_currency = get_account_currency(party_account)
-	account_balance = get_balance_on(party_account, date)
+	account_balance = get_balance_on(party_account, date, cost_center=cost_center)
 	_party_name = "title" if party_type == "Student" else party_type.lower() + "_name"
 	party_name = frappe.db.get_value(party_type, party, _party_name)
-	party_balance = get_balance_on(party_type=party_type, party=party)
+	party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center)
 
 	return {
 		"party_account": party_account,
@@ -674,11 +690,11 @@
 
 
 @frappe.whitelist()
-def get_account_details(account, date):
+def get_account_details(account, date, cost_center=None):
 	frappe.has_permission('Payment Entry', throw=True)
 	return frappe._dict({
 		"account_currency": get_account_currency(account),
-		"account_balance": get_balance_on(account, date),
+		"account_balance": get_balance_on(account, date, cost_center=cost_center),
 		"account_type": frappe.db.get_value("Account", account, "account_type")
 	})
 
@@ -855,6 +871,7 @@
 	pe = frappe.new_doc("Payment Entry")
 	pe.payment_type = payment_type
 	pe.company = doc.company
+	pe.cost_center = doc.get("cost_center")
 	pe.posting_date = nowdate()
 	pe.mode_of_payment = doc.get("mode_of_payment")
 	pe.party_type = party_type
@@ -912,4 +929,12 @@
 			and {dr_or_cr} > 0
 	""".format(dr_or_cr=dr_or_cr), (dt, dn, party_type, party, account, due_date))
 
-	return paid_amount[0][0] if paid_amount else 0
\ No newline at end of file
+	return paid_amount[0][0] if paid_amount else 0
+
+@frappe.whitelist()
+def get_party_and_account_balance(company, date, paid_from, paid_to=None, ptype=None, pty=None, cost_center=None):
+	return frappe._dict({
+		"party_balance": get_balance_on(party_type=ptype, party=pty, cost_center=cost_center),
+		"paid_from_account_balance": get_balance_on(paid_from, date, cost_center=cost_center),
+		"paid_to_account_balance": get_balance_on(paid_to, date=date, cost_center=cost_center)
+	})
diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
index 2408235..a7ab175 100644
--- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -8,8 +8,8 @@
 from frappe.utils import flt, nowdate
 from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
 from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, InvalidPaymentEntry
-from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
-from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
+from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice, create_sales_invoice_against_cost_center
+from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice, make_purchase_invoice_against_cost_center
 from erpnext.hr.doctype.expense_claim.test_expense_claim import make_expense_claim
 
 test_dependencies = ["Item"]
@@ -322,7 +322,7 @@
 
 		self.assertTrue(gl_entries)
 
-		for i, gle in enumerate(gl_entries):
+		for gle in gl_entries:
 			self.assertEqual(expected_gle[gle.account][0], gle.account)
 			self.assertEqual(expected_gle[gle.account][1], gle.debit)
 			self.assertEqual(expected_gle[gle.account][2], gle.credit)
@@ -394,3 +394,176 @@
 
 		outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
 		self.assertEqual(outstanding_amount, 0)
+
+	def test_payment_entry_against_sales_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center for BS Account - _TC"
+		create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
+
+		si =  create_sales_invoice_against_cost_center(cost_center=cost_center, debit_to="Debtors - _TC")
+
+		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
+		self.assertEqual(pe.cost_center, si.cost_center)
+
+		pe.reference_no = "112211-1"
+		pe.reference_date = nowdate()
+		pe.paid_to = "_Test Bank - _TC"
+		pe.paid_amount = si.grand_total
+		pe.insert()
+		pe.submit()
+
+		expected_values = {
+			"_Test Bank - _TC": {
+				"cost_center": cost_center
+			},
+			"Debtors - _TC": {
+				"cost_center": cost_center
+			}
+		}
+
+		gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
+			debit_in_account_currency, credit_in_account_currency
+			from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
+			order by account asc""", pe.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		for gle in gl_entries:
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+
+	def test_payment_entry_against_sales_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+		si =  create_sales_invoice(debit_to="Debtors - _TC")
+
+		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
+
+		pe.reference_no = "112211-2"
+		pe.reference_date = nowdate()
+		pe.paid_to = "_Test Bank - _TC"
+		pe.paid_amount = si.grand_total
+		pe.insert()
+		pe.submit()
+
+		gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
+			debit_in_account_currency, credit_in_account_currency
+			from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
+			order by account asc""", pe.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		for gle in gl_entries:
+			self.assertEqual(gle.cost_center, None)
+
+	def test_payment_entry_against_purchase_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center for BS Account - _TC"
+		create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
+
+		pi =  make_purchase_invoice_against_cost_center(cost_center=cost_center, credit_to="Creditors - _TC")
+
+		pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
+		self.assertEqual(pe.cost_center, pi.cost_center)
+
+		pe.reference_no = "112222-1"
+		pe.reference_date = nowdate()
+		pe.paid_from = "_Test Bank - _TC"
+		pe.paid_amount = pi.grand_total
+		pe.insert()
+		pe.submit()
+
+		expected_values = {
+			"_Test Bank - _TC": {
+				"cost_center": cost_center
+			},
+			"Creditors - _TC": {
+				"cost_center": cost_center
+			}
+		}
+
+		gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
+			debit_in_account_currency, credit_in_account_currency
+			from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
+			order by account asc""", pe.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		for gle in gl_entries:
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+
+	def test_payment_entry_against_purchase_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+		pi =  make_purchase_invoice(credit_to="Creditors - _TC")
+
+		pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
+
+		pe.reference_no = "112222-2"
+		pe.reference_date = nowdate()
+		pe.paid_from = "_Test Bank - _TC"
+		pe.paid_amount = pi.grand_total
+		pe.insert()
+		pe.submit()
+
+		gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
+			debit_in_account_currency, credit_in_account_currency
+			from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
+			order by account asc""", pe.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		for gle in gl_entries:
+			self.assertEqual(gle.cost_center, None)
+
+	def test_payment_entry_account_and_party_balance_for_enable_allow_cost_center_in_entry_of_bs_account(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+		from erpnext.accounts.utils import get_balance_on
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center for BS Account - _TC"
+		create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
+
+		si =  create_sales_invoice_against_cost_center(cost_center=cost_center, debit_to="Debtors - _TC")
+
+		account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=si.cost_center)
+		party_balance = get_balance_on(party_type="Customer", party=si.customer, cost_center=si.cost_center)
+		party_account_balance = get_balance_on(si.debit_to, cost_center=si.cost_center)
+
+		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
+		pe.reference_no = "112211-1"
+		pe.reference_date = nowdate()
+		pe.paid_to = "_Test Bank - _TC"
+		pe.paid_amount = si.grand_total
+		pe.insert()
+		pe.submit()
+
+		expected_account_balance = account_balance + si.grand_total
+		expected_party_balance = party_balance - si.grand_total
+		expected_party_account_balance = party_account_balance - si.grand_total
+
+		account_balance = get_balance_on(account=pe.paid_to, cost_center=pe.cost_center)
+		party_balance = get_balance_on(party_type="Customer", party=pe.party, cost_center=pe.cost_center)
+		party_account_balance = get_balance_on(account=pe.paid_from, cost_center=pe.cost_center)
+
+		self.assertEqual(pe.cost_center, si.cost_center)
+		self.assertEqual(expected_account_balance, account_balance)
+		self.assertEqual(expected_party_balance, party_balance)
+		self.assertEqual(expected_party_account_balance, party_account_balance)
+
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
diff --git a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json
index 83e3ba0..1b38904 100644
--- a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json
+++ b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json
@@ -15,6 +15,7 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -47,11 +48,12 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 2, 
-   "fetch_from": "payment_term.description",
+   "fetch_from": "", 
    "fieldname": "description", 
    "fieldtype": "Small Text", 
    "hidden": 0, 
@@ -80,6 +82,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -112,11 +115,12 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 2, 
-   "fetch_from": "payment_term.invoice_portion", 
+   "fetch_from": "", 
    "fieldname": "invoice_portion", 
    "fieldtype": "Percent", 
    "hidden": 0, 
@@ -145,6 +149,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -177,6 +182,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -218,7 +224,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-05-25 22:43:31.890251",
+ "modified": "2018-09-06 17:35:44.580209", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Payment Schedule", 
@@ -232,5 +238,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 7a1a182..2e82c01 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -525,4 +525,4 @@
 		}
 		frm.toggle_reqd("supplier_warehouse", frm.doc.is_subcontracted==="Yes");
 	}
-})
\ No newline at end of file
+})
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 2dd6e17..6c0ee8b 100755
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -386,6 +386,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "cost_center", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Cost Center", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Cost Center", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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": "Today", 
    "fieldname": "posting_date", 
    "fieldtype": "Date", 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 2660490..273a6e4 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -389,6 +389,7 @@
 						if self.party_account_currency==self.company_currency else grand_total,
 					"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
 					"against_voucher_type": self.doctype,
+					"cost_center": self.cost_center
 				}, self.party_account_currency)
 			)
 
@@ -472,7 +473,8 @@
 									"account": self.stock_received_but_not_billed,
 									"against": self.supplier,
 									"debit": flt(item.item_tax_amount, item.precision("item_tax_amount")),
-									"remarks": self.remarks or "Accounting Entry for Stock"
+									"remarks": self.remarks or "Accounting Entry for Stock",
+									"cost_center": self.cost_center
 								})
 							)
 
@@ -500,7 +502,8 @@
 						"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
 						"debit": base_asset_amount,
 						"debit_in_account_currency": (base_asset_amount
-							if asset_rbnb_currency == self.company_currency else asset_amount)
+							if asset_rbnb_currency == self.company_currency else asset_amount),
+						"cost_center": item.cost_center
 					}))
 
 					if item.item_tax_amount:
@@ -526,7 +529,8 @@
 						"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
 						"debit": base_asset_amount,
 						"debit_in_account_currency": (base_asset_amount
-							if cwip_account_currency == self.company_currency else asset_amount)
+							if cwip_account_currency == self.company_currency else asset_amount),
+						"cost_center": self.cost_center
 					}))
 
 					if item.item_tax_amount and not cint(erpnext.is_perpetual_inventory_enabled(self.company)):
@@ -626,6 +630,7 @@
 						if self.party_account_currency==self.company_currency else self.paid_amount,
 					"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
 					"against_voucher_type": self.doctype,
+					"cost_center": self.cost_center
 				}, self.party_account_currency)
 			)
 
@@ -635,7 +640,8 @@
 					"against": self.supplier,
 					"credit": self.base_paid_amount,
 					"credit_in_account_currency": self.base_paid_amount \
-						if bank_account_currency==self.company_currency else self.paid_amount
+						if bank_account_currency==self.company_currency else self.paid_amount,
+					"cost_center": self.cost_center
 				}, bank_account_currency)
 			)
 
@@ -656,6 +662,7 @@
 						if self.party_account_currency==self.company_currency else self.write_off_amount,
 					"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
 					"against_voucher_type": self.doctype,
+					"cost_center": self.cost_center
 				}, self.party_account_currency)
 			)
 			gl_entries.append(
@@ -665,7 +672,7 @@
 					"credit": flt(self.base_write_off_amount),
 					"credit_in_account_currency": self.base_write_off_amount \
 						if write_off_account_currency==self.company_currency else self.write_off_amount,
-					"cost_center": self.write_off_cost_center
+					"cost_center": self.cost_center or self.write_off_cost_center
 				})
 			)
 
@@ -680,7 +687,7 @@
 					"against": self.supplier,
 					"debit_in_account_currency": self.rounding_adjustment,
 					"debit": self.base_rounding_adjustment,
-					"cost_center": round_off_cost_center,
+					"cost_center": self.cost_center or round_off_cost_center,
 				}
 			))
 
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 8cf6b1a..c8c23c7 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -790,6 +790,66 @@
 		pi_doc = frappe.get_doc('Purchase Invoice', pi.name)
 		self.assertEqual(pi_doc.outstanding_amount, 0)
 
+	def test_purchase_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center for BS Account - _TC"
+		create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
+
+		pi =  make_purchase_invoice_against_cost_center(cost_center=cost_center, credit_to="Creditors - _TC")
+		self.assertEqual(pi.cost_center, cost_center)
+
+		expected_values = {
+			"Creditors - _TC": {
+				"cost_center": cost_center
+			},
+			"_Test Account Cost for Goods Sold - _TC": {
+				"cost_center": cost_center
+			}
+		}
+
+		gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
+			debit_in_account_currency, credit_in_account_currency
+			from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
+			order by account asc""", pi.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		for gle in gl_entries:
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+
+	def test_purchase_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+		cost_center = "_Test Cost Center - _TC"
+		pi =  make_purchase_invoice(credit_to="Creditors - _TC")
+
+		expected_values = {
+			"Creditors - _TC": {
+				"cost_center": None
+			},
+			"_Test Account Cost for Goods Sold - _TC": {
+				"cost_center": cost_center
+			}
+		}
+
+		gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
+			debit_in_account_currency, credit_in_account_currency
+			from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
+			order by account asc""", pi.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		for gle in gl_entries:
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+
 def unlink_payment_on_cancel_of_invoice(enable=1):
 	accounts_settings = frappe.get_doc("Accounts Settings")
 	accounts_settings.unlink_payment_on_cancellation_of_invoice = enable
@@ -839,4 +899,50 @@
 			pi.submit()
 	return pi
 
-test_records = frappe.get_test_records('Purchase Invoice')
\ No newline at end of file
+def make_purchase_invoice_against_cost_center(**args):
+	pi = frappe.new_doc("Purchase Invoice")
+	args = frappe._dict(args)
+	pi.posting_date = args.posting_date or today()
+	if args.posting_time:
+		pi.posting_time = args.posting_time
+	if args.update_stock:
+		pi.update_stock = 1
+	if args.is_paid:
+		pi.is_paid = 1
+
+	if args.cash_bank_account:
+		pi.cash_bank_account=args.cash_bank_account
+
+	pi.company = args.company or "_Test Company"
+	pi.cost_center = args.cost_center or "_Test Cost Center - _TC"
+	pi.supplier = args.supplier or "_Test Supplier"
+	pi.currency = args.currency or "INR"
+	pi.conversion_rate = args.conversion_rate or 1
+	pi.is_return = args.is_return
+	pi.is_return = args.is_return
+	pi.credit_to = args.return_against or "Creditors - _TC"
+	pi.is_subcontracted = args.is_subcontracted or "No"
+	pi.supplier_warehouse = "_Test Warehouse 1 - _TC"
+
+	pi.append("items", {
+		"item_code": args.item or args.item_code or "_Test Item",
+		"warehouse": args.warehouse or "_Test Warehouse - _TC",
+		"qty": args.qty or 5,
+		"received_qty": args.received_qty or 0,
+		"rejected_qty": args.rejected_qty or 0,
+		"rate": args.rate or 50,
+		"conversion_factor": 1.0,
+		"serial_no": args.serial_no,
+		"stock_uom": "_Test UOM",
+		"cost_center": args.cost_center or "_Test Cost Center - _TC",
+		"project": args.project,
+		"rejected_warehouse": args.rejected_warehouse or "",
+		"rejected_serial_no": args.rejected_serial_no or ""
+	})
+	if not args.do_not_save:
+		pi.insert()
+		if not args.do_not_submit:
+			pi.submit()
+	return pi
+
+test_records = frappe.get_test_records('Purchase Invoice')
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index dc201b0..b2044ab 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -6,7 +6,6 @@
 
 {% include 'erpnext/selling/sales_common.js' %};
 
-cur_frm.add_fetch('customer', 'tax_id', 'tax_id');
 
 frappe.provide("erpnext.accounts");
 erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.extend({
@@ -16,7 +15,7 @@
 	},
 	onload: function() {
 		var me = this;
-		this._super();		
+		this._super();
 
 		if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
 			// show debit_to in print format
@@ -466,7 +465,7 @@
 	}
 }
 
-//project name
+// project name
 //--------------------------
 cur_frm.fields_dict['project'].get_query = function(doc, cdt, cdn) {
 	return{
@@ -543,7 +542,10 @@
 
 frappe.ui.form.on('Sales Invoice', {
 	setup: function(frm){
-		
+		frm.add_fetch('customer', 'tax_id', 'tax_id');
+		frm.add_fetch('payment_term', 'invoice_portion', 'invoice_portion');
+		frm.add_fetch('payment_term', 'description', 'description');
+
 		frm.custom_make_buttons = {
 			'Delivery Note': 'Delivery',
 			'Sales Invoice': 'Sales Return',
@@ -625,7 +627,7 @@
 			}
 		};
 	},
-	//When multiple companies are set up. in case company name is changed set default company address
+	// When multiple companies are set up. in case company name is changed set default company address
 	company:function(frm){
 		if (frm.doc.company)
 		{
@@ -712,8 +714,52 @@
 			}
 			frm.set_value("loyalty_amount", loyalty_amount);
 		}
-	}
+	},
 
+	// Healthcare
+	patient: function(frm) {
+		if (frappe.boot.active_domains.includes("Healthcare")){
+			if(frm.doc.patient){
+				frappe.call({
+					method: "frappe.client.get_value",
+					args:{
+						doctype: "Patient",
+						filters: {"name": frm.doc.patient},
+						fieldname: "customer"
+					},
+					callback:function(patient_customer) {
+						if(patient_customer){
+							frm.set_value("customer", patient_customer.message.customer);
+							frm.refresh_fields();
+						}
+					}
+				});
+			}
+			else{
+					frm.set_value("customer", '');
+			}
+		}
+	},
+	refresh: function(frm) {
+		if (frappe.boot.active_domains.includes("Healthcare")){
+			frm.set_df_property("patient", "hidden", 0);
+			frm.set_df_property("patient_name", "hidden", 0);
+			frm.set_df_property("ref_practitioner", "hidden", 0);
+			if (cint(frm.doc.docstatus==0) && cur_frm.page.current_view_name!=="pos" && !frm.doc.is_return) {
+				frm.add_custom_button(__('Healthcare Services'), function() {
+					get_healthcare_services_to_invoice(frm);
+				},"Get items from");
+				frm.add_custom_button(__('Prescriptions'), function() {
+					get_drugs_to_invoice(frm);
+				},"Get items from");
+			}
+		}
+		else{
+			frm.set_df_property("patient", "hidden", 1);
+			frm.set_df_property("patient_name", "hidden", 1);
+			frm.set_df_property("ref_practitioner", "hidden", 1);
+		}
+	}
 })
 
 frappe.ui.form.on('Sales Invoice Timesheet', {
@@ -816,3 +862,270 @@
 
 	dialog.show();
 }
+
+// Healthcare
+var get_healthcare_services_to_invoice = function(frm) {
+	var me = this;
+	let selected_patient = '';
+	var dialog = new frappe.ui.Dialog({
+		title: __("Get Items from Healthcare Services"),
+		fields:[
+			{
+				fieldtype: 'Link',
+				options: 'Patient',
+				label: 'Patient',
+				fieldname: "patient",
+				reqd: true
+			},
+			{ fieldtype: 'Section Break'	},
+			{ fieldtype: 'HTML', fieldname: 'results_area' }
+		]
+	});
+	var $wrapper;
+	var $results;
+	var $placeholder;
+	dialog.set_values({
+		'patient': frm.doc.patient
+	});
+	dialog.fields_dict["patient"].df.onchange = () => {
+		var patient = dialog.fields_dict.patient.input.value;
+		if(patient && patient!=selected_patient){
+			selected_patient = patient;
+			var method = "erpnext.healthcare.utils.get_healthcare_services_to_invoice";
+			var args = {patient: patient};
+			var columns = (["service", "reference_name", "reference_type"]);
+			get_healthcare_items(frm, true, $results, $placeholder, method, args, columns);
+		}
+		else if(!patient){
+			selected_patient = '';
+			$results.empty();
+			$results.append($placeholder);
+		}
+	}
+	$wrapper = dialog.fields_dict.results_area.$wrapper.append(`<div class="results"
+		style="border: 1px solid #d1d8dd; border-radius: 3px; height: 300px; overflow: auto;"></div>`);
+	$results = $wrapper.find('.results');
+	$placeholder = $(`<div class="multiselect-empty-state">
+				<span class="text-center" style="margin-top: -40px;">
+					<i class="fa fa-2x fa-heartbeat text-extra-muted"></i>
+					<p class="text-extra-muted">No billable Healthcare Services found</p>
+				</span>
+			</div>`);
+	$results.on('click', '.list-item--head :checkbox', (e) => {
+		$results.find('.list-item-container .list-row-check')
+			.prop("checked", ($(e.target).is(':checked')));
+	});
+	set_primary_action(frm, dialog, $results, true);
+	dialog.show();
+};
+
+var get_healthcare_items = function(frm, invoice_healthcare_services, $results, $placeholder, method, args, columns) {
+	var me = this;
+	$results.empty();
+	frappe.call({
+		method: method,
+		args: args,
+		callback: function(data) {
+			if(data.message){
+				$results.append(make_list_row(columns, invoice_healthcare_services));
+				for(let i=0; i<data.message.length; i++){
+					$results.append(make_list_row(columns, invoice_healthcare_services, data.message[i]));
+				}
+			}else {
+				$results.append($placeholder);
+			}
+		}
+	});
+}
+
+var make_list_row= function(columns, invoice_healthcare_services, result={}) {
+	var me = this;
+	// Make a head row by default (if result not passed)
+	let head = Object.keys(result).length === 0;
+	let contents = ``;
+	columns.forEach(function(column) {
+		contents += `<div class="list-item__content ellipsis">
+			${
+				head ? `<span class="ellipsis">${__(frappe.model.unscrub(column))}</span>`
+
+				:(column !== "name" ? `<span class="ellipsis">${__(result[column])}</span>`
+					: `<a class="list-id ellipsis">
+						${__(result[column])}</a>`)
+			}
+		</div>`;
+	})
+
+	let $row = $(`<div class="list-item">
+		<div class="list-item__content" style="flex: 0 0 10px;">
+			<input type="checkbox" class="list-row-check" ${result.checked ? 'checked' : ''}>
+		</div>
+		${contents}
+	</div>`);
+
+	$row = list_row_data_items(head, $row, result, invoice_healthcare_services);
+	return $row;
+};
+
+var set_primary_action= function(frm, dialog, $results, invoice_healthcare_services) {
+	var me = this;
+	dialog.set_primary_action(__('Add'), function() {
+		let checked_values = get_checked_values($results);
+		if(checked_values.length > 0){
+			frm.set_value("patient", dialog.fields_dict.patient.input.value);
+			frm.set_value("items", []);
+			add_to_item_line(frm, checked_values, invoice_healthcare_services);
+			dialog.hide();
+		}
+		else{
+			if(invoice_healthcare_services){
+				frappe.msgprint(__("Please select Healthcare Service"));
+			}
+			else{
+				frappe.msgprint(__("Please select Drug"));
+			}
+		}
+	});
+};
+
+var get_checked_values= function($results) {
+	return $results.find('.list-item-container').map(function() {
+		let checked_values = {};
+		if ($(this).find('.list-row-check:checkbox:checked').length > 0 ) {
+			checked_values['dn'] = $(this).attr('data-dn');
+			checked_values['dt'] = $(this).attr('data-dt');
+			checked_values['item'] = $(this).attr('data-item');
+			if($(this).attr('data-rate') != 'undefined'){
+				checked_values['rate'] = $(this).attr('data-rate');
+			}
+			else{
+				checked_values['rate'] = false;
+			}
+			if($(this).attr('data-income-account') != 'undefined'){
+				checked_values['income_account'] = $(this).attr('data-income-account');
+			}
+			else{
+				checked_values['income_account'] = false;
+			}
+			if($(this).attr('data-qty') != 'undefined'){
+				checked_values['qty'] = $(this).attr('data-qty');
+			}
+			else{
+				checked_values['qty'] = false;
+			}
+			if($(this).attr('data-description') != 'undefined'){
+				checked_values['description'] = $(this).attr('data-description');
+			}
+			else{
+				checked_values['description'] = false;
+			}
+			return checked_values;
+		}
+	}).get();
+};
+
+var get_drugs_to_invoice = function(frm) {
+	var me = this;
+	let selected_encounter = '';
+	var dialog = new frappe.ui.Dialog({
+		title: __("Get Items from Prescriptions"),
+		fields:[
+			{ fieldtype: 'Link', options: 'Patient', label: 'Patient', fieldname: "patient", reqd: true },
+			{ fieldtype: 'Link', options: 'Patient Encounter', label: 'Patient Encounter', fieldname: "encounter", reqd: true,
+				description:'Quantity will be calculated only for items which has "Nos" as UoM. You may change as required for each invoice item.',
+				get_query: function(doc) {
+					return {
+						filters: { patient :dialog.get_value("patient") }
+					};
+				}
+			},
+			{ fieldtype: 'Section Break' },
+			{ fieldtype: 'HTML', fieldname: 'results_area' }
+		]
+	});
+	var $wrapper;
+	var $results;
+	var $placeholder;
+	dialog.set_values({
+		'patient': frm.doc.patient,
+		'encounter': ""
+	});
+	dialog.fields_dict["encounter"].df.onchange = () => {
+		var encounter = dialog.fields_dict.encounter.input.value;
+		if(encounter && encounter!=selected_encounter){
+			selected_encounter = encounter;
+			var method = "erpnext.healthcare.utils.get_drugs_to_invoice";
+			var args = {encounter: encounter};
+			var columns = (["drug_code", "quantity", "description"]);
+			get_healthcare_items(frm, false, $results, $placeholder, method, args, columns);
+		}
+		else if(!encounter){
+			selected_encounter = '';
+			$results.empty();
+			$results.append($placeholder);
+		}
+	}
+	$wrapper = dialog.fields_dict.results_area.$wrapper.append(`<div class="results"
+		style="border: 1px solid #d1d8dd; border-radius: 3px; height: 300px; overflow: auto;"></div>`);
+	$results = $wrapper.find('.results');
+	$placeholder = $(`<div class="multiselect-empty-state">
+				<span class="text-center" style="margin-top: -40px;">
+					<i class="fa fa-2x fa-heartbeat text-extra-muted"></i>
+					<p class="text-extra-muted">No Drug Prescription found</p>
+				</span>
+			</div>`);
+	$results.on('click', '.list-item--head :checkbox', (e) => {
+		$results.find('.list-item-container .list-row-check')
+			.prop("checked", ($(e.target).is(':checked')));
+	});
+	set_primary_action(frm, dialog, $results, false);
+	dialog.show();
+};
+
+var list_row_data_items = function(head, $row, result, invoice_healthcare_services) {
+	if(invoice_healthcare_services){
+		head ? $row.addClass('list-item--head')
+			: $row = $(`<div class="list-item-container"
+				data-dn= "${result.reference_name}" data-dt= "${result.reference_type}" data-item= "${result.service}"
+				data-rate = ${result.rate}
+				data-income-account = "${result.income_account}"
+				data-qty = ${result.qty}
+				data-description = "${result.description}">
+				</div>`).append($row);
+	}
+	else{
+		head ? $row.addClass('list-item--head')
+			: $row = $(`<div class="list-item-container"
+				data-item= "${result.drug_code}"
+				data-qty = ${result.quantity}
+				data-description = "${result.description}">
+				</div>`).append($row);
+	}
+	return $row
+};
+
+var add_to_item_line = function(frm, checked_values, invoice_healthcare_services){
+	if(invoice_healthcare_services){
+		frappe.call({
+			doc: frm.doc,
+			method: "set_healthcare_services",
+			args:{
+				checked_values: checked_values
+			},
+			callback: function() {
+				frm.trigger("validate");
+				frm.refresh_fields();
+			}
+		});
+	}
+	else{
+		for(let i=0; i<checked_values.length; i++){
+			var si_item = frappe.model.add_child(frm.doc, 'Sales Invoice Item', 'items');
+			frappe.model.set_value(si_item.doctype, si_item.name, 'item_code', checked_values[i]['item']);
+			frappe.model.set_value(si_item.doctype, si_item.name, 'qty', 1);
+			if(checked_values[i]['qty'] > 1){
+				frappe.model.set_value(si_item.doctype, si_item.name, 'qty', parseFloat(checked_values[i]['qty']));
+			}
+		}
+		frm.refresh_fields();
+	}
+};
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 05b8300..4154d2e 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -101,7 +101,7 @@
    "no_copy": 1, 
    "oldfieldname": "naming_series", 
    "oldfieldtype": "Select", 
-   "options": "ACC-SINV-.YYYY.-\n", 
+   "options": "ACC-SINV-.YYYY.-", 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
@@ -451,6 +451,39 @@
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "cost_center", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Cost Center", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Cost Center", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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": 1, 
    "collapsible": 0, 
    "columns": 0, 
@@ -2808,7 +2841,7 @@
    "label": "Apply Additional Discount On", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "\nGrand Total\nNet Total\n", 
+   "options": "\nGrand Total\nNet Total", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 1, 
@@ -4383,6 +4416,38 @@
   {
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
+   "allow_on_submit": 1, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "group_same_items", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Group same items", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
@@ -4662,7 +4727,7 @@
    "label": "Status", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "\nDraft\nReturn\nCredit Note Issued\nSubmitted\nPaid\nUnpaid\nOverdue\nCancelled\n", 
+   "options": "\nDraft\nReturn\nCredit Note Issued\nSubmitted\nPaid\nUnpaid\nOverdue\nCancelled", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 1, 
@@ -4834,7 +4899,7 @@
    "no_copy": 0, 
    "oldfieldname": "is_opening", 
    "oldfieldtype": "Select", 
-   "options": "No\nYes\n", 
+   "options": "No\nYes", 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
@@ -4866,7 +4931,7 @@
    "label": "C-Form Applicable", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "No\nYes\n", 
+   "options": "No\nYes", 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
@@ -5481,7 +5546,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-08-29 16:23:03.940415", 
+ "modified": "2018-09-07 14:24:58.854289", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Invoice", 
@@ -5575,5 +5640,6 @@
  "timeline_field": "customer", 
  "title_field": "title", 
  "track_changes": 1, 
- "track_seen": 1
+ "track_seen": 1, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index bdf8349..4eeedac 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -24,6 +24,8 @@
 from erpnext.accounts.doctype.loyalty_program.loyalty_program import \
 	get_loyalty_program_details_with_points, get_loyalty_details, validate_loyalty_points
 
+from erpnext.healthcare.utils import manage_invoice_submit_cancel
+
 from six import iteritems
 
 form_grid_templates = {
@@ -179,6 +181,13 @@
 		if self.redeem_loyalty_points and self.loyalty_points:
 			self.apply_loyalty_points()
 
+		# Healthcare Service Invoice.
+		domain_settings = frappe.get_doc('Domain Settings')
+		active_domains = [d.domain for d in domain_settings.active_domains]
+
+		if "Healthcare" in active_domains:
+			manage_invoice_submit_cancel(self, "on_submit")
+
 	def validate_pos_paid_amount(self):
 		if len(self.payments) == 0 and self.is_pos:
 			frappe.throw(_("At least one mode of payment is required for POS invoice."))
@@ -227,6 +236,13 @@
 
 		unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
 
+		# Healthcare Service Invoice.
+		domain_settings = frappe.get_doc('Domain Settings')
+		active_domains = [d.domain for d in domain_settings.active_domains]
+
+		if "Healthcare" in active_domains:
+			manage_invoice_submit_cancel(self, "on_cancel")
+
 	def update_status_updater_args(self):
 		if cint(self.update_stock):
 			self.status_updater.extend([{
@@ -719,7 +735,8 @@
 					"debit_in_account_currency": grand_total_in_company_currency \
 						if self.party_account_currency==self.company_currency else grand_total,
 					"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
-					"against_voucher_type": self.doctype
+					"against_voucher_type": self.doctype,
+					"cost_center": self.cost_center
 				}, self.party_account_currency)
 			)
 
@@ -780,13 +797,14 @@
 					"against": "Expense account - " + cstr(self.loyalty_redemption_account) + " for the Loyalty Program",
 					"credit": self.loyalty_amount,
 					"against_voucher": self.return_against if cint(self.is_return) else self.name,
-					"against_voucher_type": self.doctype
+					"against_voucher_type": self.doctype,
+					"cost_center": self.cost_center
 				})
 			)
 			gl_entries.append(
 				self.get_gl_dict({
 					"account": self.loyalty_redemption_account,
-					"cost_center": self.loyalty_redemption_cost_center,
+					"cost_center": self.cost_center or self.loyalty_redemption_cost_center,
 					"against": self.customer,
 					"debit": self.loyalty_amount,
 					"remark": "Loyalty Points redeemed by the customer"
@@ -810,6 +828,7 @@
 								else payment_mode.amount,
 							"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
 							"against_voucher_type": self.doctype,
+							"cost_center": self.cost_center
 						}, self.party_account_currency)
 					)
 
@@ -821,7 +840,8 @@
 							"debit": payment_mode.base_amount,
 							"debit_in_account_currency": payment_mode.base_amount \
 								if payment_mode_account_currency==self.company_currency \
-								else payment_mode.amount
+								else payment_mode.amount,
+							"cost_center": self.cost_center
 						}, payment_mode_account_currency)
 					)
 
@@ -838,7 +858,8 @@
 						"debit_in_account_currency": flt(self.base_change_amount) \
 							if self.party_account_currency==self.company_currency else flt(self.change_amount),
 						"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
-						"against_voucher_type": self.doctype
+						"against_voucher_type": self.doctype,
+						"cost_center": self.cost_center
 					}, self.party_account_currency)
 				)
 
@@ -846,7 +867,8 @@
 					self.get_gl_dict({
 						"account": self.account_for_change_amount,
 						"against": self.customer,
-						"credit": self.base_change_amount
+						"credit": self.base_change_amount,
+						"cost_center": self.cost_center
 					})
 				)
 			else:
@@ -868,7 +890,8 @@
 					"credit_in_account_currency": self.base_write_off_amount \
 						if self.party_account_currency==self.company_currency else self.write_off_amount,
 					"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
-					"against_voucher_type": self.doctype
+					"against_voucher_type": self.doctype,
+					"cost_center": self.cost_center
 				}, self.party_account_currency)
 			)
 			gl_entries.append(
@@ -878,7 +901,7 @@
 					"debit": self.base_write_off_amount,
 					"debit_in_account_currency": self.base_write_off_amount \
 						if write_off_account_currency==self.company_currency else self.write_off_amount,
-					"cost_center": self.write_off_cost_center or default_cost_center
+					"cost_center": self.cost_center or self.write_off_cost_center or default_cost_center
 				}, write_off_account_currency)
 			)
 
@@ -893,7 +916,7 @@
 					"against": self.customer,
 					"credit_in_account_currency": self.base_rounding_adjustment,
 					"credit": self.base_rounding_adjustment,
-					"cost_center": round_off_cost_center,
+					"cost_center": self.cost_center or round_off_cost_center,
 				}
 			))
 
@@ -1178,6 +1201,43 @@
 			from erpnext.accounts.general_ledger import make_gl_entries
 			make_gl_entries(gl_entries, cancel=(self.docstatus == 2), merge_entries=True)
 
+	# Healthcare
+	def set_healthcare_services(self, checked_values):
+		self.set("items", [])
+		from erpnext.stock.get_item_details import get_item_details
+		for checked_item in checked_values:
+			item_line = self.append("items", {})
+			price_list, price_list_currency = frappe.db.get_values("Price List", {"selling": 1}, ['name', 'currency'])[0]
+			args = {
+				'doctype': "Sales Invoice",
+				'item_code': checked_item['item'],
+				'company': self.company,
+				'customer': frappe.db.get_value("Patient", self.patient, "customer"),
+				'selling_price_list': price_list,
+				'price_list_currency': price_list_currency,
+				'plc_conversion_rate': 1.0,
+				'conversion_rate': 1.0
+			}
+			item_details = get_item_details(args)
+			item_line.item_code = checked_item['item']
+			item_line.qty = 1
+			if checked_item['qty']:
+				item_line.qty = checked_item['qty']
+			if checked_item['rate']:
+				item_line.rate = checked_item['rate']
+			else:
+				item_line.rate = item_details.price_list_rate
+			item_line.amount = float(item_line.rate) * float(item_line.qty)
+			if checked_item['income_account']:
+				item_line.income_account = checked_item['income_account']
+			if checked_item['dt']:
+				item_line.reference_dt = checked_item['dt']
+			if checked_item['dn']:
+				item_line.reference_dn = checked_item['dn']
+			if checked_item['description']:
+				item_line.description = checked_item['description']
+
+		self.set_missing_values(for_validate = True)
 
 def booked_deferred_revenue(start_date=None, end_date=None):
 	# check for the sales invoice for which GL entries has to be done
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 468ed9f..b0fbc98 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1438,6 +1438,66 @@
 		si_doc = frappe.get_doc('Sales Invoice', si.name)
 		self.assertEqual(si_doc.outstanding_amount, 0)
 
+	def test_sales_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center for BS Account - _TC"
+		create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
+
+		si =  create_sales_invoice_against_cost_center(cost_center=cost_center, debit_to="Debtors - _TC")
+		self.assertEqual(si.cost_center, cost_center)
+
+		expected_values = {
+			"Debtors - _TC": {
+				"cost_center": cost_center
+			},
+			"Sales - _TC": {
+				"cost_center": cost_center
+			}
+		}
+
+		gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
+			debit_in_account_currency, credit_in_account_currency
+			from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+			order by account asc""", si.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		for gle in gl_entries:
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+
+	def test_sales_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center - _TC"
+		si =  create_sales_invoice(debit_to="Debtors - _TC")
+
+		expected_values = {
+			"Debtors - _TC": {
+				"cost_center": None
+			},
+			"Sales - _TC": {
+				"cost_center": cost_center
+			}
+		}
+
+		gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
+			debit_in_account_currency, credit_in_account_currency
+			from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+			order by account asc""", si.name, as_dict=1)
+
+		self.assertTrue(gl_entries)
+
+		for gle in gl_entries:
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+
 def create_sales_invoice(**args):
 	si = frappe.new_doc("Sales Invoice")
 	args = frappe._dict(args)
@@ -1478,6 +1538,48 @@
 
 	return si
 
+def create_sales_invoice_against_cost_center(**args):
+	si = frappe.new_doc("Sales Invoice")
+	args = frappe._dict(args)
+	if args.posting_date:
+		si.set_posting_time = 1
+	si.posting_date = args.posting_date or nowdate()
+
+	si.company = args.company or "_Test Company"
+	si.cost_center = args.cost_center or "_Test Cost Center - _TC"
+	si.customer = args.customer or "_Test Customer"
+	si.debit_to = args.debit_to or "Debtors - _TC"
+	si.update_stock = args.update_stock
+	si.is_pos = args.is_pos
+	si.is_return = args.is_return
+	si.return_against = args.return_against
+	si.currency=args.currency or "INR"
+	si.conversion_rate = args.conversion_rate or 1
+
+	si.append("items", {
+		"item_code": args.item or args.item_code or "_Test Item",
+		"gst_hsn_code": "999800",
+		"warehouse": args.warehouse or "_Test Warehouse - _TC",
+		"qty": args.qty or 1,
+		"rate": args.rate or 100,
+		"income_account": "Sales - _TC",
+		"expense_account": "Cost of Goods Sold - _TC",
+		"cost_center": args.cost_center or "_Test Cost Center - _TC",
+		"serial_no": args.serial_no
+	})
+
+	if not args.do_not_save:
+		si.insert()
+		if not args.do_not_submit:
+			si.submit()
+		else:
+			si.payment_schedule = []
+	else:
+		si.payment_schedule = []
+
+	return si
+
+
 test_dependencies = ["Journal Entry", "Contact", "Address"]
 test_records = frappe.get_test_records('Sales Invoice')
 
diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
index 0dc4ecf..9a2c095 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
@@ -102,17 +102,25 @@
 
 	return tds_amount
 
-def get_advance_vouchers(supplier, fiscal_year):
+def get_advance_vouchers(supplier, fiscal_year=None, company=None, from_date=None, to_date=None):
+	condition = "fiscal_year=%s" % fiscal_year
+	if from_date and to_date:
+		condition = "company=%s and posting_date between %s and %s" % (company, from_date, to_date)
+
 	return frappe.db.sql_list("""
 		select distinct voucher_no
 		from `tabGL Entry`
-		where party=%s and fiscal_year=%s and debit > 0
-	""", (supplier, fiscal_year))
+		where party=%s and %s and debit > 0
+	""", (supplier, condition))
 
-def get_debit_note_amount(supplier, year_start_date, year_end_date):
+def get_debit_note_amount(supplier, year_start_date, year_end_date, company=None):
+	condition = ""
+	if company:
+		condition = " and company=%s " % company
+
 	return flt(frappe.db.sql("""
 		select abs(sum(net_total))
 		from `tabPurchase Invoice`
-		where supplier=%s and is_return=1 and docstatus=1
+		where supplier=%s %s and is_return=1 and docstatus=1
 			and posting_date between %s and %s
-	""", (supplier, year_start_date, year_end_date)))
\ No newline at end of file
+	""", (supplier, condition, year_start_date, year_end_date)))
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index ce1f34b..528e3d3 100755
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -123,6 +123,10 @@
 			me.sync_sales_invoice()
 		});
 
+		this.page.add_menu_item(__("Cashier Closing"), function () {
+			frappe.set_route('List', 'Cashier Closing');
+		});		
+
 		this.page.add_menu_item(__("POS Profile"), function () {
 			frappe.set_route('List', 'POS Profile');
 		});
diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.json b/erpnext/accounts/report/balance_sheet/balance_sheet.json
index 4e75344..f67a34b 100644
--- a/erpnext/accounts/report/balance_sheet/balance_sheet.json
+++ b/erpnext/accounts/report/balance_sheet/balance_sheet.json
@@ -1,17 +1,17 @@
 {
  "add_total_row": 0, 
- "apply_user_permissions": 1, 
  "creation": "2014-07-14 05:24:20.385279", 
  "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 2, 
  "is_standard": "Yes", 
- "modified": "2017-02-24 20:12:47.161127", 
+ "modified": "2018-09-07 12:18:21.850851", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Balance Sheet", 
  "owner": "Administrator", 
+ "prepared_report": 0, 
  "ref_doctype": "GL Entry", 
  "report_name": "Balance Sheet", 
  "report_type": "Script Report", 
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 3a97f44..74ca258 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -351,7 +351,9 @@
 			"from_date": from_date,
 			"to_date": to_date,
 			"lft": root_lft,
-			"rgt": root_rgt
+			"rgt": root_rgt,
+			"cost_center": filters.cost_center,
+			"project": filters.project
 		},
 		as_dict=True)
 
@@ -378,13 +380,11 @@
 			if not isinstance(filters.get("project"), list):
 				projects = str(filters.get("project")).strip()
 				filters.project = [d.strip() for d in projects.split(',') if d]
-			additional_conditions.append("project = '%s'" % (frappe.db.escape(filters.get("project"))))
+			additional_conditions.append("project in %(project)s")
 
 		if filters.get("cost_center"):
-			if not isinstance(filters.get("cost_center"), list):
-				cost_centers = str(filters.get("cost_center")).strip()
-				filters.cost_center = [d.strip() for d in cost_centers.split(',') if d]
-			additional_conditions.append(get_cost_center_cond(filters.get("cost_center")))
+			filters.cost_center = get_cost_centers_with_children(filters.cost_center)
+			additional_conditions.append("cost_center in %(cost_center)s")
 
 		company_finance_book = erpnext.get_default_finance_book(filters.get("company"))
 
@@ -397,14 +397,17 @@
 
 	return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
 
+def get_cost_centers_with_children(cost_centers):
+	if not isinstance(cost_centers, list):
+		cost_centers = [d.strip() for d in str(cost_centers).strip().split(',') if d]
 
-def get_cost_center_cond(cost_center):
-	cost_centers = frappe.db.get_all("Cost Center", {"name": ["in", cost_center]},
-		["name", "lft", "rgt"])
+	all_cost_centers = []
+	for d in cost_centers:
+		lft, rgt = frappe.db.get_value("Cost Center", d, ["lft", "rgt"])
+		children = frappe.get_all("Cost Center", filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
+		all_cost_centers += [c.name for c in children]
 
-	lft_rgt = " or ".join(["(lft >=%s and rgt <=%s)" % (d.lft, d.rgt) for d in cost_centers])
-
-	return """ cost_center in (select name from `tabCost Center` where %s)""" % (lft_rgt)
+	return list(set(all_cost_centers))
 
 def get_columns(periodicity, period_list, accumulated_values=1, company=None):
 	columns = [{
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index 2d174ff..56663d3 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -8,7 +8,7 @@
 from frappe.utils import getdate, cstr, flt, fmt_money
 from frappe import _, _dict
 from erpnext.accounts.utils import get_account_currency
-
+from erpnext.accounts.report.financial_statements import get_cost_centers_with_children
 from six import iteritems
 
 def execute(filters=None):
@@ -154,6 +154,10 @@
 		conditions.append("""account in (select name from tabAccount
 			where lft>=%s and rgt<=%s and docstatus<2)""" % (lft, rgt))
 
+	if filters.get("cost_center"):
+		filters.cost_center = get_cost_centers_with_children(filters.cost_center)
+		conditions.append("cost_center in %(cost_center)s")
+
 	if filters.get("voucher_no"):
 		conditions.append("voucher_no=%(voucher_no)s")
 
@@ -174,9 +178,6 @@
 	if filters.get("project"):
 		conditions.append("project in %(project)s")
 
-	if filters.get("cost_center"):
-		conditions.append("cost_center in %(cost_center)s")
-
 	company_finance_book = erpnext.get_default_finance_book(filters.get("company"))
 	if not filters.get("finance_book") or (filters.get("finance_book") == company_finance_book):
 		filters['finance_book'] = company_finance_book
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
index 1804733..250e516 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
@@ -8,37 +8,6 @@
 
 	frappe.query_reports["Profit and Loss Statement"]["filters"].push(
 		{
-			"fieldname":"cost_center",
-			"label": __("Cost Center"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var cost_centers = frappe.query_report.get_filter_value("cost_center") || "";
-
-				const values = cost_centers.split(/\s*,\s*/).filter(d => d);
-				const txt = cost_centers.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Cost Center",
-						txt: txt,
-						filters: {
-							"company": frappe.query_report.get_filter_value("company"),
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
-			}
-		},
-		{
 			"fieldname":"project",
 			"label": __("Project"),
 			"fieldtype": "MultiSelect",
diff --git a/erpnext/accounts/report/tds_computation_summary/__init__.py b/erpnext/accounts/report/tds_computation_summary/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/report/tds_computation_summary/__init__.py
diff --git a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.js b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.js
new file mode 100644
index 0000000..74669c4
--- /dev/null
+++ b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.js
@@ -0,0 +1,43 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["TDS Computation Summary"] = {
+	"filters": [
+		{
+			"fieldname":"company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"default": frappe.defaults.get_default('company')
+		},
+		{
+			"fieldname":"supplier",
+			"label": __("Supplier"),
+			"fieldtype": "Link",
+			"options": "Supplier",
+			"get_query": function() {
+				return {
+					"filters": {
+						"tax_withholding_category": ["!=",""],
+					}
+				}
+			}
+		},
+		{
+			"fieldname":"from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
+			"reqd": 1,
+			"width": "60px"
+		},
+		{
+			"fieldname":"to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.get_today(),
+			"reqd": 1,
+			"width": "60px"
+		}
+	]
+}
diff --git a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.json b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.json
new file mode 100644
index 0000000..6082ed2
--- /dev/null
+++ b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.json
@@ -0,0 +1,33 @@
+{
+ "add_total_row": 0,
+ "creation": "2018-08-21 11:25:00.551823",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "Gadgets International",
+ "modified": "2018-08-21 11:25:00.551823",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "TDS Computation Summary",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Purchase Invoice",
+ "report_name": "TDS Computation Summary",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Purchase User"
+  },
+  {
+   "role": "Accounts Manager"
+  },
+  {
+   "role": "Accounts User"
+  },
+  {
+   "role": "Auditor"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
new file mode 100644
index 0000000..391287b
--- /dev/null
+++ b/erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py
@@ -0,0 +1,135 @@
+import frappe
+from frappe import _
+from frappe.utils import flt
+from erpnext.accounts.utils import get_fiscal_year
+from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category \
+	import get_advance_vouchers, get_debit_note_amount
+
+def execute(filters=None):
+	validate_filters(filters)
+
+	columns = get_columns()
+	res = get_result(filters)
+
+	return columns, res
+
+def validate_filters(filters):
+	''' Validate if dates are properly set and lie in the same fiscal year'''
+	if filters.from_date > filters.to_date:
+		frappe.throw(_("From Date must be before To Date"))
+
+	from_year = get_fiscal_year(filters.from_date)[0]
+	to_year = get_fiscal_year(filters.to_date)[0]
+	if from_year != to_year:
+		frappe.throw(_("From Date and To Date lie in different Fiscal Year"))
+
+	filters["fiscal_year"] = from_year
+
+def get_result(filters):
+	# if no supplier selected, fetch data for all tds applicable supplier
+	# else fetch relevant data for selected supplier
+	pan = "pan" if frappe.db.has_column("Supplier", "pan") else "tax_id"
+	fields = ["name", pan+" as pan", "tax_withholding_category", "supplier_type"]
+	if filters.supplier:
+		filters.supplier = frappe.db.get_list('Supplier',
+			{"name": filters.supplier}, fields)
+	else:
+		filters.supplier = frappe.db.get_list('Supplier',
+			{"tax_withholding_category": ["!=", ""]}, fields)
+
+	out = []
+	for supplier in filters.supplier:
+		tds = frappe.get_doc("Tax Withholding Category", supplier.tax_withholding_category)
+		rate = [d.tax_withholding_rate for d in tds.rates if d.fiscal_year == filters.fiscal_year][0]
+		account = [d.account for d in tds.accounts if d.company == filters.company][0]
+
+		total_invoiced_amount, tds_deducted = get_invoice_and_tds_amount(supplier.name, account,
+			filters.company, filters.from_date, filters.to_date)
+
+		if total_invoiced_amount or tds_deducted:
+			out.append([supplier.pan, supplier.name, tds.name, supplier.supplier_type,
+				rate, total_invoiced_amount, tds_deducted])
+
+	return out
+
+def get_invoice_and_tds_amount(supplier, account, company, from_date, to_date):
+	''' calculate total invoice amount and total tds deducted for given supplier  '''
+
+	entries = frappe.db.sql("""
+		select voucher_no, credit
+		from `tabGL Entry`
+		where party in (%s) and credit > 0
+			and company=%s and posting_date between %s and %s
+	""", (supplier, company, from_date, to_date), as_dict=1)
+
+	supplier_credit_amount = flt(sum([d.credit for d in entries]))
+
+	vouchers = [d.voucher_no for d in entries]
+	vouchers += get_advance_vouchers(supplier, company=company,
+		from_date=from_date, to_date=to_date)
+
+	tds_deducted = 0
+	if vouchers:
+		tds_deducted = flt(frappe.db.sql("""
+			select sum(credit)
+			from `tabGL Entry`
+			where account=%s and posting_date between %s and %s
+				and company=%s and credit > 0 and voucher_no in ({0})
+		""".format(', '.join(["'%s'" % d for d in vouchers])),
+			(account, from_date, to_date, company))[0][0])
+
+	debit_note_amount = get_debit_note_amount(supplier, from_date, to_date, company=company)
+
+	total_invoiced_amount = supplier_credit_amount + tds_deducted - debit_note_amount
+
+	return total_invoiced_amount, tds_deducted
+
+def get_columns():
+	columns = [
+		{
+			"label": _("PAN"),
+			"fieldname": "pan",
+			"fieldtype": "Data",
+			"width": 90
+		},
+		{
+			"label": _("Supplier"),
+			"options": "Supplier",
+			"fieldname": "supplier",
+			"fieldtype": "Link",
+			"width": 180
+		},
+		{
+			"label": _("Section Code"),
+			"options": "Tax Withholding Category",
+			"fieldname": "section_code",
+			"fieldtype": "Link",
+			"width": 180
+		},
+		{
+			"label": _("Entity Type"),
+			"fieldname": "entity_type",
+			"fieldtype": "Data",
+			"width": 180
+		},
+		{
+			"label": _("TDS Rate %"),
+			"fieldname": "tds_rate",
+			"fieldtype": "Float",
+			"width": 90
+		},
+		{
+			"label": _("Total Amount Credited"),
+			"fieldname": "total_amount_credited",
+			"fieldtype": "Float",
+			"width": 90
+		},
+		{
+			"label": _("Amount of TDS Deducted"),
+			"fieldname": "tds_deducted",
+			"fieldtype": "Float",
+			"width": 90
+		}
+	]
+
+	return columns
diff --git a/erpnext/accounts/report/tds_payable_monthly/__init__.py b/erpnext/accounts/report/tds_payable_monthly/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/accounts/report/tds_payable_monthly/__init__.py
diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js
new file mode 100644
index 0000000..232d053
--- /dev/null
+++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.js
@@ -0,0 +1,89 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["TDS Payable Monthly"] = {
+	"filters": [
+		{
+			"fieldname":"company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"default": frappe.defaults.get_default('company')
+		},
+		{
+			"fieldname":"supplier",
+			"label": __("Supplier"),
+			"fieldtype": "Link",
+			"options": "Supplier",
+			"get_query": function() {
+				return {
+					"filters": {
+						"tax_withholding_category": ["!=", ""],
+					}
+				}
+			},
+			on_change: function() {
+				frappe.query_report.set_filter_value("purchase_invoice", "");
+				frappe.query_report.refresh();
+			}
+		},
+		{
+			"fieldname":"purchase_invoice",
+			"label": __("Purchase Invoice"),
+			"fieldtype": "Link",
+			"options": "Purchase Invoice",
+			"get_query": function() {
+				return {
+					"filters": {
+						"name": ["in", frappe.query_report.invoices]
+					}
+				}
+			},
+			on_change: function() {
+				let supplier = frappe.query_report.get_filter_value('supplier');
+				if(!supplier) return; // return if no supplier selected
+
+				// filter invoices based on selected supplier
+				let invoices = [];
+				frappe.query_report.invoice_data.map(d => {
+					if(d.supplier==supplier)
+						invoices.push(d.name)
+				});
+				frappe.query_report.invoices = invoices;
+				frappe.query_report.refresh();
+			}
+		},
+		{
+			"fieldname":"from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
+			"reqd": 1,
+			"width": "60px"
+		},
+		{
+			"fieldname":"to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.get_today(),
+			"reqd": 1,
+			"width": "60px"
+		}
+	],
+
+	onload: function(report) {
+		// fetch all tds applied invoices
+		frappe.call({
+			"method": "erpnext.accounts.report.tds_payable_monthly.tds_payable_monthly.get_tds_invoices",
+			callback: function(r) {
+				let invoices = [];
+				r.message.map(d => {
+					invoices.push(d.name);
+				});
+
+				report["invoice_data"] = r.message;
+				report["invoices"] = invoices;
+			}
+		});
+	}
+}
diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.json b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.json
new file mode 100644
index 0000000..6a83272
--- /dev/null
+++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.json
@@ -0,0 +1,33 @@
+{
+ "add_total_row": 0,
+ "creation": "2018-08-21 11:32:30.874923",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "Gadgets International",
+ "modified": "2018-08-21 11:33:40.804532",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "TDS Payable Monthly",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Purchase Invoice",
+ "report_name": "TDS Payable Monthly",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Purchase User"
+  },
+  {
+   "role": "Accounts Manager"
+  },
+  {
+   "role": "Accounts User"
+  },
+  {
+   "role": "Auditor"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
new file mode 100644
index 0000000..0e6f0a2
--- /dev/null
+++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
@@ -0,0 +1,190 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import getdate
+
+def execute(filters=None):
+	filters["invoices"] = frappe.cache().hget("invoices", frappe.session.user)
+	validate_filters(filters)
+	set_filters(filters)
+
+	columns = get_columns()
+	res = get_result(filters)
+
+	return columns, res
+
+def validate_filters(filters):
+	''' Validate if dates are properly set '''
+	if filters.from_date > filters.to_date:
+		frappe.throw(_("From Date must be before To Date"))
+
+def set_filters(filters):
+	invoices = []
+
+	if not filters["invoices"]:
+		filters["invoices"] = get_tds_invoices()
+	if filters.supplier and filters.purchase_invoice:
+		for d in filters["invoices"]:
+			if d.name == filters.purchase_invoice and d.supplier == filters.supplier:
+				invoices.append(d)
+	elif filters.supplier and not filters.purchase_invoice:
+		for d in filters["invoices"]:
+			if d.supplier == filters.supplier:
+				invoices.append(d)
+	elif filters.purchase_invoice and not filters.supplier:
+		for d in filters["invoices"]:
+			if d.name == filters.purchase_invoice:
+				invoices.append(d)
+
+	filters["invoices"] = invoices if invoices else filters["invoices"]
+
+def get_result(filters):
+	supplier_map, tds_docs = get_supplier_map(filters)
+	gle_map = get_gle_map(filters)
+
+	out = []
+	for d in gle_map:
+		tds_deducted, total_amount_credited = 0, 0
+		supplier = supplier_map[d]
+
+		tds_doc = tds_docs[supplier.tax_withholding_category]
+		account = [i.account for i in tds_doc.accounts if i.company == filters.company][0]
+
+		for k in gle_map[d]:
+			if k.party == supplier_map[d] and k.credit > 0:
+				total_amount_credited += k.credit
+			elif k.account == account and k.credit > 0:
+				tds_deducted = k.credit
+				total_amount_credited += k.credit
+
+		rate = [i.tax_withholding_rate for i in tds_doc.rates
+			if i.fiscal_year == gle_map[d][0].fiscal_year][0]
+
+		if getdate(filters.from_date) <= gle_map[d][0].posting_date \
+			and getdate(filters.to_date) >= gle_map[d][0].posting_date:
+			out.append([supplier.pan, supplier.name, tds_doc.name,
+				supplier.supplier_type, rate, total_amount_credited, tds_deducted,
+				gle_map[d][0].posting_date, "Purchase Invoice", d])
+
+	return out
+
+def get_supplier_map(filters):
+	# create a supplier_map of the form {"purchase_invoice": {supplier_name, pan, tds_name}}
+	# pre-fetch all distinct applicable tds docs
+	supplier_map, tds_docs = {}, {}
+	pan = "pan" if frappe.db.has_column("Supplier", "pan") else "tax_id"
+	supplier_detail = frappe.db.get_all('Supplier',
+		{"name": ["in", [d.supplier for d in filters["invoices"]]]},
+		["tax_withholding_category", "name", pan+" as pan", "supplier_type"])
+
+	for d in filters["invoices"]:
+		supplier_map[d.get("name")] = [k for k in supplier_detail
+			if k.name == d.get("supplier")][0]
+
+	for d in supplier_detail:
+		if d.get("tax_withholding_category") not in tds_docs:
+			tds_docs[d.get("tax_withholding_category")] = \
+				frappe.get_doc("Tax Withholding Category", d.get("tax_withholding_category"))
+
+	return supplier_map, tds_docs
+
+def get_gle_map(filters):
+	# create gle_map of the form
+	# {"purchase_invoice": list of dict of all gle created for this invoice}
+	gle_map = {}
+	gle = frappe.db.get_all('GL Entry',\
+		{"voucher_no": ["in", [d.get("name") for d in filters["invoices"]]]},
+		["fiscal_year", "credit", "debit", "account", "voucher_no", "posting_date"])
+
+	for d in gle:
+		if not d.voucher_no in gle_map:
+			gle_map[d.voucher_no] = [d]
+		else:
+			gle_map[d.voucher_no].append(d)
+
+	return gle_map
+
+def get_columns():
+	pan = "pan" if frappe.db.has_column("Supplier", "pan") else "tax_id"
+	columns = [
+		{
+			"label": _(frappe.unscrub(pan)),
+			"fieldname": pan,
+			"fieldtype": "Data",
+			"width": 90
+		},
+		{
+			"label": _("Supplier"),
+			"options": "Supplier",
+			"fieldname": "supplier",
+			"fieldtype": "Link",
+			"width": 180
+		},
+		{
+			"label": _("Section Code"),
+			"options": "Tax Withholding Category",
+			"fieldname": "section_code",
+			"fieldtype": "Link",
+			"width": 180
+		},
+		{
+			"label": _("Entity Type"),
+			"fieldname": "entity_type",
+			"fieldtype": "Data",
+			"width": 180
+		},
+		{
+			"label": _("TDS Rate %"),
+			"fieldname": "tds_rate",
+			"fieldtype": "Float",
+			"width": 90
+		},
+		{
+			"label": _("Total Amount Credited"),
+			"fieldname": "total_amount_credited",
+			"fieldtype": "Float",
+			"width": 90
+		},
+		{
+			"label": _("Amount of TDS Deducted"),
+			"fieldname": "tds_deducted",
+			"fieldtype": "Float",
+			"width": 90
+		},
+		{
+			"label": _("Date of Transaction"),
+			"fieldname": "transaction_date",
+			"fieldtype": "Date",
+			"width": 90
+		},
+		{
+			"label": _("Transaction Type"),
+			"fieldname": "transaction_type",
+			"width": 90
+		},
+		{
+			"label": _("Reference No."),
+			"fieldname": "ref_no",
+			"fieldtype": "Dynamic Link",
+			"options": "transaction_type",
+			"width": 90
+		}
+	]
+
+	return columns
+
+@frappe.whitelist()
+def get_tds_invoices():
+	# fetch tds applicable supplier and fetch invoices for these suppliers
+	suppliers = [d.name for d in frappe.db.get_list("Supplier",
+		{"tax_withholding_category": ["!=", ""]}, ["name"])]
+
+	invoices = frappe.db.get_list("Purchase Invoice",
+		{"supplier": ["in", suppliers]}, ["name", "supplier"])
+
+	frappe.cache().hset("invoices", frappe.session.user, invoices)
+
+	return invoices
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.js b/erpnext/accounts/report/trial_balance/trial_balance.js
index 8e95d8c..c09fa71 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.js
+++ b/erpnext/accounts/report/trial_balance/trial_balance.js
@@ -13,6 +13,21 @@
 				"reqd": 1
 			},
 			{
+				"fieldname":"cost_center",
+				"label": __("Cost Center"),
+				"fieldtype": "Link",
+				"options": "Cost Center",
+				"get_query": function() {
+					var company = frappe.query_report.get_filter_value('company');
+					return {
+						"doctype": "Cost Center",
+						"filters": {
+							"company": company,
+						}
+					}
+				}
+			},
+			{
 				"fieldname": "fiscal_year",
 				"label": __("Fiscal Year"),
 				"fieldtype": "Link",
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index ae128a7..6fbe97d 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -84,7 +84,7 @@
 			throw(_("{0} '{1}' not in Fiscal Year {2}").format(label, formatdate(date), fiscal_year))
 
 @frappe.whitelist()
-def get_balance_on(account=None, date=None, party_type=None, party=None, company=None, in_account_currency=True):
+def get_balance_on(account=None, date=None, party_type=None, party=None, company=None, in_account_currency=True, cost_center=None):
 	if not account and frappe.form_dict.get("account"):
 		account = frappe.form_dict.get("account")
 	if not date and frappe.form_dict.get("date"):
@@ -93,6 +93,9 @@
 		party_type = frappe.form_dict.get("party_type")
 	if not party and frappe.form_dict.get("party"):
 		party = frappe.form_dict.get("party")
+	if not cost_center and frappe.form_dict.get("cost_center"):
+		cost_center = frappe.form_dict.get("cost_center")
+
 
 	cond = []
 	if date:
@@ -113,17 +116,36 @@
 			# hence, assuming balance as 0.0
 			return 0.0
 
+	allow_cost_center_in_entry_of_bs_account = get_allow_cost_center_in_entry_of_bs_account()
+
+	if cost_center and allow_cost_center_in_entry_of_bs_account:
+		cc = frappe.get_doc("Cost Center", cost_center)
+		if cc.is_group:
+			cond.append(""" exists (
+				select 1 from `tabCost Center` cc where cc.name = gle.cost_center
+				and cc.lft >= %s and cc.rgt <= %s
+			)""" % (cc.lft, cc.rgt))
+
+		else:
+			cond.append("""gle.cost_center = "%s" """ % (frappe.db.escape(cost_center, percent=False), ))
+
+
 	if account:
+
 		acc = frappe.get_doc("Account", account)
 
 		if not frappe.flags.ignore_account_permission:
 			acc.check_permission("read")
 
-		# for pl accounts, get balance within a fiscal year
-		if acc.report_type == 'Profit and Loss':
+
+		if not allow_cost_center_in_entry_of_bs_account and acc.report_type == 'Profit and Loss':
+			# for pl accounts, get balance within a fiscal year
 			cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
 				% year_start_date)
-
+		elif allow_cost_center_in_entry_of_bs_account:
+			# for all accounts, get balance within a fiscal year if maintain cost center in balance account is checked
+			cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
+				% year_start_date)
 		# different filter for group and ledger - improved performance
 		if acc.is_group:
 			cond.append("""exists (
@@ -830,3 +852,10 @@
 	accounts = [d for d in accounts if d['parent_account']==parent]
 
 	return accounts
+
+def get_allow_cost_center_in_entry_of_bs_account():
+	def generator():
+		return cint(frappe.db.get_value('Accounts Settings', None, 'allow_cost_center_in_entry_of_bs_account'))
+	return frappe.local_cache("get_allow_cost_center_in_entry_of_bs_account", (), generator, regenerate_if_none=True)
+
+
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index 0423588..7625416 100755
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -2341,7 +2341,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-08-06 05:16:58.258276", 
+ "modified": "2018-09-07 05:16:58.258276", 
  "modified_by": "Administrator", 
  "module": "Buying", 
  "name": "Purchase Order Item", 
diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json
index 0cadc34..5b095b0 100644
--- a/erpnext/buying/doctype/supplier/supplier.json
+++ b/erpnext/buying/doctype/supplier/supplier.json
@@ -384,6 +384,72 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "default": "Company",
+   "fieldname": "supplier_type",
+   "fieldtype": "Select",
+   "hidden": 0,
+   "ignore_user_permissions": 0,
+   "ignore_xss_filter": 0,
+   "in_filter": 0,
+   "in_global_search": 0,
+   "in_list_view": 0,
+   "in_standard_filter": 0,
+   "label": "Supplier Type",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Company\nIndividual",
+   "permlevel": 0,
+   "precision": "",
+   "print_hide": 0,
+   "print_hide_if_no_value": 0,
+   "read_only": 0,
+   "remember_last_selected_value": 0,
+   "report_hide": 0,
+   "reqd": 1,
+   "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,
+   "fieldname": "pan",
+   "fieldtype": "Data",
+   "hidden": 0,
+   "ignore_user_permissions": 0,
+   "ignore_xss_filter": 0,
+   "in_filter": 0,
+   "in_global_search": 0,
+   "in_list_view": 0,
+   "in_standard_filter": 0,
+   "label": "PAN",
+   "length": 0,
+   "no_copy": 0,
+   "permlevel": 0,
+   "precision": "",
+   "print_hide": 0,
+   "print_hide_if_no_value": 0,
+   "read_only": 0,
+   "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,
    "fieldname": "language",
    "fieldtype": "Link",
    "hidden": 0,
@@ -1364,7 +1430,7 @@
  "issingle": 0,
  "istable": 0,
  "max_attachments": 0,
- "modified": "2018-08-29 06:25:52.313864",
+ "modified": "2018-09-07 08:48:57.719713",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Supplier",
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index 5526ac8..660f78c 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -34,6 +34,11 @@
 				},
 				{
 					"type": "doctype",
+					"name": "Cashier Closing",
+					"description": _("Cashier Closing")
+				},
+				{
+					"type": "doctype",
 					"name": "Auto Repeat",
 					"label": _("Auto Repeat"),
 					"description": _("To make recurring documents")
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index b13e404..d94564e 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -129,7 +129,7 @@
 					self.status = s[0]
 					break
 				elif s[1].startswith("eval:"):
-					if frappe.safe_eval(s[1][5:], None, { "self": self.as_dict(), "getdate": getdate, 
+					if frappe.safe_eval(s[1][5:], None, { "self": self.as_dict(), "getdate": getdate,
 							"nowdate": nowdate, "get_value": frappe.db.get_value }):
 						self.status = s[0]
 						break
@@ -256,7 +256,7 @@
 
 			if args['detail_id']:
 				if not args.get("extra_cond"): args["extra_cond"] = ""
-				
+
 				frappe.db.sql("""update `tab%(target_dt)s`
 					set %(target_field)s = (
 						(select ifnull(sum(%(source_field)s), 0)
@@ -281,7 +281,7 @@
 		"""Update percent field in parent transaction"""
 
 		self._update_modified(args, update_modified)
-		
+
 		if args.get('target_parent_field'):
 			frappe.db.sql("""update `tab%(target_parent_dt)s`
 				set %(target_parent_field)s = round(
@@ -335,8 +335,7 @@
 				from `tab%s Item` where %s=%s and docstatus=1""" %
 				(self.doctype, ref_fieldname, '%s'), (ref_dn))[0][0])
 
-			per_billed = ((ref_doc_qty if billed_qty > ref_doc_qty else billed_qty)\
-				/ ref_doc_qty)*100
+			per_billed = (min(ref_doc_qty, billed_qty) / ref_doc_qty) * 100
 
 			ref_doc = frappe.get_doc(ref_dt, ref_dn)
 
diff --git a/erpnext/domains/healthcare.py b/erpnext/domains/healthcare.py
index 5a54cf6..ee8dc81 100644
--- a/erpnext/domains/healthcare.py
+++ b/erpnext/domains/healthcare.py
@@ -21,9 +21,30 @@
 		'Patient'
 	],
 	'custom_fields': {
-		'Sales Invoice': dict(fieldname='appointment', label='Patient Appointment',
-			fieldtype='Link', options='Patient Appointment',
-			insert_after='customer')
+		'Sales Invoice': [
+			{
+				'fieldname': 'patient', 'label': 'Patient', 'fieldtype': 'Link', 'options': 'Patient',
+				'insert_after': 'naming_series'
+			},
+			{
+				'fieldname': 'patient_name', 'label': 'Patient Name', 'fieldtype': 'Data', 'fetch_from': 'patient.patient_name',
+				'insert_after': 'patient', 'read_only': True
+			},
+			{
+				'fieldname': 'ref_practitioner', 'label': 'Referring Practitioner', 'fieldtype': 'Link', 'options': 'Healthcare Practitioner',
+				'insert_after': 'customer'
+			}
+		],
+		'Sales Invoice Item': [
+			{
+				'fieldname': 'reference_dt', 'label': 'Reference DocType', 'fieldtype': 'Link', 'options': 'DocType',
+				'insert_after': 'edit_references'
+			},
+			{
+				'fieldname': 'reference_dn', 'label': 'Reference Name', 'fieldtype': 'Dynamic Link', 'options': 'reference_dt',
+				'insert_after': 'reference_dt'
+			}
+		]
 	},
 	'on_setup': 'erpnext.healthcare.setup.setup_healthcare'
 }
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
index cb11ece..3234e7a 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
@@ -3,8 +3,12 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
-import frappe, time, dateutil, math, csv, StringIO
-import amazon_mws_api as mws
+import frappe, time, dateutil, math, csv
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import StringIO
+import erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_api as mws
 from frappe import _
 
 #Get and Create Products
@@ -22,7 +26,7 @@
 			listings_response = reports.get_report(report_id=report_id)
 
 			#Get ASIN Codes
-			string_io = StringIO.StringIO(listings_response.original)
+			string_io = StringIO(listings_response.original)
 			csv_rows = list(csv.reader(string_io, delimiter=str('\t')))
 			asin_list = list(set([row[1] for row in csv_rows[1:]]))
 			#break into chunks of 10
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py
index 798e637..bf6d85b 100755
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py
@@ -9,7 +9,7 @@
 import hashlib
 import hmac
 import base64
-import xml_utils
+from erpnext.erpnext_integrations.doctype.amazon_mws_settings import xml_utils
 import re
 try:
 	from xml.etree.ElementTree import ParseError as XMLError
@@ -196,7 +196,7 @@
 			except XMLError:
 				parsed_response = DataWrapper(data, response.headers)
 
-		except HTTPError, e:
+		except HTTPError as e:
 			error = MWSError(str(e))
 			error.response = e.response
 			raise error
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json
index 771d1f2..607ca4f 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.json
@@ -864,7 +864,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "default": "1", 
+   "default": "", 
    "description": "Check this to enable a scheduled Daily synchronization routine via scheduler", 
    "fieldname": "enable_synch", 
    "fieldtype": "Check", 
@@ -935,7 +935,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-23 20:52:58.471424", 
+ "modified": "2018-09-07 16:45:44.439834", 
  "modified_by": "Administrator", 
  "module": "ERPNext Integrations", 
  "name": "Amazon MWS Settings", 
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
index 7e64915..249a73f 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
@@ -7,12 +7,15 @@
 from frappe.model.document import Document
 import dateutil
 from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-from amazon_methods import get_products_details, get_orders
+from erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_methods import get_products_details, get_orders
 
 class AmazonMWSSettings(Document):
 	def validate(self):
 		if self.enable_amazon == 1:
+			self.enable_synch = 1
 			setup_custom_fields()
+		else:
+			self.enable_synch = 0
 
 	def get_products_details(self):
 		if self.enable_amazon == 1:
@@ -25,7 +28,7 @@
 
 def schedule_get_order_details():
 	mws_settings = frappe.get_doc("Amazon MWS Settings")
-	if mws_settings.enable_synch:
+	if mws_settings.enable_synch and mws_settings.enable_amazon:
 		after_date = dateutil.parser.parse(mws_settings.after_date).strftime("%Y-%m-%d")
 		get_orders(after_date = after_date)
 
diff --git a/erpnext/healthcare/doctype/appointment_type/appointment_type.json b/erpnext/healthcare/doctype/appointment_type/appointment_type.json
index 4dc40b1..ceabce2 100644
--- a/erpnext/healthcare/doctype/appointment_type/appointment_type.json
+++ b/erpnext/healthcare/doctype/appointment_type/appointment_type.json
@@ -1,7 +1,7 @@
 {
  "allow_copy": 0, 
  "allow_guest_to_view": 0, 
- "allow_import": 0, 
+ "allow_import": 1, 
  "allow_rename": 1, 
  "autoname": "field:appointment_type", 
  "beta": 1, 
@@ -152,7 +152,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-06-13 00:04:24.597019", 
+ "modified": "2018-08-08 12:57:54.544216", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Appointment Type", 
@@ -208,5 +208,6 @@
  "sort_order": "DESC", 
  "title_field": "", 
  "track_changes": 0, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
index 9fc5b37..7f866e1 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
@@ -264,21 +264,20 @@
 		let args = null;
 		if(d.item_code) {
 			args = {
-				'item_code'			: d.item_code,
-				'transfer_qty'		: d.transfer_qty,
-				'company'			: frm.doc.company,
-				'quantity'				: d.qty
+				'doctype' : "Clinical Procedure",
+				'item_code' : d.item_code,
+				'company' : frm.doc.company,
+				'warehouse': frm.doc.warehouse
 			};
 			return frappe.call({
-				doc: frm.doc,
-				method: "get_item_details",
-				args: args,
+				method: "erpnext.stock.get_item_details.get_item_details",
+				args: {args: args},
 				callback: function(r) {
 					if(r.message) {
-						var d = locals[cdt][cdn];
-						$.each(r.message, function(k, v){
-							d[k] = v;
-						});
+						frappe.model.set_value(cdt, cdn, "item_name", r.message.item_name);
+						frappe.model.set_value(cdt, cdn, "stock_uom", r.message.stock_uom);
+						frappe.model.set_value(cdt, cdn, "conversion_factor", r.message.conversion_factor);
+						frappe.model.set_value(cdt, cdn, "actual_qty", r.message.actual_qty);
 						refresh_field("items");
 					}
 				}
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
index 04b96e9..c755b7f 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
@@ -252,6 +252,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "prescription", 
+   "fieldtype": "Link", 
+   "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": "Procedure Prescription", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Procedure Prescription", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "medical_department", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -480,7 +513,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "is_invoiced", 
+   "default": "0", 
+   "fieldname": "invoiced", 
    "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -489,9 +523,9 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Is Invoiced", 
+   "label": "Invoiced", 
    "length": 0, 
-   "no_copy": 0, 
+   "no_copy": 1, 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -677,6 +711,139 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "0", 
+   "fieldname": "invoice_separately_as_consumables", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Consumables Invoice Separately", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "depends_on": "invoice_separately_as_consumables", 
+   "fieldname": "consumable_total_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Consumable Total Amount", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "depends_on": "invoice_separately_as_consumables", 
+   "fieldname": "consumption_details", 
+   "fieldtype": "Small Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Consumption Details", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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", 
+   "depends_on": "invoice_separately_as_consumables", 
+   "fieldname": "consumption_invoiced", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Consumption Invoiced", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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": "", 
    "fieldname": "status", 
    "fieldtype": "Select", 
@@ -745,10 +912,11 @@
  "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "restrict_to_domain": "Healthcare", 
  "show_name_in_global_search": 0, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
  "track_seen": 0, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
index 97d8a02..6d00c25 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
@@ -10,20 +10,29 @@
 from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
 from erpnext.healthcare.doctype.lab_test.lab_test import create_sample_doc
 from erpnext.stock.stock_ledger import get_previous_sle
+from erpnext.stock.get_item_details import get_item_details
 
 class ClinicalProcedure(Document):
 	def validate(self):
 		if self.consume_stock and not self.status == 'Draft':
 			if not self.warehouse:
-				frappe.throw(("Set warehouse for Procedure {0} ").format(self.name))
+				frappe.throw(_("Set warehouse for Procedure {0} ").format(self.name))
 			self.set_actual_qty()
 
+		if self.items:
+			self.invoice_separately_as_consumables = False
+			for item in self.items:
+				if item.invoice_separately_as_consumables == 1:
+					self.invoice_separately_as_consumables = True
+
 	def before_insert(self):
 		if self.consume_stock:
 			set_stock_items(self, self.procedure_template, "Clinical Procedure Template")
 			self.set_actual_qty();
 
 	def after_insert(self):
+		if self.prescription:
+			frappe.db.set_value("Procedure Prescription", self.prescription, "procedure_created", 1)
 		if self.appointment:
 			frappe.db.set_value("Patient Appointment", self.appointment, "status", "Closed")
 		template = frappe.get_doc("Clinical Procedure Template", self.procedure_template)
@@ -38,6 +47,36 @@
 			create_stock_entry(self)
 		frappe.db.set_value("Clinical Procedure", self.name, "status", 'Completed')
 
+		if self.items:
+			consumable_total_amount = 0
+			consumption_details = False
+			for item in self.items:
+				if item.invoice_separately_as_consumables:
+					price_list, price_list_currency = frappe.db.get_values("Price List", {"selling": 1}, ['name', 'currency'])[0]
+					args = {
+						'doctype': "Sales Invoice",
+						'item_code': item.item_code,
+						'company': self.company,
+						'warehouse': self.warehouse,
+						'customer': frappe.db.get_value("Patient", self.patient, "customer"),
+						'selling_price_list': price_list,
+						'price_list_currency': price_list_currency,
+						'plc_conversion_rate': 1.0,
+						'conversion_rate': 1.0
+					}
+					item_details = get_item_details(args)
+					item_price = item_details.price_list_rate * item.transfer_qty
+					item_consumption_details = item_details.item_name+"\t"+str(item.qty)+" "+item.uom+"\t"+str(item_price)
+					consumable_total_amount += item_price
+					if not consumption_details:
+						consumption_details = "Clinical Procedure ("+self.name+"):\n\t"+item_consumption_details
+					else:
+						consumption_details += "\n\t"+item_consumption_details
+			if consumable_total_amount > 0:
+				frappe.db.set_value("Clinical Procedure", self.name, "consumable_total_amount", consumable_total_amount)
+				frappe.db.set_value("Clinical Procedure", self.name, "consumption_details", consumption_details)
+
+
 	def start(self):
 		allow_start = self.set_actual_qty()
 		if allow_start:
@@ -52,16 +91,7 @@
 
 		allow_start = True
 		for d in self.get('items'):
-			previous_sle = get_previous_sle({
-				"item_code": d.item_code,
-				"warehouse": self.warehouse,
-				"posting_date": nowdate(),
-				"posting_time": nowtime()
-			})
-
-			# get actual stock at source warehouse
-			d.actual_qty = previous_sle.get("qty_after_transaction") or 0
-
+			d.actual_qty = get_stock_qty(d.item_code, self.warehouse)
 			# validate qty
 			if not allow_negative_stock and d.actual_qty < d.qty:
 				allow_start = False
@@ -91,28 +121,14 @@
 				se_child.expense_account = expense_account
 		return stock_entry.as_dict()
 
-	def get_item_details(self, args=None):
-		item = frappe.db.sql("""select stock_uom, description, image, item_name,
-			expense_account, buying_cost_center, item_group from `tabItem`
-			where name = %s
-				and disabled=0
-				and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)""",
-			(args.get('item_code'), nowdate()), as_dict = 1)
-		if not item:
-			frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get('item_code')))
-
-		item = item[0]
-
-		ret = {
-			'uom'			      	: item.stock_uom,
-			'stock_uom'			  	: item.stock_uom,
-			'item_name' 		  	: item.item_name,
-			'quantity'				: 0,
-			'transfer_qty'			: 0,
-			'conversion_factor'		: 1
-		}
-		return ret
-
+@frappe.whitelist()
+def get_stock_qty(item_code, warehouse):
+	return get_previous_sle({
+		"item_code": item_code,
+		"warehouse": warehouse,
+		"posting_date": nowdate(),
+		"posting_time": nowtime()
+	}).get("qty_after_transaction") or 0
 
 @frappe.whitelist()
 def set_stock_items(doc, stock_detail_parent, parenttype):
@@ -130,6 +146,8 @@
 		se_child.conversion_factor = flt(d["conversion_factor"])
 		if d["batch_no"]:
 			se_child.batch_no = d["batch_no"]
+		if parenttype == "Clinical Procedure Template":
+			se_child.invoice_separately_as_consumables = d["invoice_separately_as_consumables"]
 	return doc
 
 def get_item_dict(table, parent, parenttype):
@@ -165,6 +183,8 @@
 	procedure.patient_age = appointment.patient_age
 	procedure.patient_sex = appointment.patient_sex
 	procedure.procedure_template = appointment.procedure_template
+	procedure.procedure_prescription = appointment.procedure_prescription
+	procedure.invoiced = appointment.invoiced
 	procedure.medical_department = appointment.department
 	procedure.start_date = appointment.appointment_date
 	procedure.start_time = appointment.appointment_time
diff --git a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
index c0a3247..a974f21 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
@@ -14,6 +14,7 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 1, 
    "collapsible": 0, 
@@ -46,6 +47,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -77,6 +79,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -108,6 +111,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -139,6 +143,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -171,6 +176,39 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "invoice_separately_as_consumables", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Invoice Separately as Consumables", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
@@ -201,6 +239,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -233,6 +272,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -264,6 +304,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -296,6 +337,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -327,6 +369,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -367,7 +410,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-03-28 14:34:03.796229", 
+ "modified": "2018-07-26 17:05:29.402908", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Clinical Procedure Item", 
@@ -381,5 +424,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
index 35c0ff5..df56918 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
@@ -1,7 +1,7 @@
 {
  "allow_copy": 0, 
  "allow_guest_to_view": 0, 
- "allow_import": 0, 
+ "allow_import": 1, 
  "allow_rename": 1, 
  "autoname": "field:template", 
  "beta": 1, 
@@ -16,6 +16,7 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -43,11 +44,12 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
+   "translatable": 0, 
+   "unique": 1
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -75,11 +77,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -107,11 +110,12 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -139,11 +143,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -169,11 +174,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -200,11 +206,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -232,11 +239,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -263,11 +271,12 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -294,11 +303,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -325,11 +335,12 @@
    "reqd": 0, 
    "search_index": 1, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -357,11 +368,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -389,11 +401,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 1, 
@@ -421,11 +434,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -453,16 +467,17 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fetch_from": "sample.sample_uom",
+   "fetch_from": "sample.sample_uom", 
    "fieldname": "sample_uom", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -486,11 +501,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -517,11 +533,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -547,11 +564,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -578,11 +596,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -609,11 +628,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -640,11 +660,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -672,7 +693,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -686,7 +707,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-05-16 22:43:29.674822",
+ "modified": "2018-08-08 13:00:06.260997", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Clinical Procedure Template", 
@@ -780,5 +801,6 @@
  "sort_order": "DESC", 
  "title_field": "template", 
  "track_changes": 1, 
- "track_seen": 1
-}
+ "track_seen": 1, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/fee_validity/fee_validity.py b/erpnext/healthcare/doctype/fee_validity/fee_validity.py
index 53a1741..9028545 100644
--- a/erpnext/healthcare/doctype/fee_validity/fee_validity.py
+++ b/erpnext/healthcare/doctype/fee_validity/fee_validity.py
@@ -4,6 +4,33 @@
 
 from __future__ import unicode_literals
 from frappe.model.document import Document
+import frappe
+from frappe.utils import getdate
+import datetime
 
 class FeeValidity(Document):
 	pass
+
+def update_fee_validity(fee_validity, date, ref_invoice=None):
+	max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
+	valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
+	if not valid_days:
+		valid_days = 1
+	if not max_visit:
+		max_visit = 1
+	date = getdate(date)
+	valid_till = date + datetime.timedelta(days=int(valid_days))
+	fee_validity.max_visit = max_visit
+	fee_validity.visited = 1
+	fee_validity.valid_till = valid_till
+	fee_validity.ref_invoice = ref_invoice
+	fee_validity.save(ignore_permissions=True)
+	return fee_validity
+
+
+def create_fee_validity(practitioner, patient, date, ref_invoice=None):
+	fee_validity = frappe.new_doc("Fee Validity")
+	fee_validity.practitioner = practitioner
+	fee_validity.patient = patient
+	fee_validity = update_fee_validity(fee_validity, date, ref_invoice)
+	return fee_validity
diff --git a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
index 64222ad..b8305d7 100644
--- a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
+++ b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
@@ -5,33 +5,35 @@
 
 import frappe
 import unittest
-from erpnext.healthcare.doctype.patient_appointment.patient_appointment import invoice_appointment
 from frappe.utils.make_random import get_random
-from frappe.utils import nowdate, add_days
-# test_records = frappe.get_test_records('Fee Validity')
+from frappe.utils import nowdate, add_days, getdate
+
+test_dependencies = ["Company"]
 
 class TestFeeValidity(unittest.TestCase):
 	def test_fee_validity(self):
+		frappe.db.sql("""delete from `tabPatient Appointment`""")
+		frappe.db.sql("""delete from `tabFee Validity`""")
 		patient = get_random("Patient")
 		practitioner = get_random("Healthcare Practitioner")
 		department = get_random("Medical Department")
 
 		if not patient:
 			patient = frappe.new_doc("Patient")
-			patient.patient_name = "Test Patient"
+			patient.patient_name = "_Test Patient"
 			patient.sex = "Male"
 			patient.save(ignore_permissions=True)
 			patient = patient.name
 
 		if not department:
 			medical_department = frappe.new_doc("Medical Department")
-			medical_department.department = "Test Medical Department"
+			medical_department.department = "_Test Medical Department"
 			medical_department.save(ignore_permissions=True)
 			department = medical_department.name
 
 		if not practitioner:
 			practitioner = frappe.new_doc("Healthcare Practitioner")
-			practitioner.first_name = "Amit Jain"
+			practitioner.first_name = "_Test Healthcare Practitioner"
 			practitioner.department = department
 			practitioner.save(ignore_permissions=True)
 			practitioner = practitioner.name
@@ -42,18 +44,22 @@
 		frappe.db.set_value("Healthcare Settings", None, "valid_days", 7)
 
 		appointment = create_appointment(patient, practitioner, nowdate(), department)
-		invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
-		self.assertEqual(invoice, None)
+		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
+		self.assertEqual(invoiced, 0)
+
 		invoice_appointment(appointment)
+
 		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 4), department)
-		invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
-		self.assertTrue(invoice)
+		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
+		self.assertTrue(invoiced)
+
 		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 5), department)
-		invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
-		self.assertEqual(invoice, None)
+		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
+		self.assertEqual(invoiced, 0)
+
 		appointment = create_appointment(patient, practitioner, add_days(nowdate(), 10), department)
-		invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
-		self.assertEqual(invoice, None)
+		invoiced = frappe.db.get_value("Patient Appointment", appointment.name, "invoiced")
+		self.assertEqual(invoiced, 0)
 
 def create_appointment(patient, practitioner, appointment_date, department):
 	appointment = frappe.new_doc("Patient Appointment")
@@ -64,3 +70,34 @@
 	appointment.company = "_Test Company"
 	appointment.save(ignore_permissions=True)
 	return appointment
+
+def invoice_appointment(appointment_doc):
+	if not appointment_doc.name:
+		return False
+	sales_invoice = frappe.new_doc("Sales Invoice")
+	sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
+	sales_invoice.due_date = getdate()
+	sales_invoice.is_pos = 0
+	sales_invoice.company = appointment_doc.company
+	sales_invoice.debit_to = "_Test Receivable - _TC"
+
+	create_invoice_items(appointment_doc, sales_invoice)
+
+	sales_invoice.save(ignore_permissions=True)
+	sales_invoice.submit()
+
+def create_invoice_items(appointment, invoice):
+	item_line = invoice.append("items")
+	item_line.item_name = "Consulting Charges"
+	item_line.description = "Consulting Charges:  " + appointment.practitioner
+	item_line.uom = "Nos"
+	item_line.conversion_factor = 1
+	item_line.income_account = "_Test Account Cost for Goods Sold - _TC"
+	item_line.cost_center = "_Test Cost Center - _TC"
+	item_line.rate = 250
+	item_line.amount = 250
+	item_line.qty = 1
+	item_line.reference_dt = "Patient Appointment"
+	item_line.reference_dn = appointment.name
+
+	return invoice
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
index f2dc849..efca484 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
@@ -27,9 +27,22 @@
 				}
 			};
 		});
+		set_query_service_item(frm, 'inpatient_visit_charge_item');
+		set_query_service_item(frm, 'op_consulting_charge_item');
 	}
 });
 
+var set_query_service_item = function(frm, service_item_field) {
+	frm.set_query(service_item_field, function() {
+		return {
+			filters: {
+				'is_sales_item': 1,
+				'is_stock_item': 0
+			}
+		};
+	});
+};
+
 frappe.ui.form.on("Healthcare Practitioner", "user_id",function(frm) {
 	if(frm.doc.user_id){
 		frappe.call({
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
index e7c575d..ad68924 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
@@ -201,7 +201,7 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -535,6 +535,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "op_consulting_charge_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Out Patient Consulting Charge Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "op_consulting_charge", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -568,6 +601,102 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "column_break_18", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "inpatient_visit_charge_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Inpatient Visit Charge Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "inpatient_visit_charge", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Inpatient Visit Charge", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "contacts_and_address", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -798,7 +927,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-07-10 11:18:58.760297", 
+ "modified": "2018-08-06 16:45:37.899084", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Healthcare Practitioner", 
@@ -873,5 +1002,6 @@
  "sort_order": "DESC", 
  "title_field": "first_name", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
index 753ecd1..8a087dd 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
@@ -21,6 +21,10 @@
 
 	def validate(self):
 		validate_party_accounts(self)
+		if self.inpatient_visit_charge_item:
+			validate_service_item(self.inpatient_visit_charge_item, "Configure a service Item for Inpatient Visit Charge Item")
+		if self.op_consulting_charge_item:
+			validate_service_item(self.op_consulting_charge_item, "Configure a service Item for Out Patient Consulting Charge Item")
 
 		if self.user_id:
 			self.validate_for_enabled_user_id()
@@ -57,3 +61,7 @@
 
 	def on_trash(self):
 		delete_contact_and_address('Healthcare Practitioner', self.name)
+
+def validate_service_item(item, msg):
+	if frappe.db.get_value("Item", item, "is_stock_item") == 1:
+		frappe.throw(_(msg))
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
index 3c01ab0..635464e 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
@@ -9,10 +9,6 @@
 			{
 				'label': _('Appointments and Patient Encounters'),
 				'items': ['Patient Appointment', 'Patient Encounter']
-			},
-			{
-				'label': _('Lab Tests'),
- 				'items': ['Lab Test']
 			}
 		]
 	}
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
index 945817c..7d6b6c1 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
@@ -1,7 +1,7 @@
 {
  "allow_copy": 0, 
  "allow_guest_to_view": 0, 
- "allow_import": 0, 
+ "allow_import": 1, 
  "allow_rename": 1, 
  "autoname": "field:healthcare_service_unit_name", 
  "beta": 1, 
@@ -43,7 +43,7 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "translatable": 0, 
-   "unique": 0
+   "unique": 1
   }, 
   {
    "allow_bulk_edit": 0, 
@@ -116,7 +116,7 @@
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
-   "bold": 0, 
+   "bold": 1, 
    "collapsible": 0, 
    "columns": 0, 
    "depends_on": "eval:doc.is_group != 1", 
@@ -246,7 +246,7 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -258,10 +258,10 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "default": "0", 
+   "default": "", 
    "depends_on": "eval:doc.inpatient_occupancy == 1", 
-   "fieldname": "occupied", 
-   "fieldtype": "Check", 
+   "fieldname": "occupancy_status", 
+   "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -269,9 +269,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Occupied", 
+   "label": "Occupancy Status", 
    "length": 0, 
    "no_copy": 1, 
+   "options": "Vacant\nOccupied", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -460,7 +461,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-07-17 17:40:18.867327", 
+ "modified": "2018-08-08 12:57:12.709806", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Healthcare Service Unit", 
@@ -535,5 +536,6 @@
  "sort_order": "DESC", 
  "title_field": "healthcare_service_unit_name", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
index 4eb9475..a03b579 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
@@ -1,3 +1,35 @@
 frappe.treeview_settings["Healthcare Service Unit"] = {
-	ignore_fields:["parent_healthcare_service_unit"]
+	breadcrumbs: "Healthcare Service Unit",
+	title: __("Healthcare Service Unit"),
+	get_tree_root: false,
+	filters: [{
+		fieldname: "company",
+		fieldtype: "Select",
+		options: erpnext.utils.get_tree_options("company"),
+		label: __("Company"),
+		default: erpnext.utils.get_tree_default("company")
+	}],
+	get_tree_nodes: 'erpnext.healthcare.utils.get_children',
+	ignore_fields:["parent_healthcare_service_unit"],
+	onrender: function(node) {
+		if (node.data.occupied_out_of_vacant!==undefined){
+			$('<span class="balance-area pull-right text-muted small">'
+				+ " " + node.data.occupied_out_of_vacant
+				+ '</span>').insertBefore(node.$ul);
+		}
+		if (node.data && node.data.inpatient_occupancy!==undefined) {
+			if (node.data.inpatient_occupancy == 1){
+				if (node.data.occupancy_status == "Occupied"){
+					$('<span class="balance-area pull-right small">'
+						+ " " + node.data.occupancy_status
+						+ '</span>').insertBefore(node.$ul);
+				}
+				if (node.data.occupancy_status == "Vacant"){
+					$('<span class="balance-area pull-right text-muted small">'
+						+ " " + node.data.occupancy_status
+						+ '</span>').insertBefore(node.$ul);
+				}
+			}
+		}
+	},
 };
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
index 6394ce7..40681e9 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
@@ -1,8 +1,8 @@
 {
  "allow_copy": 0, 
  "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
+ "allow_import": 1, 
+ "allow_rename": 1, 
  "autoname": "field:service_unit_type", 
  "beta": 0, 
  "creation": "2018-07-11 16:47:51.414675", 
@@ -43,7 +43,7 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "translatable": 0, 
-   "unique": 0
+   "unique": 1
   }, 
   {
    "allow_bulk_edit": 0, 
@@ -351,8 +351,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "rate", 
-   "fieldtype": "Currency", 
+   "fieldname": "no_of_hours", 
+   "fieldtype": "Int", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -360,7 +360,7 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Rate / UOM", 
+   "label": "UOM Conversion in Hours", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -414,6 +414,38 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "rate", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Rate / UOM", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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": "disabled", 
    "fieldtype": "Check", 
@@ -515,7 +547,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-07-13 16:54:59.131606", 
+ "modified": "2018-08-08 13:00:23.751635", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Healthcare Service Unit Type", 
@@ -545,10 +577,12 @@
  "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "restrict_to_domain": "Healthcare", 
  "show_name_in_global_search": 0, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "title_field": "service_unit_type", 
  "track_changes": 0, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
index e0d380b..727d035 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
@@ -8,6 +8,11 @@
 from frappe.model.document import Document
 
 class HealthcareServiceUnitType(Document):
+	def validate(self):
+		if self.is_billable == 1:
+			if not self.uom or not self.item_group or not self.description or not self.no_of_hours > 0:
+				frappe.throw(_("Configure Item Fields like UOM, Item Group, Description and No of Hours."))
+
 	def after_insert(self):
 		if self.inpatient_occupancy and self.is_billable:
 			create_item(self)
@@ -22,13 +27,16 @@
 	def on_update(self):
 		if(self.change_in_item and self.is_billable == 1 and self.item):
 			updating_item(self)
-			if not item_price_exist(self):
-				if(self.test_rate != 0.0):
+			item_price = item_price_exist(self)
+			if not item_price:
+				if(self.rate != 0.0):
 					price_list_name = frappe.db.get_value("Price List", {"selling": 1})
-					if(self.test_rate):
-						make_item_price(self.test_code, price_list_name, self.test_rate)
+					if(self.rate):
+						make_item_price(self.item_code, price_list_name, self.rate)
 					else:
-						make_item_price(self.test_code, price_list_name, 0.0)
+						make_item_price(self.item_code, price_list_name, 0.0)
+			else:
+				frappe.db.set_value("Item Price", item_price, "price_list_rate", self.rate)
 
 			frappe.db.set_value(self.doctype,self.name,"change_in_item",0)
 		elif(self.is_billable == 0 and self.item):
@@ -40,7 +48,7 @@
 	"doctype": "Item Price",
 	"item_code": doc.item_code})
 	if(item_price):
-		return True
+		return item_price[0][0]
 	else:
 		return False
 
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
index 8e98fee..22fbf50 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.js
@@ -23,5 +23,19 @@
 				}
 			};
 		});
+		set_query_service_item(frm, 'inpatient_visit_charge_item');
+		set_query_service_item(frm, 'op_consulting_charge_item');
+		set_query_service_item(frm, 'clinical_procedure_consumable_item');
 	}
 });
+
+var set_query_service_item = function(frm, service_item_field) {
+	frm.set_query(service_item_field, function() {
+		return {
+			filters: {
+				'is_sales_item': 1,
+				'is_stock_item': 0
+			}
+		};
+	});
+};
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
index 0bd8534..24c3cd9 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
@@ -248,6 +248,40 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "0", 
+   "description": "Manage Appointment Invoice submit and cancel automatically for Patient Encounter", 
+   "fieldname": "manage_appointment_invoice_automatically", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Manage Appointment Invoice Automatically", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "max_visit", 
    "fieldtype": "Int", 
    "hidden": 0, 
@@ -312,6 +346,168 @@
    "bold": 0, 
    "collapsible": 1, 
    "columns": 0, 
+   "fieldname": "healthcare_service_items", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Healthcare Service Items", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "inpatient_visit_charge_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Inpatient Visit Charge Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "op_consulting_charge_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Out Patient Consulting Charge Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "column_break_13", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "clinical_procedure_consumable_item", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Clinical Procedure Consumable Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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": 1, 
+   "columns": 0, 
    "fieldname": "out_patient_sms_alerts", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -804,6 +1000,38 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "create_test_on_si_submit", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Create Lab Test(s) on Sales Invoice Submit", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "description": "Create documents for sample collection", 
    "fieldname": "require_sample_collection", 
    "fieldtype": "Check", 
@@ -1099,7 +1327,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-07-16 14:00:04.171717", 
+ "modified": "2018-08-03 15:18:36.631441", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Healthcare Settings", 
@@ -1134,5 +1362,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
index 8c3cdfe..8555e80 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
@@ -10,13 +10,19 @@
 import json
 
 class HealthcareSettings(Document):
-    def validate(self):
-        for key in ["collect_registration_fee","manage_customer","patient_master_name",
-        "require_test_result_approval","require_sample_collection", "default_medical_code_standard"]:
-            frappe.db.set_default(key, self.get(key, ""))
-        if(self.collect_registration_fee):
-            if self.registration_fee <= 0 :
-                frappe.throw(_("Registration fee can not be Zero"))
+	def validate(self):
+		for key in ["collect_registration_fee","manage_customer","patient_master_name",
+		"require_test_result_approval","require_sample_collection", "default_medical_code_standard"]:
+			frappe.db.set_default(key, self.get(key, ""))
+		if(self.collect_registration_fee):
+			if self.registration_fee <= 0 :
+				frappe.throw(_("Registration fee can not be Zero"))
+		if self.inpatient_visit_charge_item:
+			validate_service_item(self.inpatient_visit_charge_item, "Configure a service Item for Inpatient Visit Charge Item")
+		if self.op_consulting_charge_item:
+			validate_service_item(self.op_consulting_charge_item, "Configure a service Item for Out Patient Consulting Charge Item")
+		if self.clinical_procedure_consumable_item:
+			validate_service_item(self.clinical_procedure_consumable_item, "Configure a service Item for Clinical Procedure Consumable Item")
 
 @frappe.whitelist()
 def get_sms_text(doc):
@@ -67,3 +73,7 @@
     if(parent_field):
         return frappe.db.get_value("Party Account",
             {"parentfield": parent_field, "parent": parent, "company": company}, "account")
+
+def validate_service_item(item, msg):
+	if frappe.db.get_value("Item", item, "is_stock_item") == 1:
+		frappe.throw(_(msg))
diff --git a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
index 2ac498d..62dc198 100644
--- a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
+++ b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
@@ -104,7 +104,7 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -140,6 +140,39 @@
    "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": "invoiced", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Invoiced", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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
   }
  ], 
  "has_web_view": 0, 
@@ -152,7 +185,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-07-17 18:26:46.009878", 
+ "modified": "2018-08-06 16:46:54.699133", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Inpatient Occupancy", 
@@ -166,5 +199,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
index 936c682..67c12f6 100644
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
@@ -94,7 +94,7 @@
 			filters: {
 				"is_group": 0,
 				"service_unit_type": dialog.get_value("service_unit_type"),
-				"occupied" : 0
+				"occupancy_status" : "Vacant"
 			}
 		};
 	};
@@ -166,7 +166,7 @@
 			filters: {
 				"is_group": 0,
 				"service_unit_type": dialog.get_value("service_unit_type"),
-				"occupied" : 0
+				"occupancy_status" : "Vacant"
 			}
 		};
 	};
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
index 50f17e9..92c11fb 100644
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
@@ -968,6 +968,7 @@
  "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "restrict_to_domain": "Healthcare", 
  "search_fields": "patient", 
  "show_name_in_global_search": 0, 
  "sort_field": "modified", 
@@ -976,4 +977,4 @@
  "track_changes": 1, 
  "track_seen": 0, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
index 07cd9e4..c107cd7 100644
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
@@ -69,29 +69,75 @@
 	inpatient_record.save(ignore_permissions = True)
 
 @frappe.whitelist()
-def schedule_discharge(patient, encounter_id, practitioner):
+def schedule_discharge(patient, encounter_id=None, practitioner=None):
 	inpatient_record_id = frappe.db.get_value('Patient', patient, 'inpatient_record')
 	if inpatient_record_id:
 		inpatient_record = frappe.get_doc("Inpatient Record", inpatient_record_id)
 		inpatient_record.discharge_practitioner = practitioner
 		inpatient_record.discharge_encounter = encounter_id
 		inpatient_record.status = "Discharge Scheduled"
+
+		check_out_inpatient(inpatient_record)
+
 		inpatient_record.save(ignore_permissions = True)
 	frappe.db.set_value("Patient", patient, "inpatient_status", "Discharge Scheduled")
 
-def discharge_patient(inpatient_record):
+def check_out_inpatient(inpatient_record):
 	if inpatient_record.inpatient_occupancies:
 		for inpatient_occupancy in inpatient_record.inpatient_occupancies:
 			if inpatient_occupancy.left != 1:
 				inpatient_occupancy.left = True
 				inpatient_occupancy.check_out = now_datetime()
-				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupied", False)
+				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupancy_status", "Vacant")
 
+def discharge_patient(inpatient_record):
+	validate_invoiced_inpatient(inpatient_record)
 	inpatient_record.discharge_date = today()
 	inpatient_record.status = "Discharged"
 
 	inpatient_record.save(ignore_permissions = True)
 
+def validate_invoiced_inpatient(inpatient_record):
+	pending_invoices = []
+	if inpatient_record.inpatient_occupancies:
+		service_unit_names = False
+		for inpatient_occupancy in inpatient_record.inpatient_occupancies:
+			if inpatient_occupancy.invoiced != 1:
+				if service_unit_names:
+					service_unit_names += ", " + inpatient_occupancy.service_unit
+				else:
+					service_unit_names = inpatient_occupancy.service_unit
+		if service_unit_names:
+			pending_invoices.append("Inpatient Occupancy (" + service_unit_names + ")")
+
+	docs = ["Patient Appointment", "Patient Encounter", "Lab Test", "Clinical Procedure"]
+
+	for doc in docs:
+		doc_name_list = get_inpatient_docs_not_invoiced(doc, inpatient_record)
+		if doc_name_list:
+			pending_invoices = get_pending_doc(doc, doc_name_list, pending_invoices)
+
+	if pending_invoices:
+		frappe.throw(_("Can not mark Inpatient Record Discharged, there are Unbilled Invoices {0}").format(", "
+			.join(pending_invoices)))
+
+def get_pending_doc(doc, doc_name_list, pending_invoices):
+	if doc_name_list:
+		doc_ids = False
+		for doc_name in doc_name_list:
+			if doc_ids:
+				doc_ids += ", "+doc_name.name
+			else:
+				doc_ids = doc_name.name
+		if doc_ids:
+			pending_invoices.append(doc + " (" + doc_ids + ")")
+
+	return pending_invoices
+
+def get_inpatient_docs_not_invoiced(doc, inpatient_record):
+	return frappe.db.get_list(doc, filters = {"patient": inpatient_record.patient,
+					"inpatient_record": inpatient_record.name, "invoiced": 0})
+
 def admit_patient(inpatient_record, service_unit, check_in, expected_discharge=None):
 	inpatient_record.admitted_datetime = check_in
 	inpatient_record.status = "Admitted"
@@ -110,7 +156,7 @@
 
 	inpatient_record.save(ignore_permissions = True)
 
-	frappe.db.set_value("Healthcare Service Unit", service_unit, "occupied", True)
+	frappe.db.set_value("Healthcare Service Unit", service_unit, "occupancy_status", "Occupied")
 
 def patient_leave_service_unit(inpatient_record, check_out, leave_from):
 	if inpatient_record.inpatient_occupancies:
@@ -118,7 +164,7 @@
 			if inpatient_occupancy.left != 1 and inpatient_occupancy.service_unit == leave_from:
 				inpatient_occupancy.left = True
 				inpatient_occupancy.check_out = check_out
-				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupied", False)
+				frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupancy_status", "Vacant")
 	inpatient_record.save(ignore_permissions = True)
 
 @frappe.whitelist()
diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
index b192064..8849748 100644
--- a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
@@ -7,10 +7,11 @@
 import unittest
 from frappe.utils import now_datetime, today
 from frappe.utils.make_random import get_random
-from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient
+from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient, schedule_discharge
 
 class TestInpatientRecord(unittest.TestCase):
 	def test_admit_and_discharge(self):
+		frappe.db.sql("""delete from `tabInpatient Record`""")
 		patient = get_patient()
 		# Schedule Admission
 		ip_record = create_inpatient(patient)
@@ -22,13 +23,21 @@
 		service_unit = get_healthcare_service_unit()
 		admit_patient(ip_record, service_unit, now_datetime())
 		self.assertEqual("Admitted", frappe.db.get_value("Patient", patient, "inpatient_status"))
-		self.assertEqual(1, frappe.db.get_value("Healthcare Service Unit", service_unit, "occupied"))
+		self.assertEqual("Occupied", frappe.db.get_value("Healthcare Service Unit", service_unit, "occupancy_status"))
 
 		# Discharge
-		discharge_patient(ip_record)
+		schedule_discharge(patient=patient)
+		self.assertEqual("Vacant", frappe.db.get_value("Healthcare Service Unit", service_unit, "occupancy_status"))
+
+		ip_record1 = frappe.get_doc("Inpatient Record", ip_record.name)
+		# Validate Pending Invoices
+		self.assertRaises(frappe.ValidationError, ip_record.discharge)
+		mark_invoiced_inpatient_occupancy(ip_record1)
+
+		discharge_patient(ip_record1)
+
 		self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_record"))
 		self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_status"))
-		self.assertEqual(0, frappe.db.get_value("Healthcare Service Unit", service_unit, "occupied"))
 
 	def test_validate_overlap_admission(self):
 		frappe.db.sql("""delete from `tabInpatient Record`""")
@@ -45,6 +54,12 @@
 		self.assertRaises(frappe.ValidationError, ip_record_new.save)
 		frappe.db.sql("""delete from `tabInpatient Record`""")
 
+def mark_invoiced_inpatient_occupancy(ip_record):
+	if ip_record.inpatient_occupancies:
+		for inpatient_occupancy in ip_record.inpatient_occupancies:
+			inpatient_occupancy.invoiced = 1
+		ip_record.save(ignore_permissions = True)
+
 def create_inpatient(patient):
 	patient_obj = frappe.get_doc('Patient', patient)
 	inpatient_record = frappe.new_doc('Inpatient Record')
@@ -78,7 +93,7 @@
 		service_unit.healthcare_service_unit_name = "Test Service Unit Ip Occupancy"
 		service_unit.service_unit_type = get_service_unit_type()
 		service_unit.inpatient_occupancy = 1
-		service_unit.occupied = 0
+		service_unit.occupancy_status = "Vacant"
 		service_unit.is_group = 0
 		service_unit_parent_name = frappe.db.exists({
 				"doctype": "Healthcare Service Unit",
diff --git a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json b/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
index 127bebf..ce6b206 100644
--- a/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
+++ b/erpnext/healthcare/doctype/lab_prescription/lab_prescription.json
@@ -13,6 +13,7 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -40,16 +41,17 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fetch_from": "test_code.test_name",
+   "fetch_from": "test_code.test_name", 
    "fieldname": "test_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -73,17 +75,19 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -91,10 +95,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
-   "no_copy": 0, 
-   "options": "Sales Invoice", 
+   "no_copy": 1, 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -103,13 +107,14 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -135,11 +140,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -166,11 +172,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -195,9 +202,9 @@
    "remember_last_selected_value": 0, 
    "report_hide": 1, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -211,7 +218,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-05-16 22:43:39.014193",
+ "modified": "2018-08-06 16:53:02.033406", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Lab Prescription", 
@@ -226,5 +233,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 0, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.js b/erpnext/healthcare/doctype/lab_test/lab_test.js
index c3b069d..06637bc 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.js
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.js
@@ -24,11 +24,6 @@
 	refresh :  function(frm){
 		refresh_field('normal_test_items');
 		refresh_field('special_test_items');
-		if(!frm.doc.__islocal && !frm.doc.invoice && frappe.user.has_role("Accounts User")){
-			frm.add_custom_button(__('Make Invoice'), function() {
-				make_invoice(frm);
-			});
-		}
 		if(frm.doc.__islocal){
 			frm.add_custom_button(__('Get from Patient Encounter'), function () {
 				get_lab_test_prescribed(frm);
@@ -166,8 +161,8 @@
 		<div class="col-xs-1">\
 		<a data-name="%(name)s" data-lab-test="%(lab_test)s"\
 		data-encounter="%(encounter)s" data-practitioner="%(practitioner)s"\
-		data-invoice="%(invoice)s" href="#"><button class="btn btn-default btn-xs">Get Lab Test\
-		</button></a></div></div>', {name:y[0], lab_test: y[1], encounter:y[2], invoice:y[3], practitioner:y[4], date:y[5]})).appendTo(html_field);
+		data-invoiced="%(invoiced)s" href="#"><button class="btn btn-default btn-xs">Get Lab Test\
+		</button></a></div></div>', {name:y[0], lab_test: y[1], encounter:y[2], invoiced:y[3], practitioner:y[4], date:y[5]})).appendTo(html_field);
 		row.find("a").click(function() {
 			frm.doc.template = $(this).attr("data-lab-test");
 			frm.doc.prescription = $(this).attr("data-name");
@@ -175,14 +170,11 @@
 			frm.set_df_property("template", "read_only", 1);
 			frm.set_df_property("patient", "read_only", 1);
 			frm.set_df_property("practitioner", "read_only", 1);
-			if($(this).attr("data-invoice") != 'null'){
-				frm.doc.invoice = $(this).attr("data-invoice");
-				refresh_field("invoice");
-			}else {
-				frm.doc.invoice = "";
-				refresh_field("invoice");
+			frm.doc.invoiced = 0;
+			if($(this).attr("data-invoiced") == 1){
+				frm.doc.invoiced = 1;
 			}
-
+			refresh_field("invoiced");
 			refresh_field("template");
 			d.hide();
 			return false;
@@ -195,24 +187,6 @@
 	d.show();
 };
 
-var make_invoice = function(frm){
-	var doc = frm.doc;
-	frappe.call({
-		method: "erpnext.healthcare.doctype.lab_test.lab_test.create_invoice",
-		args: {company:doc.company, patient:doc.patient, lab_tests: [doc.name], prescriptions:[]},
-		callback: function(r){
-			if(!r.exc){
-				if(r.message){
-					/*	frappe.show_alert(__('Sales Invoice {0} created',
-					['<a href="#Form/Sales Invoice/'+r.message+'">' + r.message+ '</a>']));	*/
-					frappe.set_route("Form", "Sales Invoice", r.message);
-				}
-				cur_frm.reload_doc();
-			}
-		}
-	});
-};
-
 cur_frm.cscript.custom_before_submit =  function(doc) {
 	if(doc.normal_test_items){
 		for(let result in doc.normal_test_items){
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.json b/erpnext/healthcare/doctype/lab_test/lab_test.json
index 89b513f..9db3ae5 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.json
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.json
@@ -88,8 +88,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -97,10 +98,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "Sales Invoice", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -1586,7 +1587,7 @@
  "read_only": 0, 
  "read_only_onload": 0, 
  "restrict_to_domain": "Healthcare", 
- "search_fields": "patient,invoice,practitioner,test_name,sample", 
+ "search_fields": "patient,practitioner,test_name,sample", 
  "show_name_in_global_search": 1, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
@@ -1594,4 +1595,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py
index 767581f..98ab696 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.py
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.py
@@ -4,11 +4,9 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe.model.document import Document
-import json
-from frappe.utils import getdate, cstr
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account
 from frappe import _
+from frappe.model.document import Document
+from frappe.utils import getdate, cstr
 
 class LabTest(Document):
 	def on_submit(self):
@@ -31,6 +29,8 @@
 	def after_insert(self):
 		if(self.prescription):
 			frappe.db.set_value("Lab Prescription", self.prescription, "test_created", 1)
+			if frappe.db.get_value("Lab Prescription", self.prescription, 'invoiced') == 1:
+				self.invoiced = True
 		if not self.test_name and self.template:
 			self.load_test_from_template()
 			self.reload()
@@ -60,20 +60,97 @@
 def update_lab_test_print_sms_email_status(print_sms_email, name):
 	frappe.db.set_value("Lab Test",name,print_sms_email,1)
 
-def create_lab_test_doc(invoice, encounter, patient, template):
-	#create Test Result for template, copy vals from Invoice
+@frappe.whitelist()
+def create_multiple(doctype, docname):
+	lab_test_created = False
+	if doctype == "Sales Invoice":
+		lab_test_created = create_lab_test_from_invoice(docname)
+	elif doctype == "Patient Encounter":
+		lab_test_created = create_lab_test_from_encounter(docname)
+
+	if lab_test_created:
+		frappe.msgprint(_("Lab Test(s) "+lab_test_created+" created."))
+	else:
+		frappe.msgprint(_("No Lab Test created"))
+
+def create_lab_test_from_encounter(encounter_id):
+	lab_test_created = False
+	encounter = frappe.get_doc("Patient Encounter", encounter_id)
+
+	lab_test_ids = frappe.db.sql("""select lp.name, lp.test_code, lp.invoiced
+	from `tabPatient Encounter` et, `tabLab Prescription` lp
+	where et.patient=%s and lp.parent=%s and
+	lp.parent=et.name and lp.test_created=0 and et.docstatus=1""", (encounter.patient, encounter_id))
+
+	if lab_test_ids:
+		patient = frappe.get_doc("Patient", encounter.patient)
+		for lab_test_id in lab_test_ids:
+			template = get_lab_test_template(lab_test_id[1])
+			if template:
+				lab_test = create_lab_test_doc(lab_test_id[2], encounter.practitioner, patient, template)
+				lab_test.save(ignore_permissions = True)
+				frappe.db.set_value("Lab Prescription", lab_test_id[0], "test_created", 1)
+				if not lab_test_created:
+					lab_test_created = lab_test.name
+				else:
+					lab_test_created += ", "+lab_test.name
+	return lab_test_created
+
+
+def create_lab_test_from_invoice(invoice_name):
+	lab_test_created = False
+	invoice = frappe.get_doc("Sales Invoice", invoice_name)
+	if invoice.patient:
+		patient = frappe.get_doc("Patient", invoice.patient)
+		for item in invoice.items:
+			test_created = 0
+			if item.reference_dt == "Lab Prescription":
+				test_created = frappe.db.get_value("Lab Prescription", item.reference_dn, "test_created")
+			elif item.reference_dt == "Lab Test":
+				test_created = 1
+			if test_created != 1:
+				template = get_lab_test_template(item.item_code)
+				if template:
+					lab_test = create_lab_test_doc(True, invoice.ref_practitioner, patient, template)
+					if item.reference_dt == "Lab Prescription":
+						lab_test.prescription = item.reference_dn
+					lab_test.save(ignore_permissions = True)
+					if item.reference_dt != "Lab Prescription":
+						frappe.db.set_value("Sales Invoice Item", item.name, "reference_dt", "Lab Test")
+						frappe.db.set_value("Sales Invoice Item", item.name, "reference_dn", lab_test.name)
+					if not lab_test_created:
+						lab_test_created = lab_test.name
+					else:
+						lab_test_created += ", "+lab_test.name
+	return lab_test_created
+
+def get_lab_test_template(item):
+	template_id = check_template_exists(item)
+	if template_id:
+		return frappe.get_doc("Lab Test Template", template_id)
+	return False
+
+def check_template_exists(item):
+	template_exists = frappe.db.exists(
+		"Lab Test Template",
+		{
+			'item': item
+		}
+	)
+	if template_exists:
+		return template_exists
+	return False
+
+def create_lab_test_doc(invoiced, practitioner, patient, template):
 	lab_test = frappe.new_doc("Lab Test")
-	if(invoice):
-		lab_test.invoice = invoice
-	if(encounter):
-		lab_test.practitioner = encounter.practitioner
+	lab_test.invoiced = invoiced
+	lab_test.practitioner = practitioner
 	lab_test.patient = patient.name
 	lab_test.patient_age = patient.get_age()
 	lab_test.patient_sex = patient.sex
 	lab_test.email = patient.email
 	lab_test.mobile = patient.mobile
 	lab_test.department = template.department
-	lab_test.test_name = template.test_name
 	lab_test.template = template.name
 	lab_test.test_group = template.test_group
 	lab_test.result_date = getdate()
@@ -133,7 +210,7 @@
 			#create Sample Collection for template, copy vals from Invoice
 			sample_collection = frappe.new_doc("Sample Collection")
 			if(invoice):
-				sample_collection.invoice = invoice
+				sample_collection.invoiced = True
 			sample_collection.patient = patient.name
 			sample_collection.patient_age = patient.get_age()
 			sample_collection.patient_sex = patient.sex
@@ -146,24 +223,6 @@
 
 		return sample_collection
 
-@frappe.whitelist()
-def create_lab_test_from_desk(patient, template, prescription, invoice=None):
-	lab_test_exist = frappe.db.exists({
-		"doctype": "Lab Test",
-		"prescription": prescription
-		})
-	if lab_test_exist:
-		return
-	template = frappe.get_doc("Lab Test Template", template)
-	#skip the loop if there is no test_template for Item
-	if not (template):
-		return
-	patient = frappe.get_doc("Patient", patient)
-	encounter_id = frappe.get_value("Lab Prescription", prescription, "parent")
-	encounter = frappe.get_doc("Patient Encounter", encounter_id)
-	lab_test = create_lab_test(patient, template, prescription, encounter, invoice)
-	return lab_test.name
-
 def create_sample_collection(lab_test, template, patient, invoice):
 	if(frappe.db.get_value("Healthcare Settings", None, "require_sample_collection") == "1"):
 		sample_collection = create_sample_doc(template, patient, invoice)
@@ -211,16 +270,10 @@
 		if(prescription):
 			lab_test.prescription = prescription
 			if(invoice):
-				frappe.db.set_value("Lab Prescription", prescription, "invoice", invoice)
+				frappe.db.set_value("Lab Prescription", prescription, "invoiced", True)
 		lab_test.save(ignore_permissions=True) # insert the result
 		return lab_test
 
-def create_lab_test(patient, template, prescription,  encounter, invoice):
-	lab_test = create_lab_test_doc(invoice, encounter, patient, template)
-	lab_test = create_sample_collection(lab_test, template, patient, invoice)
-	lab_test = load_result_format(lab_test, template, prescription, invoice)
-	return lab_test
-
 @frappe.whitelist()
 def get_employee_by_user_id(user_id):
 	emp_id = frappe.db.get_value("Employee",{"user_id":user_id})
@@ -248,49 +301,7 @@
 	if medical_record_id and medical_record_id[0][0]:
 		frappe.delete_doc("Patient Medical Record", medical_record_id[0][0])
 
-def create_item_line(test_code, sales_invoice):
-	if test_code:
-		item = frappe.get_doc("Item", test_code)
-		if item:
-			if not item.disabled:
-				sales_invoice_line = sales_invoice.append("items")
-				sales_invoice_line.item_code = item.item_code
-				sales_invoice_line.item_name =  item.item_name
-				sales_invoice_line.qty = 1.0
-				sales_invoice_line.description = item.description
-
-@frappe.whitelist()
-def create_invoice(company, patient, lab_tests, prescriptions):
-	test_ids = json.loads(lab_tests)
-	line_ids = json.loads(prescriptions)
-	if not test_ids and not line_ids:
-		return
-	sales_invoice = frappe.new_doc("Sales Invoice")
-	sales_invoice.customer = frappe.get_value("Patient", patient, "customer")
-	sales_invoice.due_date = getdate()
-	sales_invoice.is_pos = '0'
-	sales_invoice.debit_to = get_receivable_account(company)
-	for line in line_ids:
-		test_code = frappe.get_value("Lab Prescription", line, "test_code")
-		create_item_line(test_code, sales_invoice)
-	for test in test_ids:
-		template = frappe.get_value("Lab Test", test, "template")
-		test_code = frappe.get_value("Lab Test Template", template, "item")
-		create_item_line(test_code, sales_invoice)
-	sales_invoice.set_missing_values()
-	sales_invoice.save()
-	#set invoice in lab test
-	for test in test_ids:
-		frappe.db.set_value("Lab Test", test, "invoice", sales_invoice.name)
-		prescription = frappe.db.get_value("Lab Test", test, "prescription")
-		if prescription:
-			frappe.db.set_value("Lab Prescription", prescription, "invoice", sales_invoice.name)
-	#set invoice in prescription
-	for line in line_ids:
-		frappe.db.set_value("Lab Prescription", line, "invoice", sales_invoice.name)
-	return sales_invoice.name
-
 @frappe.whitelist()
 def get_lab_test_prescribed(patient):
-	return frappe.db.sql("""select cp.name, cp.test_code, cp.parent, cp.invoice, ct.practitioner, ct.encounter_date from `tabPatient Encounter` ct,
+	return frappe.db.sql("""select cp.name, cp.test_code, cp.parent, cp.invoiced, ct.practitioner, ct.encounter_date from `tabPatient Encounter` ct,
 	`tabLab Prescription` cp where ct.patient=%s and cp.parent=ct.name and cp.test_created=0""", (patient))
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test_list.js b/erpnext/healthcare/doctype/lab_test/lab_test_list.js
index c36c115..1f6a12f 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test_list.js
+++ b/erpnext/healthcare/doctype/lab_test/lab_test_list.js
@@ -2,7 +2,7 @@
 (c) ESS 2015-16
 */
 frappe.listview_settings['Lab Test'] = {
-	add_fields: ["name", "status", "invoice"],
+	add_fields: ["name", "status", "invoiced"],
 	filters:[["docstatus","=","0"]],
 	get_indicator: function(doc) {
 		if(doc.status=="Approved"){
@@ -11,5 +11,52 @@
 		if(doc.status=="Rejected"){
 			return [__("Rejected"), "yellow", "status,=,Rejected"];
 		}
+	},
+	onload: function(listview) {
+		listview.page.add_menu_item(__("Create Multiple"), function() {
+			create_multiple_dialog(listview);
+		});
 	}
 };
+
+var create_multiple_dialog = function(listview){
+	var dialog = new frappe.ui.Dialog({
+		title: 'Create Multiple Lab Test',
+		width: 100,
+		fields: [
+			{fieldtype: "Link", label: "Patient", fieldname: "patient", options: "Patient", reqd: 1},
+			{fieldtype: "Select", label: "Invoice / Patient Encounter", fieldname: "doctype",
+				options: "\nSales Invoice\nPatient Encounter", reqd: 1},
+			{fieldtype: "Dynamic Link", fieldname: "docname", options: "doctype", reqd: 1,
+				get_query: function(){
+					return {
+						filters: {
+							"patient": dialog.get_value("patient"),
+							"docstatus": 1
+						}
+					};
+				}
+			}
+		],
+		primary_action_label: __("Create Lab Test"),
+		primary_action : function(){
+			frappe.call({
+				method: 'erpnext.healthcare.doctype.lab_test.lab_test.create_multiple',
+				args:{
+					'doctype': dialog.get_value("doctype"),
+					'docname': dialog.get_value("docname")
+				},
+				callback: function(data) {
+					if(!data.exc){
+						listview.refresh();
+					}
+				},
+				freeze: true,
+				freeze_message: "Creating Lab Test..."
+			});
+			dialog.hide();
+		}
+	});
+
+	dialog.show();
+};
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
index d76fb29..62a3b30 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
@@ -12,13 +12,16 @@
 		#Item and Price List update --> if (change_in_item)
 		if(self.change_in_item and self.is_billable == 1 and self.item):
 			updating_item(self)
-			if not item_price_exist(self):
+			item_price = item_price_exist(self)
+			if not item_price:
 				if(self.test_rate != 0.0):
 					price_list_name = frappe.db.get_value("Price List", {"selling": 1})
 					if(self.test_rate):
 						make_item_price(self.test_code, price_list_name, self.test_rate)
 					else:
 						make_item_price(self.test_code, price_list_name, 0.0)
+			else:
+				frappe.db.set_value("Item Price", item_price, "price_list_rate", self.test_rate)
 
 			frappe.db.set_value(self.doctype,self.name,"change_in_item",0)
 		elif(self.is_billable == 0 and self.item):
@@ -43,7 +46,7 @@
 	"doctype": "Item Price",
 	"item_code": doc.test_code})
 	if(item_price):
-		return True
+		return item_price[0][0]
 	else:
 		return False
 
diff --git a/erpnext/healthcare/doctype/patient/patient_dashboard.py b/erpnext/healthcare/doctype/patient/patient_dashboard.py
index 098497c..46b1013 100644
--- a/erpnext/healthcare/doctype/patient/patient_dashboard.py
+++ b/erpnext/healthcare/doctype/patient/patient_dashboard.py
@@ -13,6 +13,10 @@
 			{
 				'label': _('Lab Tests and Vital Signs'),
  				'items': ['Lab Test', 'Sample Collection', 'Vital Signs']
+			},
+			{
+				'label': _('Billing'),
+				'items': ['Sales Invoice']
 			}
 		]
 	}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index 9799018..9338b9f 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -4,7 +4,6 @@
 frappe.ui.form.on('Patient Appointment', {
 	setup: function(frm) {
 		frm.custom_make_buttons = {
-			'Sales Invoice': 'Invoice',
 			'Vital Signs': 'Vital Signs',
 			'Patient Encounter': 'Patient Encounter'
 		};
@@ -84,20 +83,21 @@
 				btn_update_status(frm, "Cancelled");
 			});
 		}
-
-		if(!frm.doc.__islocal){
-			if(frm.doc.sales_invoice && frappe.user.has_role("Accounts User")){
-				frm.add_custom_button(__('Invoice'), function() {
-					frappe.set_route("Form", "Sales Invoice", frm.doc.sales_invoice);
-				},__("View") );
-			}
-			else if(frm.doc.status != "Cancelled" && frappe.user.has_role("Accounts User")){
-				frm.add_custom_button(__('Invoice'), function() {
-					btn_invoice_encounter(frm);
-				},__("Create"));
-			}
-		}
 		frm.set_df_property("get_procedure_from_encounter", "read_only", frm.doc.__islocal ? 0 : 1);
+		frappe.db.get_value('Healthcare Settings', {name: 'Healthcare Settings'}, 'manage_appointment_invoice_automatically', (r) => {
+			if(r.manage_appointment_invoice_automatically == 1){
+				frm.set_df_property("mode_of_payment", "hidden", 0);
+				frm.set_df_property("paid_amount", "hidden", 0);
+				frm.set_df_property("mode_of_payment", "reqd", 1);
+				frm.set_df_property("paid_amount", "reqd", 1);
+			}
+			else{
+				frm.set_df_property("mode_of_payment", "hidden", 1);
+				frm.set_df_property("paid_amount", "hidden", 1);
+				frm.set_df_property("mode_of_payment", "reqd", 0);
+				frm.set_df_property("paid_amount", "reqd", 0);
+			}
+		});
 	},
 	check_availability: function(frm) {
 		var { practitioner, appointment_date } = frm.doc;
@@ -339,21 +339,6 @@
 	);
 };
 
-var btn_invoice_encounter = function(frm){
-	frappe.call({
-		doc: frm.doc,
-		method:"create_invoice",
-		callback: function(data){
-			if(!data.exc){
-				if(data.message){
-					frappe.set_route("Form", "Sales Invoice", data.message);
-				}
-				cur_frm.reload_doc();
-			}
-		}
-	});
-};
-
 frappe.ui.form.on("Patient Appointment", "practitioner", function(frm) {
 	if(frm.doc.practitioner){
 		frappe.call({
@@ -364,6 +349,7 @@
 			},
 			callback: function (data) {
 				frappe.model.set_value(frm.doctype,frm.docname, "department",data.message.department);
+				frappe.model.set_value(frm.doctype,frm.docname, "paid_amount",data.message.op_consulting_charge);
 			}
 		});
 	}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
index 960648b..5215c28 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
@@ -108,7 +108,7 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "reqd": 0, 
    "search_index": 1, 
    "set_only_once": 1, 
    "translatable": 0, 
@@ -617,7 +617,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "depends_on": "eval:!doc.__islocal", 
+   "depends_on": "", 
    "fieldname": "section_break_1", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -681,6 +681,71 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "mode_of_payment", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Mode of Payment", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Mode of Payment", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "paid_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "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": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "column_break_2", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -712,8 +777,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "sales_invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -721,10 +787,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Sales Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Sales Invoice", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -989,4 +1055,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index ad2a933..3e6706f 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -6,12 +6,13 @@
 import frappe
 from frappe.model.document import Document
 import json
-from frappe.utils import getdate
+from frappe.utils import getdate, add_days
 from frappe import _
 import datetime
 from frappe.core.doctype.sms_settings.sms_settings import send_sms
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account
 from erpnext.hr.doctype.employee.employee import is_holiday
+from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account
+from erpnext.healthcare.utils import validity_exists, service_item_and_practitioner_charge
 
 class PatientAppointment(Document):
 	def on_update(self):
@@ -38,30 +39,112 @@
 				visited = fee_validity.visited + 1
 				frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
 				if fee_validity.ref_invoice:
-					frappe.db.set_value("Patient Appointment", appointment.name, "sales_invoice", fee_validity.ref_invoice)
+					frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
 				frappe.msgprint(_("{0} has fee validity till {1}").format(appointment.patient, fee_validity.valid_till))
 		confirm_sms(self)
 
-	def create_invoice(self):
-		return invoice_appointment(self)
+		if frappe.db.get_value("Healthcare Settings", None, "manage_appointment_invoice_automatically") == '1' and \
+			frappe.db.get_value("Patient Appointment", self.name, "invoiced") != 1:
+			invoice_appointment(self)
+
+@frappe.whitelist()
+def invoice_appointment(appointment_doc):
+	if not appointment_doc.name:
+		return False
+	sales_invoice = frappe.new_doc("Sales Invoice")
+	sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
+	sales_invoice.appointment = appointment_doc.name
+	sales_invoice.due_date = getdate()
+	sales_invoice.is_pos = True
+	sales_invoice.company = appointment_doc.company
+	sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
+
+	item_line = sales_invoice.append("items")
+	service_item, practitioner_charge = service_item_and_practitioner_charge(appointment_doc)
+	item_line.item_code = service_item
+	item_line.description = "Consulting Charges:  " + appointment_doc.practitioner
+	item_line.income_account = get_income_account(appointment_doc.practitioner, appointment_doc.company)
+	item_line.rate = practitioner_charge
+	item_line.amount = practitioner_charge
+	item_line.qty = 1
+	item_line.reference_dt = "Patient Appointment"
+	item_line.reference_dn = appointment_doc.name
+
+	payments_line = sales_invoice.append("payments")
+	payments_line.mode_of_payment = appointment_doc.mode_of_payment
+	payments_line.amount = appointment_doc.paid_amount
+
+	sales_invoice.set_missing_values(for_validate = True)
+
+	sales_invoice.save(ignore_permissions=True)
+	sales_invoice.submit()
+	frappe.msgprint(_("Sales Invoice {0} created as paid".format(sales_invoice.name)), alert=True)
 
 def appointment_cancel(appointment_id):
 	appointment = frappe.get_doc("Patient Appointment", appointment_id)
-
-	# If invoice --> fee_validity update with -1 visit
-	if appointment.sales_invoice:
-		validity = frappe.db.exists({"doctype": "Fee Validity", "ref_invoice": appointment.sales_invoice})
-		if validity:
-			fee_validity = frappe.get_doc("Fee Validity", validity[0][0])
-			visited = fee_validity.visited - 1
-			frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
-			if visited <= 0:
-				frappe.msgprint(
-					_("Appointment cancelled, Please review and cancel the invoice {0}".format(appointment.sales_invoice))
-				)
+	# If invoiced --> fee_validity update with -1 visit
+	if appointment.invoiced:
+		sales_invoice = exists_sales_invoice(appointment)
+		if sales_invoice and cancel_sales_invoice(sales_invoice):
+			frappe.msgprint(
+				_("Appointment {0} and Sales Invoice {1} cancelled".format(appointment.name, sales_invoice.name))
+			)
+		else:
+			validity = validity_exists(appointment.practitioner, appointment.patient)
+			if validity:
+				fee_validity = frappe.get_doc("Fee Validity", validity[0][0])
+				if appointment_valid_in_fee_validity(appointment, fee_validity.valid_till, True, fee_validity.ref_invoice):
+					visited = fee_validity.visited - 1
+					frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+					frappe.msgprint(
+						_("Appointment cancelled, Please review and cancel the invoice {0}".format(fee_validity.ref_invoice))
+					)
+				else:
+					frappe.msgprint(_("Appointment cancelled"))
 			else:
 				frappe.msgprint(_("Appointment cancelled"))
+	else:
+		frappe.msgprint(_("Appointment cancelled"))
 
+def appointment_valid_in_fee_validity(appointment, valid_end_date, invoiced, ref_invoice):
+	valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
+	max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
+	valid_start_date = add_days(getdate(valid_end_date), -int(valid_days))
+
+	# Appointments which has same fee validity range with the appointment
+	appointments = frappe.get_list("Patient Appointment",{'patient': appointment.patient, 'invoiced': invoiced,
+	'appointment_date':("<=", getdate(valid_end_date)), 'appointment_date':(">=", getdate(valid_start_date)),
+	'practitioner': appointment.practitioner}, order_by="appointment_date desc", limit=int(max_visit))
+
+	if appointments and len(appointments) > 0:
+		appointment_obj = appointments[len(appointments)-1]
+		sales_invoice = exists_sales_invoice(appointment_obj)
+		if sales_invoice.name == ref_invoice:
+			return True
+	return False
+
+def cancel_sales_invoice(sales_invoice):
+	if frappe.db.get_value("Healthcare Settings", None, "manage_appointment_invoice_automatically") == '1':
+		if len(sales_invoice.items) == 1:
+			sales_invoice.cancel()
+			return True
+	return False
+
+def exists_sales_invoice_item(appointment):
+	return frappe.db.exists(
+		"Sales Invoice Item",
+		{
+			"reference_dt": "Patient Appointment",
+			"reference_dn": appointment.name
+		}
+	)
+
+def exists_sales_invoice(appointment):
+	sales_item_exist = exists_sales_invoice_item(appointment)
+	if sales_item_exist:
+		sales_invoice = frappe.get_doc("Sales Invoice", frappe.db.get_value("Sales Invoice Item", sales_item_exist, "parent"))
+		return sales_invoice
+	return False
 
 @frappe.whitelist()
 def get_availability_data(date, practitioner):
@@ -197,100 +280,6 @@
 		message = frappe.db.get_value("Healthcare Settings", None, "app_con_msg")
 		send_message(doc, message)
 
-
-@frappe.whitelist()
-def invoice_appointment(appointment_doc):
-	if not appointment_doc.name:
-		return False
-	sales_invoice = frappe.new_doc("Sales Invoice")
-	sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
-	sales_invoice.appointment = appointment_doc.name
-	sales_invoice.due_date = getdate()
-	sales_invoice.is_pos = '0'
-	sales_invoice.company = appointment_doc.company
-	sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
-
-	fee_validity = get_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date)
-	procedure_template = False
-	if appointment_doc.procedure_template:
-		procedure_template = appointment_doc.procedure_template
-	create_invoice_items(appointment_doc.practitioner, appointment_doc.company, sales_invoice, procedure_template)
-
-	sales_invoice.save(ignore_permissions=True)
-	frappe.db.sql("""update `tabPatient Appointment` set sales_invoice=%s where name=%s""", (sales_invoice.name, appointment_doc.name))
-	frappe.db.set_value("Fee Validity", fee_validity.name, "ref_invoice", sales_invoice.name)
-	encounter = frappe.db.exists({
-			"doctype": "Patient Encounter",
-			"appointment": appointment_doc.name})
-	if encounter:
-		frappe.db.set_value("Patient Encounter", encounter[0][0], "invoice", sales_invoice.name)
-	return sales_invoice.name
-
-
-def get_fee_validity(practitioner, patient, date):
-	validity_exist = validity_exists(practitioner, patient)
-	if validity_exist:
-		fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
-		fee_validity = update_fee_validity(fee_validity, date)
-	else:
-		fee_validity = create_fee_validity(practitioner, patient, date)
-	return fee_validity
-
-
-def validity_exists(practitioner, patient):
-	return frappe.db.exists({
-			"doctype": "Fee Validity",
-			"practitioner": practitioner,
-			"patient": patient})
-
-
-def update_fee_validity(fee_validity, date):
-	max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
-	valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
-	if not valid_days:
-		valid_days = 1
-	if not max_visit:
-		max_visit = 1
-	date = getdate(date)
-	valid_till = date + datetime.timedelta(days=int(valid_days))
-	fee_validity.max_visit = max_visit
-	fee_validity.visited = 1
-	fee_validity.valid_till = valid_till
-	fee_validity.save(ignore_permissions=True)
-	return fee_validity
-
-
-def create_fee_validity(practitioner, patient, date):
-	fee_validity = frappe.new_doc("Fee Validity")
-	fee_validity.practitioner = practitioner
-	fee_validity.patient = patient
-	fee_validity = update_fee_validity(fee_validity, date)
-	return fee_validity
-
-
-def create_invoice_items(practitioner, company, invoice, procedure_template):
-	item_line = invoice.append("items")
-	if procedure_template:
-		procedure_template_obj = frappe.get_doc("Clinical Procedure Template", procedure_template)
-		item_line.item_code = procedure_template_obj.item_code
-		item_line.item_name = procedure_template_obj.template
-		item_line.description = procedure_template_obj.description
-	else:
-		item_line.item_name = "Consulting Charges"
-		item_line.description = "Consulting Charges:  " + practitioner
-		item_line.uom = "Nos"
-		item_line.conversion_factor = 1
-		item_line.income_account = get_income_account(practitioner, company)
-		op_consulting_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
-		if op_consulting_charge:
-			item_line.rate = op_consulting_charge
-			item_line.amount = op_consulting_charge
-	item_line.qty = 1
-
-
-	return invoice
-
-
 @frappe.whitelist()
 def create_encounter(appointment):
 	appointment = frappe.get_doc("Patient Appointment", appointment)
@@ -301,8 +290,8 @@
 	encounter.visit_department = appointment.department
 	encounter.patient_sex = appointment.patient_sex
 	encounter.encounter_date = appointment.appointment_date
-	if appointment.sales_invoice:
-		encounter.invoice = appointment.sales_invoice
+	if appointment.invoiced:
+		encounter.invoiced = True
 	return encounter.as_dict()
 
 
@@ -359,6 +348,7 @@
 		item.appointment_datetime = item.appointment_date + datetime.timedelta(minutes = item.duration)
 
 	return data
+
 @frappe.whitelist()
 def get_procedure_prescribed(patient):
 	return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner,
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
index f9ef1cb..a030f19 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
@@ -10,10 +10,6 @@
 			{
 				'label': _('Consultations'),
 				'items': ['Patient Encounter', 'Vital Signs', 'Patient Medical Record']
-			},
-			{
-				'label': _('Billing'),
-				'items': ['Sales Invoice']
 			}
 		]
 	}
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index 47c9cad..2dd3512 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -94,11 +94,6 @@
 				}
 			};
 		});
-		if(!frm.doc.__islocal && !frm.doc.invoice && (frappe.user.has_role("Accounts User"))){
-			frm.add_custom_button(__('Invoice'), function() {
-				btn_invoice_encounter(frm);
-			},__("Create"));
-		}
 		frm.set_df_property("appointment", "read_only", frm.doc.__islocal ? 0:1);
 		frm.set_df_property("patient", "read_only", frm.doc.__islocal ? 0:1);
 		frm.set_df_property("patient_age", "read_only", frm.doc.__islocal ? 0:1);
@@ -139,23 +134,6 @@
 	});
 };
 
-var btn_invoice_encounter = function(frm){
-	var doc = frm.doc;
-	frappe.call({
-		method:
-		"erpnext.healthcare.doctype.encounter.encounter.create_invoice",
-		args: {company: doc.company, patient: doc.patient, practitioner: doc.practitioner, encounter_id: doc.name },
-		callback: function(data){
-			if(!data.exc){
-				if(data.message){
-					frappe.set_route("Form", "Sales Invoice", data.message);
-				}
-				cur_frm.reload_doc();
-			}
-		}
-	});
-};
-
 var create_medical_record = function (frm) {
 	if(!frm.doc.patient){
 		frappe.throw(__("Please select patient"));
@@ -203,10 +181,16 @@
 				frappe.model.set_value(frm.doctype,frm.docname, "patient", data.message.patient);
 				frappe.model.set_value(frm.doctype,frm.docname, "type", data.message.appointment_type);
 				frappe.model.set_value(frm.doctype,frm.docname, "practitioner", data.message.practitioner);
-				frappe.model.set_value(frm.doctype,frm.docname, "invoice", data.message.sales_invoice);
+				frappe.model.set_value(frm.doctype,frm.docname, "invoiced", data.message.invoiced);
 			}
 		});
 	}
+	else{
+		frappe.model.set_value(frm.doctype,frm.docname, "patient", "");
+		frappe.model.set_value(frm.doctype,frm.docname, "type", "");
+		frappe.model.set_value(frm.doctype,frm.docname, "practitioner", "");
+		frappe.model.set_value(frm.doctype,frm.docname, "invoiced", 0);
+	}
 });
 
 frappe.ui.form.on("Patient Encounter", "practitioner", function(frm) {
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
index d11d1a7..6f00e5b 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
@@ -220,9 +220,43 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "", 
+   "fetch_from": "patient.patient_name", 
+   "fieldname": "patient_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Patient Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
    "fieldname": "patient_age", 
    "fieldtype": "Data", 
-   "hidden": 1, 
+   "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
@@ -235,9 +269,9 @@
    "options": "", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 1, 
+   "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 1, 
    "reqd": 0, 
@@ -255,7 +289,7 @@
    "columns": 0, 
    "fieldname": "patient_sex", 
    "fieldtype": "Select", 
-   "hidden": 1, 
+   "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
@@ -268,9 +302,9 @@
    "options": "\nMale\nFemale\nOther", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 1, 
+   "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 1, 
    "reqd": 0, 
@@ -286,39 +320,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "practitioner", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 1, 
-   "label": "Healthcare Practitioner", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Healthcare Practitioner", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "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, 
    "fieldname": "company", 
    "fieldtype": "Link", 
    "hidden": 1, 
@@ -383,6 +384,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "practitioner", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 1, 
+   "label": "Healthcare Practitioner", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Healthcare Practitioner", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "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, 
    "fieldname": "visit_department", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -482,8 +516,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -491,10 +526,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "Sales Invoice", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -1145,4 +1180,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
index 3d8f952..4c62e57 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
@@ -5,9 +5,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.model.document import Document
-from frappe.utils import getdate, cstr
-import json
-from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
+from frappe.utils import cstr
 
 class PatientEncounter(Document):
 	def on_update(self):
@@ -23,77 +21,6 @@
 			frappe.db.set_value("Patient Appointment", self.appointment, "status", "Open")
 		delete_medical_record(self)
 
-def set_sales_invoice_fields(company, patient):
-	sales_invoice = frappe.new_doc("Sales Invoice")
-	sales_invoice.customer = frappe.get_value("Patient", patient, "customer")
-	# patient is custom field in sales inv.
-	sales_invoice.due_date = getdate()
-	sales_invoice.is_pos = '0'
-	sales_invoice.debit_to = get_receivable_account(company)
-
-	return sales_invoice
-
-def create_sales_invoice_item_lines(item, sales_invoice):
-	sales_invoice_line = sales_invoice.append("items")
-	sales_invoice_line.item_code = item.item_code
-	sales_invoice_line.item_name =  item.item_name
-	sales_invoice_line.qty = 1.0
-	sales_invoice_line.description = item.description
-	return sales_invoice_line
-
-@frappe.whitelist()
-def create_drug_invoice(company, patient, prescriptions):
-	list_ids = json.loads(prescriptions)
-	if not (company or patient or prescriptions):
-		return False
-
-	sales_invoice = set_sales_invoice_fields(company, patient)
-	sales_invoice.update_stock = 1
-
-	for line_id in list_ids:
-		line_obj = frappe.get_doc("Drug Prescription", line_id)
-		if line_obj:
-			if(line_obj.drug_code):
-				item = frappe.get_doc("Item", line_obj.drug_code)
-				sales_invoice_line = create_sales_invoice_item_lines(item, sales_invoice)
-				sales_invoice_line.qty = line_obj.get_quantity()
-	#income_account and cost_center in itemlines - by set_missing_values()
-	sales_invoice.set_missing_values()
-	return sales_invoice.as_dict()
-
-@frappe.whitelist()
-def create_invoice(company, patient, practitioner, encounter_id):
-	if not encounter_id:
-		return False
-	sales_invoice = frappe.new_doc("Sales Invoice")
-	sales_invoice.customer = frappe.get_value("Patient", patient, "customer")
-	sales_invoice.due_date = getdate()
-	sales_invoice.is_pos = '0'
-	sales_invoice.debit_to = get_receivable_account(company)
-
-	create_invoice_items(practitioner, sales_invoice, company)
-
-	sales_invoice.save(ignore_permissions=True)
-	frappe.db.sql("""update `tabPatient Encounter` set invoice=%s where name=%s""", (sales_invoice.name, encounter_id))
-	appointment = frappe.db.get_value("Patient Encounter", encounter_id, "appointment")
-	if appointment:
-		frappe.db.set_value("Patient Appointment", appointment, "sales_invoice", sales_invoice.name)
-	return sales_invoice.name
-
-def create_invoice_items(practitioner, invoice, company):
-	item_line = invoice.append("items")
-	item_line.item_name = "Consulting Charges"
-	item_line.description = "Consulting Charges:  " + practitioner
-	item_line.qty = 1
-	item_line.uom = "Nos"
-	item_line.conversion_factor = 1
-	item_line.income_account = get_income_account(practitioner, company)
-	op_consulting_charge = frappe.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
-	if op_consulting_charge:
-		item_line.rate = op_consulting_charge
-		item_line.amount = op_consulting_charge
-	return invoice
-
 def insert_encounter_to_medical_record(doc):
 	subject = set_subject_field(doc)
 	medical_record = frappe.new_doc("Patient Medical Record")
diff --git a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
index 8c35ccd..c6a6b44 100644
--- a/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
+++ b/erpnext/healthcare/doctype/patient_medical_record/patient_medical_record.json
@@ -331,7 +331,7 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -454,4 +454,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
index b4c4532..d67da97 100644
--- a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
+++ b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
@@ -236,7 +236,72 @@
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
-   "search_index": 0, 
+   "search_index": 1, 
+   "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, 
+   "fieldname": "procedure_created", 
+   "fieldtype": "Check", 
+   "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": "Procedure Created", 
+   "length": 0, 
+   "no_copy": 1, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 1, 
+   "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": "invoiced", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Invoiced", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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": 1, 
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
@@ -252,7 +317,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-07-16 13:08:15.499491", 
+ "modified": "2018-08-06 16:53:36.440428", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Procedure Prescription", 
@@ -266,5 +331,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.json b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
index 7655685..783fc3d 100644
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.json
+++ b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
@@ -88,8 +88,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -97,10 +97,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "length": 0, 
-   "no_copy": 0, 
-   "options": "Sales Invoice", 
+   "no_copy": 1, 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -684,4 +684,4 @@
  "track_changes": 1, 
  "track_seen": 1, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json b/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json
index 4deff80..ac5ca1a 100644
--- a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json
+++ b/erpnext/healthcare/page/appointment_analytic/appointment_analytic.json
@@ -1,22 +1,24 @@
 {
- "content": null,
- "creation": "2016-08-18 12:29:52.497819",
- "docstatus": 0,
- "doctype": "Page",
- "idx": 0,
- "modified": "2016-08-18 12:29:52.497819",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "appointment-analytic",
- "owner": "Administrator",
- "page_name": "Appointment Analytics",
+ "content": null, 
+ "creation": "2016-08-18 12:29:52.497819", 
+ "docstatus": 0, 
+ "doctype": "Page", 
+ "idx": 0, 
+ "modified": "2018-08-06 11:40:53.082863", 
+ "modified_by": "Administrator", 
+ "module": "Healthcare", 
+ "name": "appointment-analytic", 
+ "owner": "Administrator", 
+ "page_name": "Appointment Analytics", 
+ "restrict_to_domain": "Healthcare", 
  "roles": [
   {
    "role": "Physician"
   }
- ],
- "script": null,
- "standard": "Yes",
- "style": null,
+ ], 
+ "script": null, 
+ "standard": "Yes", 
+ "style": null, 
+ "system_page": 0, 
  "title": "Appointment Analytics"
-}
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/medical_record/medical_record.json b/erpnext/healthcare/page/medical_record/medical_record.json
index 7c786ca..ca30c3b 100644
--- a/erpnext/healthcare/page/medical_record/medical_record.json
+++ b/erpnext/healthcare/page/medical_record/medical_record.json
@@ -1,23 +1,25 @@
 {
- "content": null,
- "creation": "2016-06-09 11:33:14.025787",
- "docstatus": 0,
- "doctype": "Page",
- "icon": "icon-play",
- "idx": 0,
- "modified": "2017-03-06 11:20:40.174661",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "medical_record",
- "owner": "Administrator",
- "page_name": "medical_record",
+ "content": null, 
+ "creation": "2016-06-09 11:33:14.025787", 
+ "docstatus": 0, 
+ "doctype": "Page", 
+ "icon": "icon-play", 
+ "idx": 0, 
+ "modified": "2018-08-06 11:40:39.705660", 
+ "modified_by": "Administrator", 
+ "module": "Healthcare", 
+ "name": "medical_record", 
+ "owner": "Administrator", 
+ "page_name": "medical_record", 
+ "restrict_to_domain": "Healthcare", 
  "roles": [
   {
    "role": "Physician"
   }
- ],
- "script": null,
- "standard": "Yes",
- "style": null,
+ ], 
+ "script": null, 
+ "standard": "Yes", 
+ "style": null, 
+ "system_page": 0, 
  "title": "Medical Record"
-}
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json b/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
index 2f85ff6..d3ad440 100644
--- a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
+++ b/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
@@ -7,10 +7,10 @@
  "docstatus": 0, 
  "doctype": "Print Format", 
  "font": "Default", 
- "html": "<div >\n  {% if letter_head and not no_letterhead -%}\n    <div class=\"letter-head\">{{ letter_head }}</div>\n    <hr>\n  {%- endif %}\n\n  {% if (doc.docstatus != 1) %}\n  <b>Lab Tests have to be Submitted for Print .. !</b>\n  {% elif (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"require_test_result_approval\") == '1' and doc.approval_status != \"Approved\") %}\n  <b>Lab Tests have to be Approved for Print .. !</b>\n  {%- else -%}\n  <div class=\"row section-break\">\n    <div class=\"col-xs-6 column-break\">\n      {% if doc.invoice %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Order No.</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong>{{doc.invoice}}\n        </div>\n      </div>\n      {%- endif -%}\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Patient</label>\n        </div>\n        {% if doc.patient %}\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong>{{doc.patient}}\n        </div>\n        {% else %}\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong><em>Patient Name</em>\n        </div>\n        {%- endif -%}\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Age</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong> {{doc.patient_age}}\n        </div>\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Gender</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong> {{doc.patient_sex}}\n        </div>\n      </div>\n\n    </div>\n\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Healthcare Practitioner</label>\n        </div>\n        {% if doc.practitioner %}\n        <div class=\"col-xs-7  text-left value\">\n          <strong>: </strong>{{doc.practitioner}}\n        </div>\n        {%- endif -%}\n      </div>\n\n      {% if doc.sample_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Sample Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          <strong>: </strong>{{doc.sample_date}}\n        </div>\n      </div>\n      {%- endif -%}\n\n      {% if doc.result_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Result Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          <strong>: </strong>{{doc.result_date}}\n        </div>\n      </div>\n      {%- endif -%}\n\n    </div>\n\n  </div>\n\n  <div align=\"center\">\n    <hr><h4 class=\"text-uppercase\"><b><u>Department of {{doc.department}}</u></b></h4>\n  </div>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.normal_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n        <th class=\"text-right\">Normal Range</th>\n      </tr>\n\n      {%- if doc.normal_test_items|length > 1 %}\n      <tr><td style=\"width: 40%;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n      {%- endif -%}\n\n      {%- for row in doc.normal_test_items -%}\n      <tr>\n        <td style=\"width: 40%;border:none;\">\n          {%- if doc.normal_test_items|length > 1 %}&emsp;&emsp;{%- endif -%}\n          {%- if row.test_name -%}<b>{{ row.test_name }}</b>\n          {%- else -%}&emsp;&emsp;&emsp;{%- endif -%}\n          {%- if row.test_event -%} &emsp;&emsp;{{ row.test_event }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 20%;text-align: left;border:none;\">\n          {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}&emsp;\n          {%- if row.test_uom -%}{{ row.test_uom }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 30%;text-align: right;border:none;\">\n          <div style=\"border: 0px;\">\n            {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n          </div>\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n    </tbody>\n  </table>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.special_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n      </tr>\n      <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n      {%- for row in doc.special_test_items -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> &emsp;&emsp;{{ row.test_particulars }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\">\n          {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n\n      {%- if doc.sensitivity_test_items -%}\n      <tr>\n        <th>Antibiotic</th>\n        <th class=\"text-left\">Sensitivity</th>\n      </tr>\n      {%- for row in doc.sensitivity_test_items -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> {{ row.antibiotic }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\">{{ row.antibiotic_sensitivity }}</td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n\n    </tbody>\n  </table>\n  {%- endif -%}\n\n  <div align=\"right\">\n    {%- if (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"employee_name_and_designation_in_print\") == '1') -%}\n    <h6 class=\"text-uppercase\"><b>{{doc.employee_name}}</b></h6>\n    <h6 class=\"text-uppercase\"><b>{{doc.employee_designation}}</b></h6>\n    {%- else -%}\n    <h6 ><b>{{frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") }}</b></h6>\n    {%- endif -%}\n  </div>\n</div>\n", 
+ "html": "<div >\n  {% if letter_head and not no_letterhead -%}\n    <div class=\"letter-head\">{{ letter_head }}</div>\n    <hr>\n  {%- endif %}\n\n  {% if (doc.docstatus != 1) %}\n  <b>Lab Tests have to be Submitted for Print .. !</b>\n  {% elif (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"require_test_result_approval\") == '1' and doc.approval_status != \"Approved\") %}\n  <b>Lab Tests have to be Approved for Print .. !</b>\n  {%- else -%}\n  <div class=\"row section-break\">\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Patient</label>\n        </div>\n        {% if doc.patient %}\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong>{{doc.patient}}\n        </div>\n        {% else %}\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong><em>Patient Name</em>\n        </div>\n        {%- endif -%}\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Age</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong> {{doc.patient_age}}\n        </div>\n      </div>\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Gender</label>\n        </div>\n        <div class=\"col-xs-7  value\">\n          <strong>: </strong> {{doc.patient_sex}}\n        </div>\n      </div>\n\n    </div>\n\n    <div class=\"col-xs-6 column-break\">\n\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Practitioner</label>\n        </div>\n        {% if doc.practitioner %}\n        <div class=\"col-xs-7  text-left value\">\n          <strong>: </strong>{{doc.practitioner}}\n        </div>\n        {%- endif -%}\n      </div>\n\n      {% if doc.sample_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Sample Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          <strong>: </strong>{{doc.sample_date}}\n        </div>\n      </div>\n      {%- endif -%}\n\n      {% if doc.result_date %}\n      <div class=\"row\">\n        <div class=\"col-xs-4 text-left\">\n          <label>Result Date</label>\n        </div>\n        <div class=\"col-xs-7 text-left value\">\n          <strong>: </strong>{{doc.result_date}}\n        </div>\n      </div>\n      {%- endif -%}\n\n    </div>\n\n  </div>\n\n  <div align=\"center\">\n    <hr><h4 class=\"text-uppercase\"><b><u>Department of {{doc.department}}</u></b></h4>\n  </div>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.normal_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n        <th class=\"text-right\">Normal Range</th>\n      </tr>\n\n      {%- if doc.normal_test_items|length > 1 %}\n      <tr><td style=\"width: 40%;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n      {%- endif -%}\n\n      {%- for row in doc.normal_test_items -%}\n      <tr>\n        <td style=\"width: 40%;border:none;\">\n          {%- if doc.normal_test_items|length > 1 %}&emsp;&emsp;{%- endif -%}\n          {%- if row.test_name -%}<b>{{ row.test_name }}</b>\n          {%- else -%}&emsp;&emsp;&emsp;{%- endif -%}\n          {%- if row.test_event -%} &emsp;&emsp;{{ row.test_event }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 20%;text-align: left;border:none;\">\n          {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}&emsp;\n          {%- if row.test_uom -%}{{ row.test_uom }}{%- endif -%}\n        </td>\n\n        <td style=\"width: 30%;text-align: right;border:none;\">\n          <div style=\"border: 0px;\">\n            {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n          </div>\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n    </tbody>\n  </table>\n\n  <table class=\"table\">\n    <tbody>\n      {%- if doc.special_test_items -%}\n      <tr>\n        <th>Name of Test</th>\n        <th class=\"text-left\">Result</th>\n      </tr>\n      <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n      {%- for row in doc.special_test_items -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> &emsp;&emsp;{{ row.test_particulars }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\">\n          {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n        </td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n\n      {%- if doc.sensitivity_test_items -%}\n      <tr>\n        <th>Antibiotic</th>\n        <th class=\"text-left\">Sensitivity</th>\n      </tr>\n      {%- for row in doc.sensitivity_test_items -%}\n      <tr>\n        <td style=\"width: 30%;border:none;\"> {{ row.antibiotic }} </td>\n        <td style=\"width: 70%;text-align: left;border:none;\">{{ row.antibiotic_sensitivity }}</td>\n      </tr>\n\n      {%- endfor -%}\n      {%- endif -%}\n\n    </tbody>\n  </table>\n  {%- endif -%}\n\n  <div align=\"right\">\n    {%- if (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"employee_name_and_designation_in_print\") == '1') -%}\n    <h6 class=\"text-uppercase\"><b>{{doc.employee_name}}</b></h6>\n    <h6 class=\"text-uppercase\"><b>{{doc.employee_designation}}</b></h6>\n    {%- else -%}\n    <h6 ><b>{{frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") }}</b></h6>\n    {%- endif -%}\n  </div>\n</div>\n", 
  "idx": 0, 
  "line_breaks": 0, 
- "modified": "2018-07-10 11:29:24.167265", 
+ "modified": "2018-07-13 12:51:25.750441", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Lab Test Print", 
@@ -19,4 +19,4 @@
  "print_format_type": "Server", 
  "show_section_headings": 0, 
  "standard": "Yes"
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.json b/erpnext/healthcare/report/lab_test_report/lab_test_report.json
index f133a8e..30e5a5f 100644
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.json
+++ b/erpnext/healthcare/report/lab_test_report/lab_test_report.json
@@ -1,17 +1,17 @@
 {
  "add_total_row": 1, 
- "apply_user_permissions": 1, 
  "creation": "2013-04-23 18:15:29", 
  "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 1, 
  "is_standard": "Yes", 
- "modified": "2017-08-23 14:54:12.593140", 
+ "modified": "2018-08-06 11:41:50.218737", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Lab Test Report", 
  "owner": "Administrator", 
+ "prepared_report": 0, 
  "ref_doctype": "Lab Test", 
  "report_name": "Lab Test Report", 
  "report_type": "Script Report", 
@@ -20,7 +20,13 @@
    "role": "Laboratory User"
   }, 
   {
-   "role": "System Manager"
+   "role": "Nursing User"
+  }, 
+  {
+   "role": "LabTest Approver"
+  }, 
+  {
+   "role": "Healthcare Administrator"
   }
  ]
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.py b/erpnext/healthcare/report/lab_test_report/lab_test_report.py
index e4771c5..b9a26df 100644
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.py
+++ b/erpnext/healthcare/report/lab_test_report/lab_test_report.py
@@ -17,7 +17,7 @@
 
 	data = []
 	for lab_test in lab_test_list:
-		row = [ lab_test.test_name, lab_test.patient, lab_test.practitioner, lab_test.invoice, lab_test.status, lab_test.result_date, lab_test.department]
+		row = [ lab_test.test_name, lab_test.patient, lab_test.practitioner, lab_test.invoiced, lab_test.status, lab_test.result_date, lab_test.department]
 		data.append(row)
 
 	return columns, data
@@ -28,7 +28,7 @@
 		_("Test") + ":Data:120",
 		_("Patient") + ":Link/Patient:180",
 		_("Healthcare Practitioner") + ":Link/Healthcare Practitioner:120",
-		_("Invoice") + ":Link/Sales Invoice:120",
+		_("Invoiced") + ":Check:100",
 		_("Status") + ":Data:120",
 		_("Result Date") + ":Date:120",
 		_("Department") + ":Data:120",
@@ -52,7 +52,7 @@
 
 def get_lab_test(filters):
 	conditions = get_conditions(filters)
-	return frappe.db.sql("""select name, patient, test_name, patient_name, status, result_date, practitioner, invoice, department
+	return frappe.db.sql("""select name, patient, test_name, patient_name, status, result_date, practitioner, invoiced, department
 		from `tabLab Test`
 		where docstatus<2 %s order by submitted_date desc, name desc""" %
 		conditions, filters, as_dict=1)
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
new file mode 100644
index 0000000..1be82e2
--- /dev/null
+++ b/erpnext/healthcare/utils.py
@@ -0,0 +1,426 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, earthians and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+import datetime
+from frappe import _
+import math
+from frappe.utils import time_diff_in_hours, rounded, getdate, add_days
+from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account
+from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity, update_fee_validity
+from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
+
+@frappe.whitelist()
+def get_healthcare_services_to_invoice(patient):
+	patient = frappe.get_doc("Patient", patient)
+	if patient:
+		if patient.customer:
+			item_to_invoice = []
+			patient_appointments = frappe.get_list("Patient Appointment",{'patient': patient.name, 'invoiced': False},
+			order_by="appointment_date")
+			if patient_appointments:
+				fee_validity_details = []
+				valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
+				max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
+				for patient_appointment in patient_appointments:
+					patient_appointment_obj = frappe.get_doc("Patient Appointment", patient_appointment['name'])
+
+					if patient_appointment_obj.procedure_template:
+						if frappe.db.get_value("Clinical Procedure Template", patient_appointment_obj.procedure_template, "is_billable") == 1:
+							item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name, 'service': patient_appointment_obj.procedure_template})
+					else:
+						practitioner_exist_in_list = False
+						skip_invoice = False
+						if fee_validity_details:
+							for validity in fee_validity_details:
+								if validity['practitioner'] == patient_appointment_obj.practitioner:
+									practitioner_exist_in_list = True
+									if validity['valid_till'] >= patient_appointment_obj.appointment_date:
+										validity['visits'] = validity['visits']+1
+										if int(max_visit) > validity['visits']:
+											skip_invoice = True
+									if not skip_invoice:
+										validity['visits'] = 1
+										validity['valid_till'] = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
+						if not practitioner_exist_in_list:
+							valid_till = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
+							visits = 0
+							validity_exist = validity_exists(patient_appointment_obj.practitioner, patient_appointment_obj.patient)
+							if validity_exist:
+								fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
+								valid_till = fee_validity.valid_till
+								visits = fee_validity.visited
+							fee_validity_details.append({'practitioner': patient_appointment_obj.practitioner,
+							'valid_till': valid_till, 'visits': visits})
+
+						if not skip_invoice:
+							practitioner_charge = 0
+							income_account = None
+							service_item = None
+							if patient_appointment_obj.practitioner:
+								service_item, practitioner_charge = service_item_and_practitioner_charge(patient_appointment_obj)
+								income_account = get_income_account(patient_appointment_obj.practitioner, patient_appointment_obj.company)
+							item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name,
+							'service': service_item, 'rate': practitioner_charge,
+							'income_account': income_account})
+
+			encounters = frappe.get_list("Patient Encounter", {'patient': patient.name, 'invoiced': False, 'docstatus': 1})
+			if encounters:
+				for encounter in encounters:
+					encounter_obj = frappe.get_doc("Patient Encounter", encounter['name'])
+					if not encounter_obj.appointment:
+						practitioner_charge = 0
+						income_account = None
+						service_item = None
+						if encounter_obj.practitioner:
+							service_item, practitioner_charge = service_item_and_practitioner_charge(encounter_obj)
+							income_account = get_income_account(encounter_obj.practitioner, encounter_obj.company)
+
+						item_to_invoice.append({'reference_type': 'Patient Encounter', 'reference_name': encounter_obj.name,
+						'service': service_item, 'rate': practitioner_charge,
+						'income_account': income_account})
+
+			lab_tests = frappe.get_list("Lab Test", {'patient': patient.name, 'invoiced': False})
+			if lab_tests:
+				for lab_test in lab_tests:
+					lab_test_obj = frappe.get_doc("Lab Test", lab_test['name'])
+					if frappe.db.get_value("Lab Test Template", lab_test_obj.template, "is_billable") == 1:
+						item_to_invoice.append({'reference_type': 'Lab Test', 'reference_name': lab_test_obj.name,
+						'service': frappe.db.get_value("Lab Test Template", lab_test_obj.template, "item")})
+
+			lab_rxs = frappe.db.sql("""select lp.name from `tabPatient Encounter` et, `tabLab Prescription` lp
+			where et.patient=%s and lp.parent=et.name and lp.test_created=0 and lp.invoiced=0""", (patient.name))
+			if lab_rxs:
+				for lab_rx in lab_rxs:
+					rx_obj = frappe.get_doc("Lab Prescription", lab_rx[0])
+					if rx_obj.test_code and (frappe.db.get_value("Lab Test Template", rx_obj.test_code, "is_billable") == 1):
+						item_to_invoice.append({'reference_type': 'Lab Prescription', 'reference_name': rx_obj.name,
+						'service': frappe.db.get_value("Lab Test Template", rx_obj.test_code, "item")})
+
+			procedures = frappe.get_list("Clinical Procedure", {'patient': patient.name, 'invoiced': False})
+			if procedures:
+				for procedure in procedures:
+					procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
+					if not procedure_obj.appointment:
+						if procedure_obj.procedure_template and (frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "is_billable") == 1):
+							item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
+							'service': frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "item")})
+
+			procedure_rxs = frappe.db.sql("""select pp.name from `tabPatient Encounter` et,
+			`tabProcedure Prescription` pp where et.patient=%s and pp.parent=et.name and
+			pp.procedure_created=0 and pp.invoiced=0 and pp.appointment_booked=0""", (patient.name))
+			if procedure_rxs:
+				for procedure_rx in procedure_rxs:
+					rx_obj = frappe.get_doc("Procedure Prescription", procedure_rx[0])
+					if frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "is_billable") == 1:
+						item_to_invoice.append({'reference_type': 'Procedure Prescription', 'reference_name': rx_obj.name,
+						'service': frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "item")})
+
+			procedures = frappe.get_list("Clinical Procedure",
+			{'patient': patient.name, 'invoice_separately_as_consumables': True, 'consumption_invoiced': False,
+			'consume_stock': True, 'status': 'Completed'})
+			if procedures:
+				service_item = get_healthcare_service_item('clinical_procedure_consumable_item')
+				if not service_item:
+					msg = _(("Please Configure {0} in ").format("Clinical Procedure Consumable Item") \
+						+ """<b><a href="#Form/Healthcare Settings">Healthcare Settings</a></b>""")
+					frappe.throw(msg)
+				for procedure in procedures:
+					procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
+					item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
+					'service': service_item, 'rate': procedure_obj.consumable_total_amount, 'description': procedure_obj.consumption_details})
+
+			inpatient_services = frappe.db.sql("""select io.name, io.parent from `tabInpatient Record` ip,
+			`tabInpatient Occupancy` io where ip.patient=%s and io.parent=ip.name and
+			io.left=1 and io.invoiced=0""", (patient.name))
+			if inpatient_services:
+				for inpatient_service in inpatient_services:
+					inpatient_occupancy = frappe.get_doc("Inpatient Occupancy", inpatient_service[0])
+					service_unit_type = frappe.get_doc("Healthcare Service Unit Type", frappe.db.get_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "service_unit_type"))
+					if service_unit_type and service_unit_type.is_billable == 1:
+						hours_occupied = time_diff_in_hours(inpatient_occupancy.check_out, inpatient_occupancy.check_in)
+						qty = 0.5
+						if hours_occupied > 0:
+							actual_qty = hours_occupied / service_unit_type.no_of_hours
+							floor = math.floor(actual_qty)
+							decimal_part = actual_qty - floor
+							if decimal_part > 0.5:
+								qty = rounded(floor + 1, 1)
+							elif decimal_part < 0.5 and decimal_part > 0:
+								qty = rounded(floor + 0.5, 1)
+							if qty <= 0:
+								qty = 0.5
+						item_to_invoice.append({'reference_type': 'Inpatient Occupancy', 'reference_name': inpatient_occupancy.name,
+						'service': service_unit_type.item, 'qty': qty})
+
+			return item_to_invoice
+		else:
+			frappe.throw(_("The Patient {0} do not have customer refrence to invoice").format(patient.name))
+
+def service_item_and_practitioner_charge(doc):
+	is_ip = doc_is_ip(doc)
+	if is_ip:
+		service_item = get_practitioner_service_item(doc.practitioner, "inpatient_visit_charge_item")
+		if not service_item:
+			service_item = get_healthcare_service_item("inpatient_visit_charge_item")
+	else:
+		service_item = get_practitioner_service_item(doc.practitioner, "op_consulting_charge_item")
+		if not service_item:
+			service_item = get_healthcare_service_item("op_consulting_charge_item")
+	if not service_item:
+		throw_config_service_item(is_ip)
+
+	practitioner_charge = get_practitioner_charge(doc.practitioner, is_ip)
+	if not practitioner_charge:
+		throw_config_practitioner_charge(is_ip, doc.practitioner)
+
+	return service_item, practitioner_charge
+
+def throw_config_service_item(is_ip):
+	service_item_lable = "Out Patient Consulting Charge Item"
+	if is_ip:
+		service_item_lable = "Inpatient Visit Charge Item"
+
+	msg = _(("Please Configure {0} in ").format(service_item_lable) \
+		+ """<b><a href="#Form/Healthcare Settings">Healthcare Settings</a></b>""")
+	frappe.throw(msg)
+
+def throw_config_practitioner_charge(is_ip, practitioner):
+	charge_name = "OP Consulting Charge"
+	if is_ip:
+		charge_name = "Inpatient Visit Charge"
+
+	msg = _(("Please Configure {0} for Healthcare Practitioner").format(charge_name) \
+		+ """ <b><a href="#Form/Healthcare Practitioner/{0}">{0}</a></b>""".format(practitioner))
+	frappe.throw(msg)
+
+def get_practitioner_service_item(practitioner, service_item_field):
+	return frappe.db.get_value("Healthcare Practitioner", practitioner, service_item_field)
+
+def get_healthcare_service_item(service_item_field):
+	return frappe.db.get_value("Healthcare Settings", None, service_item_field)
+
+def doc_is_ip(doc):
+	is_ip = False
+	if doc.inpatient_record:
+		is_ip = True
+	return is_ip
+
+def get_practitioner_charge(practitioner, is_ip):
+	if is_ip:
+		practitioner_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "inpatient_visit_charge")
+	else:
+		practitioner_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
+	if practitioner_charge:
+		return practitioner_charge
+	return False
+
+def manage_invoice_submit_cancel(doc, method):
+	if doc.items:
+		for item in doc.items:
+			if item.reference_dt and item.reference_dn:
+				if frappe.get_meta(item.reference_dt).has_field("invoiced"):
+					set_invoiced(item, method, doc.name)
+
+	if method=="on_submit" and frappe.db.get_value("Healthcare Settings", None, "create_test_on_si_submit") == '1':
+		create_multiple("Sales Invoice", doc.name)
+
+def set_invoiced(item, method, ref_invoice=None):
+	invoiced = False
+	if(method=="on_submit"):
+		validate_invoiced_on_submit(item)
+		invoiced = True
+
+	if item.reference_dt == 'Clinical Procedure':
+		if get_healthcare_service_item('clinical_procedure_consumable_item') == item.item_code:
+			frappe.db.set_value(item.reference_dt, item.reference_dn, "consumption_invoiced", invoiced)
+		else:
+			frappe.db.set_value(item.reference_dt, item.reference_dn, "invoiced", invoiced)
+	else:
+		frappe.db.set_value(item.reference_dt, item.reference_dn, "invoiced", invoiced)
+
+	if item.reference_dt == 'Patient Appointment':
+		if frappe.db.get_value('Patient Appointment', item.reference_dn, 'procedure_template'):
+			dt_from_appointment = "Clinical Procedure"
+		else:
+			manage_fee_validity(item.reference_dn, method, ref_invoice)
+			dt_from_appointment = "Patient Encounter"
+		manage_doc_for_appoitnment(dt_from_appointment, item.reference_dn, invoiced)
+
+	elif item.reference_dt == 'Lab Prescription':
+		manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, "Lab Test", "test_created")
+
+	elif item.reference_dt == 'Procedure Prescription':
+		manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, "Clinical Procedure", "procedure_created")
+
+def validate_invoiced_on_submit(item):
+	if item.reference_dt == 'Clinical Procedure' and get_healthcare_service_item('clinical_procedure_consumable_item') == item.item_code:
+			is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, "consumption_invoiced")
+	else:
+		is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, "invoiced")
+	if is_invoiced == 1:
+		frappe.throw(_("The item referenced by {0} - {1} is already invoiced"\
+		).format(item.reference_dt, item.reference_dn))
+
+def manage_prescriptions(invoiced, ref_dt, ref_dn, dt, created_check_field):
+	created = frappe.db.get_value(ref_dt, ref_dn, created_check_field)
+	if created == 1:
+		# Fetch the doc created for the prescription
+		doc_created = frappe.db.get_value(dt, {'prescription': ref_dn})
+		frappe.db.set_value(dt, doc_created, 'invoiced', invoiced)
+
+def validity_exists(practitioner, patient):
+	return frappe.db.exists({
+			"doctype": "Fee Validity",
+			"practitioner": practitioner,
+			"patient": patient})
+
+def manage_fee_validity(appointment_name, method, ref_invoice=None):
+	appointment_doc = frappe.get_doc("Patient Appointment", appointment_name)
+	validity_exist = validity_exists(appointment_doc.practitioner, appointment_doc.patient)
+	do_not_update = False
+	visited = 0
+	if validity_exist:
+		fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
+		# Check if the validity is valid
+		if (fee_validity.valid_till >= appointment_doc.appointment_date):
+			if (method == "on_cancel" and appointment_doc.status != "Closed"):
+				if ref_invoice == fee_validity.ref_invoice:
+					visited = fee_validity.visited - 1
+					if visited < 0:
+						visited = 0
+					frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+				do_not_update = True
+			elif (method == "on_submit" and fee_validity.visited < fee_validity.max_visit):
+				visited = fee_validity.visited + 1
+				frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+				do_not_update = True
+			else:
+				do_not_update = False
+
+		if not do_not_update:
+			fee_validity = update_fee_validity(fee_validity, appointment_doc.appointment_date, ref_invoice)
+			visited = fee_validity.visited
+	else:
+		fee_validity = create_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date, ref_invoice)
+		visited = fee_validity.visited
+
+	print("do_not_update: ", do_not_update)
+	print("visited: ", visited)
+
+	# Mark All Patient Appointment invoiced = True in the validity range do not cross the max visit
+	if (method == "on_cancel"):
+		invoiced = True
+	else:
+		invoiced = False
+
+	patient_appointments = appointments_valid_in_fee_validity(appointment_doc, invoiced)
+	if patient_appointments and fee_validity:
+		visit = visited
+		for appointment in patient_appointments:
+			if (method == "on_cancel" and appointment.status != "Closed"):
+				if ref_invoice == fee_validity.ref_invoice:
+					visited = visited - 1
+					if visited < 0:
+						visited = 0
+					frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+				frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", False)
+				manage_doc_for_appoitnment("Patient Encounter", appointment.name, False)
+			elif method == "on_submit" and int(fee_validity.max_visit) > visit:
+				if ref_invoice == fee_validity.ref_invoice:
+					visited = visited + 1
+					frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
+				frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
+				manage_doc_for_appoitnment("Patient Encounter", appointment.name, True)
+			if ref_invoice == fee_validity.ref_invoice:
+				visit = visit + 1
+
+	if method == "on_cancel":
+		ref_invoice_in_fee_validity = frappe.db.get_value("Fee Validity", fee_validity.name, 'ref_invoice')
+		if ref_invoice_in_fee_validity == ref_invoice:
+			frappe.delete_doc("Fee Validity", fee_validity.name)
+
+def appointments_valid_in_fee_validity(appointment, invoiced):
+	valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
+	max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
+	valid_days_date = add_days(getdate(appointment.appointment_date), int(valid_days))
+	return frappe.get_list("Patient Appointment",{'patient': appointment.patient, 'invoiced': invoiced,
+	'appointment_date':("<=", valid_days_date), 'appointment_date':(">=", getdate(appointment.appointment_date)),
+	'practitioner': appointment.practitioner}, order_by="appointment_date", limit=int(max_visit)-1)
+
+def manage_doc_for_appoitnment(dt_from_appointment, appointment, invoiced):
+	dn_from_appointment = frappe.db.exists(
+		dt_from_appointment,
+		{
+			"appointment": appointment
+		}
+	)
+	if dn_from_appointment:
+		frappe.db.set_value(dt_from_appointment, dn_from_appointment, "invoiced", invoiced)
+
+@frappe.whitelist()
+def get_drugs_to_invoice(encounter):
+	encounter = frappe.get_doc("Patient Encounter", encounter)
+	if encounter:
+		patient = frappe.get_doc("Patient", encounter.patient)
+		if patient and patient.customer:
+				item_to_invoice = []
+				for drug_line in encounter.drug_prescription:
+					if drug_line.drug_code:
+						qty = 1
+						if frappe.db.get_value("Item", drug_line.drug_code, "stock_uom") == "Nos":
+							qty = drug_line.get_quantity()
+						item_to_invoice.append({'drug_code': drug_line.drug_code, 'quantity': qty,
+						'description': drug_line.dosage+" for "+drug_line.period})
+				return item_to_invoice
+
+@frappe.whitelist()
+def get_children(doctype, parent, company, is_root=False):
+	parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_')
+	fields = [
+		'name as value',
+		'is_group as expandable',
+		'lft',
+		'rgt'
+	]
+	# fields = [ 'name', 'is_group', 'lft', 'rgt' ]
+	filters = [['ifnull(`{0}`,"")'.format(parent_fieldname), '=', '' if is_root else parent]]
+
+	if is_root:
+		fields += ['service_unit_type'] if doctype == 'Healthcare Service Unit' else []
+		filters.append(['company', '=', company])
+
+	else:
+		fields += ['service_unit_type', 'allow_appointments', 'inpatient_occupancy', 'occupancy_status'] if doctype == 'Healthcare Service Unit' else []
+		fields += [parent_fieldname + ' as parent']
+
+	hc_service_units = frappe.get_list(doctype, fields=fields, filters=filters)
+
+	if doctype == 'Healthcare Service Unit':
+		for each in hc_service_units:
+			occupancy_msg = ""
+			if each['expandable'] == 1:
+				occupied = False
+				vacant = False
+				child_list = frappe.db.sql("""
+					select name, occupancy_status from `tabHealthcare Service Unit`
+					where inpatient_occupancy = 1 and
+					lft > %s and rgt < %s""",
+					(each['lft'], each['rgt']))
+				for child in child_list:
+					print(child[0], child[1])
+					if not occupied:
+						occupied = 0
+					if child[1] == "Occupied":
+						occupied += 1
+					if not vacant:
+						vacant = 0
+					if child[1] == "Vacant":
+						vacant += 1
+				if vacant and occupied:
+					occupancy_total = vacant+occupied
+					occupancy_msg = str(occupied) + " Occupied out of " + str(occupancy_total)
+			each["occupied_out_of_vacant"] = occupancy_msg
+	return hc_service_units
diff --git a/erpnext/healthcare/web_form/lab_test/lab_test.json b/erpnext/healthcare/web_form/lab_test/lab_test.json
index 89029fa..f6f51b2 100644
--- a/erpnext/healthcare/web_form/lab_test/lab_test.json
+++ b/erpnext/healthcare/web_form/lab_test/lab_test.json
@@ -18,7 +18,7 @@
  "is_standard": 1, 
  "login_required": 1, 
  "max_attachment_size": 0, 
- "modified": "2018-07-16 13:10:47.940128", 
+ "modified": "2018-07-17 13:10:47.940128", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "lab-test", 
@@ -44,13 +44,14 @@
    "reqd": 1
   }, 
   {
-   "fieldname": "invoice", 
-   "fieldtype": "Link", 
+   "default": "0", 
+   "fieldname": "invoiced", 
+   "fieldtype": "Check", 
    "hidden": 0, 
-   "label": "Invoice", 
+   "label": "Invoiced", 
    "max_length": 0, 
    "max_value": 0, 
-   "options": "Sales Invoice", 
+   "options": "", 
    "read_only": 0, 
    "reqd": 0
   }, 
@@ -232,4 +233,4 @@
    "reqd": 0
   }
  ]
-}
\ No newline at end of file
+}
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index c706be9..a01011a 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -127,6 +127,23 @@
 				if(!r.exc) frm.refresh_fields();
 			}
 		});
+	},
+
+	routing: function(frm) {
+		if (frm.doc.routing) {
+			frappe.call({
+				doc: frm.doc,
+				method: "get_routing",
+				freeze: true,
+				callback: function(r) {
+					if (!r.exc) {
+						frm.refresh_fields();
+						erpnext.bom.calculate_op_cost(frm.doc);
+						erpnext.bom.calculate_total(frm.doc);
+					}
+				}
+			});
+		}
 	}
 });
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.json b/erpnext/manufacturing/doctype/bom/bom.json
index 69a75c4..77fc498 100644
--- a/erpnext/manufacturing/doctype/bom/bom.json
+++ b/erpnext/manufacturing/doctype/bom/bom.json
@@ -479,6 +479,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "depends_on": "with_operations", 
+   "fieldname": "transfer_material_against_job_card", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Transfer Material Against Job Card", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "currency_detail", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -674,6 +707,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "routing", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Routing", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Routing", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "operations", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -1877,7 +1943,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-06-01 03:45:06.731308", 
+ "modified": "2018-07-15 11:09:19.425998", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "BOM", 
@@ -1930,5 +1996,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 98aee05..5e9f46c 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -89,6 +89,13 @@
 
 		return item
 
+	def get_routing(self):
+		if self.routing:
+			for d in frappe.get_all("BOM Operation", fields = ["*"],
+				filters = {'parenttype': 'Routing', 'parent': self.routing}):
+				child = self.append('operations', d)
+				child.hour_rate = flt(d.hour_rate / self.conversion_rate, 2)
+
 	def validate_rm_item(self, item):
 		if (item[0]['name'] in [it.item_code for it in self.items]) and item[0]['name'] == self.item:
 			frappe.throw(_("BOM #{0}: Raw material cannot be same as main Item").format(self.name))
@@ -458,6 +465,7 @@
 				self.add_to_cur_exploded_items(frappe._dict({
 					'item_code'		: d.item_code,
 					'item_name'		: d.item_name,
+					'operation'		: d.operation,
 					'source_warehouse': d.source_warehouse,
 					'description'	: d.description,
 					'image'			: d.image,
@@ -480,7 +488,7 @@
 		""" Add all items from Flat BOM of child BOM"""
 		# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
 		child_fb_items = frappe.db.sql("""select bom_item.item_code, bom_item.item_name,
-			bom_item.description, bom_item.source_warehouse,
+			bom_item.description, bom_item.source_warehouse, bom_item.operation,
 			bom_item.stock_uom, bom_item.stock_qty, bom_item.rate, bom_item.allow_transfer_for_manufacture,
 			bom_item.stock_qty / ifnull(bom.quantity, 1) as qty_consumed_per_unit
 			from `tabBOM Explosion Item` bom_item, tabBOM bom
@@ -491,6 +499,7 @@
 				'item_code'				: d['item_code'],
 				'item_name'				: d['item_name'],
 				'source_warehouse'		: d['source_warehouse'],
+				'operation'				: d['operation'],
 				'description'			: d['description'],
 				'stock_uom'				: d['stock_uom'],
 				'stock_qty'				: d['qty_consumed_per_unit'] * stock_qty,
@@ -571,7 +580,7 @@
 		query = query.format(table="BOM Explosion Item",
 			where_conditions="",
 			is_stock_item=is_stock_item,
-			select_columns = """, bom_item.source_warehouse, bom_item.allow_transfer_for_manufacture,
+			select_columns = """, bom_item.source_warehouse, bom_item.operation, bom_item.allow_transfer_for_manufacture,
 				(Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s ) as idx""")
 
 		items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
@@ -580,7 +589,7 @@
 		items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
 	else:
 		query = query.format(table="BOM Item", where_conditions="", is_stock_item=is_stock_item,
-			select_columns = ", bom_item.source_warehouse, bom_item.idx, bom_item.allow_transfer_for_manufacture")
+			select_columns = ", bom_item.source_warehouse, bom_item.idx, bom_item.operation, bom_item.allow_transfer_for_manufacture")
 		items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
 
 	for item in items:
diff --git a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
index 8c7db8f..ab3c5a1 100644
--- a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
+++ b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
@@ -54,37 +54,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "cb", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "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, 
    "fieldname": "item_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -117,6 +86,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "cb", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "source_warehouse", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -150,6 +150,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "operation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Operation", 
+   "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, 
    "fieldname": "section_break_3", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -576,7 +609,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-07-12 16:29:55.464426", 
+ "modified": "2018-08-27 16:32:35.152139", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "BOM Explosion Item", 
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index ceee2c1..b31f692 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -17,6 +17,39 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "operation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Operation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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": 3, 
    "fieldname": "item_code", 
    "fieldtype": "Link", 
@@ -1000,7 +1033,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-07-12 16:16:16.815165", 
+ "modified": "2018-08-22 16:16:16.815165", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "BOM Item", 
diff --git a/erpnext/manufacturing/doctype/job_card/__init__.py b/erpnext/manufacturing/doctype/job_card/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/__init__.py
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js
new file mode 100644
index 0000000..6f5290e
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card.js
@@ -0,0 +1,113 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Job Card', {
+	refresh: function(frm) {
+		if (frm.doc.items && frm.doc.docstatus==1) {
+			if (frm.doc.for_quantity != frm.doc.transferred_qty) {
+				frm.add_custom_button(__("Material Request"), () => {
+					frm.trigger("make_material_request");
+				});
+			}
+
+			if (frm.doc.for_quantity != frm.doc.transferred_qty) {
+				frm.add_custom_button(__("Material Transfer"), () => {
+					frm.trigger("make_stock_entry");
+				});
+			}
+		}
+
+		if (frm.doc.docstatus == 0) {
+			if (!frm.doc.actual_start_date || !frm.doc.actual_end_date) {
+				frm.trigger("make_dashboard");
+			}
+
+			if (!frm.doc.actual_start_date) {
+				frm.add_custom_button(__("Start Job"), () => {
+					frm.set_value('actual_start_date', frappe.datetime.now_datetime());
+					frm.save();
+				});
+			} else if (!frm.doc.actual_end_date) {
+				frm.add_custom_button(__("Complete Job"), () => {
+					frm.set_value('actual_end_date', frappe.datetime.now_datetime());
+					frm.save();
+				});
+			}
+		}
+	},
+
+	make_dashboard: function(frm) {
+		if(frm.doc.__islocal)
+			return;
+
+		frm.dashboard.refresh();
+		const timer = `
+			<div class="stopwatch" style="font-weight:bold">
+				<span class="hours">00</span>
+				<span class="colon">:</span>
+				<span class="minutes">00</span>
+				<span class="colon">:</span>
+				<span class="seconds">00</span>
+			</div>`;
+
+		var section = frm.dashboard.add_section(timer);
+
+		if (frm.doc.actual_start_date) {
+			let currentIncrement = moment(frappe.datetime.now_datetime()).diff(moment(frm.doc.actual_start_date),"seconds");
+			initialiseTimer();
+
+			function initialiseTimer() {
+				const interval = setInterval(function() {
+					var current = setCurrentIncrement();
+					updateStopwatch(current);
+				}, 1000);
+			}
+
+			function updateStopwatch(increment) {
+				var hours = Math.floor(increment / 3600);
+				var minutes = Math.floor((increment - (hours * 3600)) / 60);
+				var seconds = increment - (hours * 3600) - (minutes * 60);
+
+				$(section).find(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
+				$(section).find(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
+				$(section).find(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());
+			}
+
+			function setCurrentIncrement() {
+				currentIncrement += 1;
+				return currentIncrement;
+			}
+		}
+	},
+
+	for_quantity: function(frm) {
+		frm.doc.items = [];
+		frm.call({
+			method: "get_required_items",
+			doc: frm.doc,
+			callback: function() {
+				refresh_field("items");
+			}
+		})
+	},
+
+	make_material_request: function(frm) {
+		frappe.model.open_mapped_doc({
+			method: "erpnext.manufacturing.doctype.job_card.job_card.make_material_request",
+			frm: frm,
+			run_link_triggers: true
+		});
+	},
+
+	make_stock_entry: function(frm) {
+		frappe.model.open_mapped_doc({
+			method: "erpnext.manufacturing.doctype.job_card.job_card.make_stock_entry",
+			frm: frm,
+			run_link_triggers: true
+		});
+	},
+
+	timer: function(frm) {
+		return `<button> Start </button>`
+	}
+});
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.json b/erpnext/manufacturing/doctype/job_card/job_card.json
new file mode 100644
index 0000000..443cad8
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card.json
@@ -0,0 +1,912 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "autoname": "PO-JOB.#####", 
+ "beta": 0, 
+ "creation": "2018-07-09 17:23:29.518745", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "work_order", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Work Order", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Work Order", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 1, 
+   "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, 
+   "fieldname": "workstation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Workstation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Workstation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "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, 
+   "fieldname": "operation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Operation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "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, 
+   "fieldname": "wip_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "WIP Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "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, 
+   "fieldname": "column_break_4", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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": "Today", 
+   "fieldname": "posting_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Posting Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "company", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Company", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Company", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "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, 
+   "fieldname": "for_quantity", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "For Quantity", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "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": "transferred_qty", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Transferred Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "fieldname": "timing_detail", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Timing Detail", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "employee", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Employee", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Employee", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "time_in_mins", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Time In Mins", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "fieldname": "column_break_13", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "actual_start_date", 
+   "fieldtype": "Datetime", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Actual Start Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "actual_end_date", 
+   "fieldtype": "Datetime", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Actual End Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "section_break_8", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Raw Materials", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "items", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Items", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Job Card Item", 
+   "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": 1, 
+   "columns": 0, 
+   "fieldname": "more_information", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "More Information", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "operation_id", 
+   "fieldtype": "Data", 
+   "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": "Operation ID", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "fieldname": "bom_no", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "BOM No", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "BOM", 
+   "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, 
+   "fieldname": "project", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Project", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Project", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "column_break_20", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "remarks", 
+   "fieldtype": "Small Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Remarks", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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": "Open", 
+   "fieldname": "status", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Status", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Open\nWork In Progress\nCancelled\nCompleted", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "amended_from", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Amended From", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "Job Card", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "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
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 1, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2018-08-28 16:50:43.576151", 
+ "modified_by": "Administrator", 
+ "module": "Manufacturing", 
+ "name": "Job Card", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 1, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "System Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }, 
+  {
+   "amend": 1, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Manufacturing User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }, 
+  {
+   "amend": 1, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Manufacturing Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "title_field": "operation", 
+ "track_changes": 1, 
+ "track_seen": 0, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
new file mode 100644
index 0000000..bce5b90
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -0,0 +1,211 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import flt, time_diff_in_hours, get_datetime
+from frappe.model.mapper import get_mapped_doc
+from frappe.model.document import Document
+
+class JobCard(Document):
+	def validate(self):
+		self.status = 'Open'
+		self.validate_actual_dates()
+		self.set_time_in_mins()
+
+	def validate_actual_dates(self):
+		if get_datetime(self.actual_start_date) > get_datetime(self.actual_end_date):
+			frappe.throw(_("Actual start date must be less than actual end date"))
+
+		if not (self.employee and self.actual_start_date and self.actual_end_date):
+			return
+
+		data = frappe.db.sql(""" select name from `tabJob Card`
+			where
+				((%(actual_start_date)s > actual_start_date and %(actual_start_date)s < actual_end_date) or
+				(%(actual_end_date)s > actual_start_date and %(actual_end_date)s < actual_end_date) or
+				(%(actual_start_date)s <= actual_start_date and %(actual_end_date)s >= actual_end_date)) and
+				name != %(name)s and employee = %(employee)s and docstatus =1
+		""", {
+			'actual_start_date': self.actual_start_date,
+			'actual_end_date': self.actual_end_date,
+			'employee': self.employee,
+			'name': self.name
+		}, as_dict=1)
+
+		if data:
+			frappe.throw(_("Start date and end date is overlapping with the job card <a href='#Form/Job Card/{0}'>{1}</a>")
+				.format(data[0].name, data[0].name))
+
+	def set_time_in_mins(self):
+		if self.actual_start_date and self.actual_end_date:
+			self.time_in_mins = time_diff_in_hours(self.actual_end_date, self.actual_start_date) * 60
+
+	def get_required_items(self):
+		if not self.get('work_order'):
+			return
+
+		doc = frappe.get_doc('Work Order', self.get('work_order'))
+		if not doc.transfer_material_against_job_card and doc.skip_transfer:
+			return
+
+		for d in doc.required_items:
+			if not d.operation:
+				frappe.throw(_("Row {0} : Operation is required against the raw material item {1}")
+					.format(d.idx, d.item_code))
+
+			if self.get('operation') == d.operation:
+				child = self.append('items', {
+					'item_code': d.item_code,
+					'source_warehouse': d.source_warehouse,
+					'uom': frappe.db.get_value("Item", d.item_code, 'stock_uom'),
+					'item_name': d.item_name,
+					'description': d.description,
+					'required_qty': (d.required_qty * flt(self.for_quantity)) / doc.qty
+				})
+
+	def on_submit(self):
+		self.validate_dates()
+		self.update_work_order()
+		self.set_transferred_qty()
+
+	def validate_dates(self):
+		if not self.actual_start_date and not self.actual_end_date:
+			frappe.throw(_("Actual start date and actual end date is mandatory"))
+
+	def on_cancel(self):
+		self.update_work_order()
+		self.set_transferred_qty()
+
+	def update_work_order(self):
+		if not self.work_order:
+			return
+
+		data = frappe.db.get_value("Job Card", {'docstatus': 1, 'operation_id': self.operation_id},
+			['sum(time_in_mins)', 'min(actual_start_date)', 'max(actual_end_date)', 'sum(for_quantity)'])
+
+		if data:
+			time_in_mins, actual_start_date, actual_end_date, for_quantity = data
+
+			wo = frappe.get_doc('Work Order', self.work_order)
+
+			for data in wo.operations:
+				if data.name == self.operation_id:
+					data.completed_qty = for_quantity
+					data.actual_operation_time = time_in_mins
+					data.actual_start_time = actual_start_date
+					data.actual_end_time = actual_end_date
+
+			wo.flags.ignore_validate_update_after_submit = True
+			wo.update_operation_status()
+			wo.calculate_operating_cost()
+			wo.set_actual_dates()
+			wo.save()
+
+	def set_transferred_qty(self):
+		if not self.items:
+			self.transferred_qty = self.for_quantity if self.docstatus == 1 else 0
+
+		if self.items:
+			self.transferred_qty = frappe.db.get_value('Stock Entry', {'job_card': self.name,
+				'work_order': self.work_order, 'docstatus': 1}, 'sum(fg_completed_qty)')
+
+		self.db_set("transferred_qty", self.transferred_qty)
+
+		qty = 0
+		if self.work_order:
+			doc = frappe.get_doc('Work Order', self.work_order)
+			if doc.transfer_material_against_job_card and not doc.skip_transfer:
+				completed = True
+				for d in doc.operations:
+					if d.status != 'Completed':
+						completed = False
+						break
+
+				if completed:
+					job_cards = frappe.get_all('Job Card', filters = {'work_order': self.work_order, 
+						'docstatus': ('!=', 2)}, fields = 'sum(transferred_qty) as qty', group_by='operation_id')
+					qty = min([d.qty for d in job_cards])
+
+			doc.db_set('material_transferred_for_manufacturing', qty)
+
+		self.set_status()
+
+	def set_status(self):
+		status = 'Cancelled' if self.docstatus == 2 else 'Work In Progress'
+
+		if self.for_quantity == self.transferred_qty:
+			status = 'Completed'
+
+		self.db_set('status', status)
+
+def update_job_card_reference(name, fieldname, value):
+	frappe.db.set_value('Job Card', name, fieldname, value)
+
+@frappe.whitelist()
+def make_material_request(source_name, target_doc=None):
+	def update_item(obj, target, source_parent):
+		target.warehouse = source_parent.wip_warehouse
+
+	def set_missing_values(source, target):
+		target.material_request_type = "Material Transfer"
+
+	doclist = get_mapped_doc("Job Card", source_name, {
+		"Job Card": {
+			"doctype": "Material Request",
+			"validation": {
+				"docstatus": ["=", 1]
+			},
+			"field_map": {
+				"name": "job_card",
+			},
+		},
+		"Job Card Item": {
+			"doctype": "Material Request Item",
+			"field_map": {
+				"required_qty": "qty",
+				"uom": "stock_uom"
+			},
+			"postprocess": update_item,
+		}
+	}, target_doc, set_missing_values)
+
+	return doclist
+
+@frappe.whitelist()
+def make_stock_entry(source_name, target_doc=None):
+	def update_item(obj, target, source_parent):
+		target.t_warehouse = source_parent.wip_warehouse
+
+	def set_missing_values(source, target):
+		target.purpose = "Material Transfer for Manufacture"
+		target.from_bom = 1
+		target.fg_completed_qty = source.get('for_quantity', 0) - source.get('transferred_qty', 0)
+		target.calculate_rate_and_amount()
+		target.set_missing_values()
+
+	doclist = get_mapped_doc("Job Card", source_name, {
+		"Job Card": {
+			"doctype": "Stock Entry",
+			"validation": {
+				"docstatus": ["=", 1]
+			},
+			"field_map": {
+				"name": "job_card",
+				"for_quantity": "fg_completed_qty"
+			},
+		},
+		"Job Card Item": {
+			"doctype": "Stock Entry Detail",
+			"field_map": {
+				"source_warehouse": "s_warehouse",
+				"required_qty": "qty",
+				"uom": "stock_uom"
+			},
+			"postprocess": update_item,
+		}
+	}, target_doc, set_missing_values)
+
+	return doclist
diff --git a/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py b/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py
new file mode 100644
index 0000000..a9811fc
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py
@@ -0,0 +1,12 @@
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'job_card',
+		'transactions': [
+			{
+				'label': _('Transactions'),
+				'items': ['Material Request', 'Stock Entry']
+			}
+		]
+	}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/job_card_list.js b/erpnext/manufacturing/doctype/job_card/job_card_list.js
new file mode 100644
index 0000000..d40a9fa
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card_list.js
@@ -0,0 +1,13 @@
+frappe.listview_settings['Job Card'] = {
+	get_indicator: function(doc) {
+		if (doc.status === "Work In Progress") {
+			return [__("Work In Progress"), "orange", "status,=,Work In Progress"];
+		} else if (doc.status === "Completed") {
+			return [__("Completed"), "green", "status,=,Completed"];
+		} else if (doc.docstatus == 2) {
+			return [__("Cancelled"), "red", "status,=,Cancelled"];
+		} else {
+			return [__("Open"), "red", "status,=,Open"];
+		}
+	}
+};
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.js b/erpnext/manufacturing/doctype/job_card/test_job_card.js
new file mode 100644
index 0000000..5dc7805
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/test_job_card.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Job Card", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Job Card
+		() => frappe.tests.make('Job Card', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.py b/erpnext/manufacturing/doctype/job_card/test_job_card.py
new file mode 100644
index 0000000..ca05fea
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/test_job_card.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestJobCard(unittest.TestCase):
+	pass
diff --git a/erpnext/manufacturing/doctype/job_card_item/__init__.py b/erpnext/manufacturing/doctype/job_card_item/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_item/__init__.py
diff --git a/erpnext/manufacturing/doctype/job_card_item/job_card_item.json b/erpnext/manufacturing/doctype/job_card_item/job_card_item.json
new file mode 100644
index 0000000..bc9fe10
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_item/job_card_item.json
@@ -0,0 +1,363 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-07-09 17:20:44.737289", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "item_code", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Item Code", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "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, 
+   "fieldname": "source_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 1, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Source Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "uom", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "UOM", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "UOM", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "column_break_3", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "item_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Item Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "fieldname": "description", 
+   "fieldtype": "Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Description", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "fieldname": "qty_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "required_qty", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Required Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "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, 
+   "fieldname": "column_break_9", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "allow_alternative_item", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Allow Alternative Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2018-08-28 15:23:48.099459", 
+ "modified_by": "Administrator", 
+ "module": "Manufacturing", 
+ "name": "Job Card Item", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card_item/job_card_item.py b/erpnext/manufacturing/doctype/job_card_item/job_card_item.py
new file mode 100644
index 0000000..373cba2
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_item/job_card_item.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class JobCardItem(Document):
+	pass
diff --git a/erpnext/manufacturing/doctype/routing/__init__.py b/erpnext/manufacturing/doctype/routing/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/__init__.py
diff --git a/erpnext/manufacturing/doctype/routing/routing.js b/erpnext/manufacturing/doctype/routing/routing.js
new file mode 100644
index 0000000..6cfd0ba
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/routing.js
@@ -0,0 +1,58 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Routing', {
+	calculate_operating_cost: function(frm, child) {
+		const operating_cost = flt(flt(child.hour_rate) * flt(child.time_in_mins) / 60, 2);
+		frappe.model.set_value(child.doctype, child.name, "operating_cost", operating_cost);
+	}
+});
+
+frappe.ui.form.on('BOM Operation', {
+	operation: function(frm, cdt, cdn) {
+		const d = locals[cdt][cdn];
+
+		if(!d.operation) return;
+
+		frappe.call({
+			"method": "frappe.client.get",
+			args: {
+				doctype: "Operation",
+				name: d.operation
+			},
+			callback: function (data) {
+				if (data.message.description) {
+					frappe.model.set_value(d.doctype, d.name, "description", data.message.description);
+				}
+
+				if (data.message.workstation) {
+					frappe.model.set_value(d.doctype, d.name, "workstation", data.message.workstation);
+				}
+
+				frm.events.calculate_operating_cost(frm, d);
+			}
+		});
+	},
+
+	workstation: function(frm, cdt, cdn) {
+		const d = locals[cdt][cdn];
+
+		frappe.call({
+			"method": "frappe.client.get",
+			args: {
+				doctype: "Workstation",
+				name: d.workstation
+			},
+			callback: function (data) {
+				frappe.model.set_value(d.doctype, d.name, "base_hour_rate", data.message.hour_rate);
+				frappe.model.set_value(d.doctype, d.name, "hour_rate", data.message.hour_rate);
+				frm.events.calculate_operating_cost(frm, d);
+			}
+		});
+	},
+
+	time_in_mins: function(frm, cdt, cdn) {
+		const d = locals[cdt][cdn];
+		frm.events.calculate_operating_cost(frm, d);
+	}
+});
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/routing/routing.json b/erpnext/manufacturing/doctype/routing/routing.json
new file mode 100644
index 0000000..e864c0c
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/routing.json
@@ -0,0 +1,180 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "autoname": "field:routing_name", 
+ "beta": 0, 
+ "creation": "2018-07-15 11:03:24.191613", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "routing_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Routing Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 1
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:!doc.__islocal", 
+   "fieldname": "disabled", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Disabled", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "fieldname": "operations", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "BOM Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "BOM Operation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2018-07-15 11:42:41.424793", 
+ "modified_by": "Administrator", 
+ "module": "Manufacturing", 
+ "name": "Routing", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Manufacturing Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 1
+  }, 
+  {
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Manufacturing User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/routing/routing.py b/erpnext/manufacturing/doctype/routing/routing.py
new file mode 100644
index 0000000..ecd0ba8
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/routing.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class Routing(Document):
+	pass
diff --git a/erpnext/manufacturing/doctype/routing/test_routing.js b/erpnext/manufacturing/doctype/routing/test_routing.js
new file mode 100644
index 0000000..6cb6549
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/test_routing.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Routing", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Routing
+		() => frappe.tests.make('Routing', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/manufacturing/doctype/routing/test_routing.py b/erpnext/manufacturing/doctype/routing/test_routing.py
new file mode 100644
index 0000000..53ad152
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/test_routing.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestRouting(unittest.TestCase):
+	pass
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index b32db3b..fb8fd26 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -73,53 +73,6 @@
 
 		self.assertRaises(StockOverProductionError, s.submit)
 
-	def test_make_time_sheet(self):
-		from erpnext.manufacturing.doctype.work_order.work_order import make_timesheet
-		wo_order = make_wo_order_test_record(item="_Test FG Item 2",
-			planned_start_date=now(), qty=1, do_not_save=True)
-
-		wo_order.set_work_order_operations()
-		wo_order.insert()
-		wo_order.submit()
-
-		d = wo_order.operations[0]
-		d.completed_qty = flt(d.completed_qty)
-
-		name = frappe.db.get_value('Timesheet', {'work_order': wo_order.name}, 'name')
-		time_sheet_doc = frappe.get_doc('Timesheet', name)
-		self.assertEqual(wo_order.company, time_sheet_doc.company)
-		time_sheet_doc.submit()
-
-		self.assertEqual(wo_order.name, time_sheet_doc.work_order)
-		self.assertEqual((wo_order.qty - d.completed_qty),
-			sum([d.completed_qty for d in time_sheet_doc.time_logs]))
-
-		manufacturing_settings = frappe.get_doc({
-			"doctype": "Manufacturing Settings",
-			"allow_production_on_holidays": 0
-		})
-
-		manufacturing_settings.save()
-
-		wo_order.load_from_db()
-		self.assertEqual(wo_order.operations[0].status, "Completed")
-		self.assertEqual(wo_order.operations[0].completed_qty, wo_order.qty)
-
-		self.assertEqual(wo_order.operations[0].actual_operation_time, 60)
-		self.assertEqual(wo_order.operations[0].actual_operating_cost, 6000)
-
-		time_sheet_doc1 = make_timesheet(wo_order.name, wo_order.company)
-		self.assertEqual(len(time_sheet_doc1.get('time_logs')), 0)
-
-		time_sheet_doc.cancel()
-
-		wo_order.load_from_db()
-		self.assertEqual(wo_order.operations[0].status, "Pending")
-		self.assertEqual(flt(wo_order.operations[0].completed_qty), 0)
-
-		self.assertEqual(flt(wo_order.operations[0].actual_operation_time), 0)
-		self.assertEqual(flt(wo_order.operations[0].actual_operating_cost), 0)
-
 	def test_planned_operating_cost(self):
 		wo_order = make_wo_order_test_record(item="_Test FG Item 2",
 			planned_start_date=now(), qty=1, do_not_save=True)
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js
index 013183e..e85b0a5 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order.js
@@ -4,7 +4,6 @@
 frappe.ui.form.on("Work Order", {
 	setup: function(frm) {
 		frm.custom_make_buttons = {
-			'Timesheet': 'Make Timesheet',
 			'Stock Entry': 'Make Stock Entry',
 		}
 
@@ -113,13 +112,11 @@
 			frm.trigger('show_progress');
 		}
 
-		if(frm.doc.docstatus == 1 && frm.doc.status != 'Stopped'){
-			frm.add_custom_button(__('Make Timesheet'), function(){
-				frappe.model.open_mapped_doc({
-					method: "erpnext.manufacturing.doctype.work_order.work_order.make_new_timesheet",
-					frm: cur_frm
-				})
-			})
+		if (frm.doc.docstatus === 1 && frm.doc.operations
+			&& frm.doc.qty != frm.doc.material_transferred_for_manufacturing) {
+			frm.add_custom_button(__('Make Job Card'), () => {
+				frm.trigger("make_job_card")
+			}).addClass('btn-primary');
 		}
 
 		if(frm.doc.required_items && frm.doc.allow_alternative_item) {
@@ -139,6 +136,113 @@
 				});
 			}
 		}
+
+		if (frm.doc.status == "Completed" &&
+			frm.doc.__onload.backflush_raw_materials_based_on == "Material Transferred for Manufacture") {
+			frm.add_custom_button(__("Make BOM"), () => {
+				frm.trigger("make_bom");
+			});
+		}
+	},
+
+	make_job_card: function(frm) {
+		let qty = 0;
+		const fields = [{
+			fieldtype: "Link",
+			fieldname: "operation",
+			options: "Operation",
+			label: __("Operation"),
+			get_query: () => {
+				const filter_workstation = frm.doc.operations.filter(d => {
+					if (d.status != "Completed") {
+						return d;
+					}
+				});
+
+				return {
+					filters: {
+						name: ["in", (filter_workstation || []).map(d => d.operation)]
+					}
+				};
+			},
+			reqd: true
+		}, {
+			fieldtype: "Link",
+			fieldname: "workstation",
+			options: "Workstation",
+			label: __("Workstation"),
+			get_query: () => {
+				const operation = dialog.get_value("operation");
+				const filter_workstation = frm.doc.operations.filter(d => {
+					if (d.operation == operation) {
+						return d;
+					}
+				});
+
+				return {
+					filters: {
+						name: ["in", (filter_workstation || []).map(d => d.workstation)]
+					}
+				};
+			},
+			onchange: () => {
+				const operation = dialog.get_value("operation");
+				const workstation = dialog.get_value("workstation");
+				if (operation && workstation) {
+					const row = frm.doc.operations.filter(d => d.operation == operation && d.workstation == workstation)[0];
+					qty = frm.doc.qty - row.completed_qty;
+
+					if (qty > 0) {
+						dialog.set_value("qty", qty);
+					}
+				}
+			},
+			reqd: true
+		}, {
+			fieldtype: "Float",
+			fieldname: "qty",
+			label: __("For Quantity"),
+			reqd: true
+		}];
+
+		const dialog = frappe.prompt(fields, function(data) {
+			if (data.qty > qty) {
+				frappe.throw(__("For Quantity must be less than quantity {0}", [qty]));
+			}
+
+			if (data.qty <= 0) {
+				frappe.throw(__("For Quantity must be greater than zero"));
+			}
+
+			frappe.call({
+				method: "erpnext.manufacturing.doctype.work_order.work_order.make_job_card",
+				args: {
+					work_order: frm.doc.name,
+					operation: data.operation,
+					workstation: data.workstation,
+					qty: data.qty
+				},
+				callback: function(r){
+					if (r.message) {
+						var doc = frappe.model.sync(r.message)[0];
+						frappe.set_route("Form", doc.doctype, doc.name);
+					}
+				}
+			});
+		}, __("For Job Card"));
+	},
+
+	make_bom: function(frm) {
+		frappe.call({
+			method: "make_bom",
+			doc: frm.doc,
+			callback: function(r){
+				if (r.message) {
+					var doc = frappe.model.sync(r.message)[0];
+					frappe.set_route("Form", doc.doctype, doc.name);
+				}
+			}
+		});
 	},
 
 	show_progress: function(frm) {
@@ -189,7 +293,8 @@
 						frm.set_value('sales_order', "");
 						frm.trigger('set_sales_order');
 						erpnext.in_production_item_onchange = true;
-						$.each(["description", "stock_uom", "project", "bom_no", "allow_alternative_item"], function(i, field) {
+						$.each(["description", "stock_uom", "project", "bom_no",
+							"allow_alternative_item", "transfer_material_against_job_card"], function(i, field) {
 							frm.set_value(field, r.message[field]);
 						});
 
@@ -235,6 +340,9 @@
 	before_submit: function(frm) {
 		frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true);
 		frm.fields_dict.required_items.grid.toggle_reqd("source_warehouse", true);
+		if (frm.doc.operations) {
+			frm.fields_dict.operations.grid.toggle_reqd("workstation", true);
+		}
 	},
 
 	set_sales_order: function(frm) {
@@ -316,7 +424,10 @@
 				}, __("Status"));
 			}
 
-			if(!frm.doc.skip_transfer){
+			const show_start_btn = (frm.doc.skip_transfer
+				|| frm.doc.transfer_material_against_job_card) ? 0 : 1;
+
+			if (show_start_btn){
 				if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty))
 					&& frm.doc.status != 'Stopped') {
 					frm.has_start_btn = true;
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index aef2ac4..df9dd83 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -559,6 +559,39 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "depends_on": "operations",
+   "fieldname": "transfer_material_against_job_card",
+   "fieldtype": "Check",
+   "hidden": 0,
+   "ignore_user_permissions": 0,
+   "ignore_xss_filter": 0,
+   "in_filter": 0,
+   "in_global_search": 0,
+   "in_list_view": 0,
+   "in_standard_filter": 0,
+   "label": "Transfer Material Against Job Card",
+   "length": 0,
+   "no_copy": 0,
+   "permlevel": 0,
+   "precision": "",
+   "print_hide": 0,
+   "print_hide_if_no_value": 0,
+   "read_only": 0,
+   "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,
    "fieldname": "warehouses",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1639,7 +1672,7 @@
  "issingle": 0,
  "istable": 0,
  "max_attachments": 0,
- "modified": "2018-08-29 06:28:22.983369",
+ "modified": "2018-09-05 06:28:22.983369",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Work Order",
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 6995829..1d465d5 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -190,6 +190,9 @@
 
 		for purpose, fieldname in (("Manufacture", "produced_qty"),
 			("Material Transfer for Manufacture", "material_transferred_for_manufacturing")):
+			if (purpose == 'Material Transfer for Manufacture' and
+				self.operations and self.transfer_material_against_job_card):
+				continue
 
 			qty = flt(frappe.db.sql("""select sum(fg_completed_qty)
 				from `tabStock Entry` where work_order=%s and docstatus=1
@@ -209,9 +212,6 @@
 		production_plan = frappe.get_doc('Production Plan', self.production_plan)
 		production_plan.run_method("update_produced_qty", self.produced_qty, self.production_plan_item)
 
-	def before_submit(self):
-		self.make_time_logs()
-
 	def on_submit(self):
 		if not self.wip_warehouse:
 			frappe.throw(_("Work-in-Progress Warehouse is required before Submit"))
@@ -223,18 +223,27 @@
 		self.update_completed_qty_in_material_request()
 		self.update_planned_qty()
 		self.update_ordered_qty()
+		self.create_job_card()
 
 	def on_cancel(self):
 		self.validate_cancel()
 
 		frappe.db.set(self,'status', 'Cancelled')
 		self.update_work_order_qty_in_so()
-		self.delete_timesheet()
+		self.delete_job_card()
 		self.update_completed_qty_in_material_request()
 		self.update_planned_qty()
 		self.update_ordered_qty()
 		self.update_reserved_qty_for_production()
 
+	def create_job_card(self):
+		for row in self.operations:
+			if not row.workstation:
+				frappe.throw(_("Row {0}: select the workstation against the operation {1}")
+					.format(row.idx, row.operation))
+
+			create_job_card(self, row, auto_create=True)
+
 	def validate_cancel(self):
 		if self.status == "Stopped":
 			frappe.throw(_("Stopped Work Order cannot be cancelled, Unstop it first to cancel"))
@@ -312,6 +321,17 @@
 		"""	% ", ".join(["%s"]*len(bom_list)), tuple(bom_list), as_dict=1)
 
 		self.set('operations', operations)
+
+		if self.use_multi_level_bom and self.get('operations') and self.get('items'):
+			raw_material_operations = [d.operation for d in self.get('items')]
+			operations = [d.operation for d in self.get('operations')]
+
+			for operation in raw_material_operations:
+				if operation not in operations:
+					self.append('operations', {
+						'operation': operation
+					})
+
 		self.calculate_time()
 
 	def calculate_time(self):
@@ -335,99 +355,6 @@
 
 		return holidays[holiday_list]
 
-	def make_time_logs(self, open_new=False):
-		"""Capacity Planning. Plan time logs based on earliest availablity of workstation after
-			Planned Start Date. Time logs will be created and remain in Draft mode and must be submitted
-			before manufacturing entry can be made."""
-
-		if not self.operations:
-			return
-
-		timesheets = []
-		plan_days = frappe.db.get_single_value("Manufacturing Settings", "capacity_planning_for_days") or 30
-
-		timesheet = make_timesheet(self.name, self.company)
-		timesheet.set('time_logs', [])
-
-		for i, d in enumerate(self.operations):
-
-			if d.status != 'Completed':
-				self.set_start_end_time_for_workstation(d, i)
-
-				args = self.get_operations_data(d)
-
-				add_timesheet_detail(timesheet, args)
-				original_start_time = d.planned_start_time
-
-				# validate operating hours if workstation [not mandatory] is specified
-				try:
-					timesheet.validate_time_logs()
-				except OverlapError:
-					if frappe.message_log: frappe.message_log.pop()
-					timesheet.schedule_for_work_order(d.idx)
-				except WorkstationHolidayError:
-					if frappe.message_log: frappe.message_log.pop()
-					timesheet.schedule_for_work_order(d.idx)
-
-				from_time, to_time = self.get_start_end_time(timesheet, d.name)
-
-				if date_diff(from_time, original_start_time) > plan_days:
-					frappe.throw(_("Unable to find Time Slot in the next {0} days for Operation {1}").format(plan_days, d.operation))
-					break
-
-				d.planned_start_time = from_time
-				d.planned_end_time = to_time
-				d.db_update()
-
-		if timesheet and open_new:
-			return timesheet
-
-		if timesheet and timesheet.get("time_logs"):
-			timesheet.save()
-			timesheets.append(getlink("Timesheet", timesheet.name))
-
-		self.planned_end_date = self.operations[-1].planned_end_time
-		if timesheets:
-			frappe.local.message_log = []
-			frappe.msgprint(_("Timesheet created:") + "\n" + "\n".join(timesheets))
-
-	def get_operations_data(self, data):
-		return {
-			'from_time': get_datetime(data.planned_start_time),
-			'hours': data.time_in_mins / 60.0,
-			'to_time': get_datetime(data.planned_end_time),
-			'project': self.project,
-			'operation': data.operation,
-			'operation_id': data.name,
-			'workstation': data.workstation,
-			'completed_qty': flt(self.qty) - flt(data.completed_qty)
-		}
-
-	def set_start_end_time_for_workstation(self, data, index):
-		"""Set start and end time for given operation. If first operation, set start as
-		`planned_start_date`, else add time diff to end time of earlier operation."""
-
-		if index == 0:
-			data.planned_start_time = self.planned_start_date
-		else:
-			data.planned_start_time = get_datetime(self.operations[index-1].planned_end_time)\
-								+ get_mins_between_operations()
-
-		data.planned_end_time = get_datetime(data.planned_start_time) + relativedelta(minutes = data.time_in_mins)
-
-		if data.planned_start_time == data.planned_end_time:
-			frappe.throw(_("Capacity Planning Error"))
-
-	def get_start_end_time(self, timesheet, operation_id):
-		for data in timesheet.time_logs:
-			if data.operation_id == operation_id:
-				return data.from_time, data.to_time
-
-	def check_operation_fits_in_working_hours(self, d):
-		"""Raises expection if operation is longer than working hours in the given workstation."""
-		from erpnext.manufacturing.doctype.workstation.workstation import check_if_within_operating_hours
-		check_if_within_operating_hours(d.workstation, d.operation, d.planned_start_time, d.planned_end_time)
-
 	def update_operation_status(self):
 		for d in self.get("operations"):
 			if not d.completed_qty:
@@ -451,9 +378,9 @@
 			if actual_end_dates:
 				self.actual_end_date = max(actual_end_dates)
 
-	def delete_timesheet(self):
-		for timesheet in frappe.get_all("Timesheet", ["name"], {"work_order": self.name}):
-			frappe.delete_doc("Timesheet", timesheet.name)
+	def delete_job_card(self):
+		for d in frappe.get_all("Job Card", ["name"], {"work_order": self.name}):
+			frappe.delete_doc("Job Card", d.name)
 
 	def validate_production_item(self):
 		if frappe.db.get_value("Item", self.production_item, "has_variants"):
@@ -523,6 +450,7 @@
 			else:
 				for item in sorted(item_dict.values(), key=lambda d: d['idx']):
 					self.append('required_items', {
+						'operation': item.operation,
 						'item_code': item.item_code,
 						'item_name': item.item_name,
 						'description': item.description,
@@ -573,6 +501,30 @@
 
 			d.db_set('consumed_qty', flt(consumed_qty), update_modified = False)
 
+	def make_bom(self):
+		data = frappe.db.sql(""" select sed.item_code, sed.qty, sed.s_warehouse
+			from `tabStock Entry Detail` sed, `tabStock Entry` se
+			where se.name = sed.parent and se.purpose = 'Manufacture'
+			and (sed.t_warehouse is null or sed.t_warehouse = '') and se.docstatus = 1
+			and se.work_order = %s""", (self.name), as_dict=1)
+
+		bom = frappe.new_doc("BOM")
+		bom.item = self.production_item
+		bom.conversion_rate = 1
+
+		for d in data:
+			bom.append('items', {
+				'item_code': d.item_code,
+				'qty': d.qty,
+				'source_warehouse': d.s_warehouse
+			})
+
+		if self.operations:
+			bom.set('operations', self.operations)
+			bom.with_operations = 1
+
+		bom.set_bom_material_details()
+		return bom
 
 @frappe.whitelist()
 def get_item_details(item, project = None):
@@ -609,8 +561,12 @@
 		else:
 			frappe.throw(_("Default BOM for {0} not found").format(item))
 
-	res['project'] = project or frappe.db.get_value('BOM', res['bom_no'], 'project')
-	res['allow_alternative_item'] = frappe.db.get_value('BOM', res['bom_no'], 'allow_alternative_item')
+	bom_data = frappe.db.get_value('BOM', res['bom_no'],
+		['project', 'allow_alternative_item', 'transfer_material_against_job_card'], as_dict=1)
+
+	res['project'] = project or bom_data.project
+	res['allow_alternative_item'] = bom_data.allow_alternative_item
+	res['transfer_material_against_job_card'] = bom_data.transfer_material_against_job_card
 	res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
 
 	return res
@@ -668,25 +624,6 @@
 	return stock_entry.as_dict()
 
 @frappe.whitelist()
-def make_timesheet(work_order, company):
-	timesheet = frappe.new_doc("Timesheet")
-	timesheet.employee = ""
-	timesheet.work_order = work_order
-	timesheet.company = company
-	return timesheet
-
-@frappe.whitelist()
-def add_timesheet_detail(timesheet, args):
-	if isinstance(timesheet, string_types):
-		timesheet = frappe.get_doc('Timesheet', timesheet)
-
-	if isinstance(args, string_types):
-		args = json.loads(args)
-
-	timesheet.append('time_logs', args)
-	return timesheet
-
-@frappe.whitelist()
 def get_default_warehouse():
 	wip_warehouse = frappe.db.get_single_value("Manufacturing Settings",
 		"default_wip_warehouse")
@@ -695,16 +632,6 @@
 	return {"wip_warehouse": wip_warehouse, "fg_warehouse": fg_warehouse}
 
 @frappe.whitelist()
-def make_new_timesheet(source_name, target_doc=None):
-	po = frappe.get_doc('Work Order', source_name)
-	ts = po.make_time_logs(open_new=True)
-
-	if not ts or not ts.get('time_logs'):
-		frappe.throw(_("Already completed"))
-
-	return ts
-
-@frappe.whitelist()
 def stop_unstop(work_order, status):
 	""" Called from client side on Stop/Unstop event"""
 
@@ -730,3 +657,40 @@
 	""", (production_item, production_item))
 
 	return out
+
+@frappe.whitelist()
+def make_job_card(work_order, operation, workstation, qty=0):
+	work_order = frappe.get_doc('Work Order', work_order)
+	row = get_work_order_operation_data(work_order, operation, workstation)
+	if row:
+		return create_job_card(work_order, row, qty)
+
+def create_job_card(work_order, row, qty=0, auto_create=False):
+	doc = frappe.new_doc("Job Card")
+	doc.update({
+		'work_order': work_order.name,
+		'operation': row.operation,
+		'workstation': row.workstation,
+		'posting_date': nowdate(),
+		'for_quantity': qty or work_order.get('qty', 0),
+		'operation_id': row.name,
+		'bom_no': work_order.bom_no,
+		'project': work_order.project,
+		'company': work_order.company,
+		'wip_warehouse': work_order.wip_warehouse
+	})
+
+	if work_order.transfer_material_against_job_card and not work_order.skip_transfer:
+		doc.get_required_items()
+
+	if auto_create:
+		doc.flags.ignore_mandatory = True
+		doc.insert()
+		frappe.msgprint(_("Job card {0} created").format(doc.name))
+
+	return doc
+
+def get_work_order_operation_data(work_order, operation, workstation):
+	for d in work_order.operations:
+		if d.operation == operation and d.workstation == workstation:
+			return d
diff --git a/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py b/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py
index 9b7c9a3..02fbfcd 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py
@@ -5,7 +5,7 @@
 		'fieldname': 'work_order',
 		'transactions': [
 			{
-				'items': ['Stock Entry', 'Timesheet']
+				'items': ['Stock Entry', 'Job Card']
 			}
 		]
 	}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
index badeb91..6dbb494 100644
--- a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
+++ b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
@@ -19,6 +19,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "operation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Operation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
    "fieldname": "item_code", 
    "fieldtype": "Link", 
    "hidden": 0, 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 512e33b..3b3c25b 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -434,7 +434,7 @@
 erpnext.patches.v8_6.update_timesheet_company_from_PO
 erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
 erpnext.patches.v8_5.remove_project_type_property_setter
-erpnext.patches.v8_7.add_more_gst_fields #21-09-2017
+erpnext.patches.v8_7.sync_india_custom_fields
 erpnext.patches.v8_7.fix_purchase_receipt_status
 erpnext.patches.v8_6.rename_bom_update_tool
 erpnext.patches.v8_7.set_offline_in_pos_settings #11-09-17
@@ -486,10 +486,8 @@
 erpnext.patches.v10_0.fichier_des_ecritures_comptables_for_france
 erpnext.patches.v10_0.update_assessment_plan
 erpnext.patches.v10_0.update_assessment_result
-erpnext.patches.v10_0.added_extra_gst_custom_field
 erpnext.patches.v10_0.set_default_payment_terms_based_on_company
 erpnext.patches.v10_0.update_sales_order_link_to_purchase_order
-erpnext.patches.v10_0.added_extra_gst_custom_field_in_gstr2 #2018-02-13
 erpnext.patches.v10_0.item_barcode_childtable_migrate
 erpnext.patches.v10_0.rename_price_to_rate_in_pricing_rule
 erpnext.patches.v10_0.set_currency_in_pricing_rule
@@ -563,3 +561,5 @@
 erpnext.patches.v11_0.update_hub_url # 2018-08-31  # 2018-09-03
 erpnext.patches.v10_0.set_discount_amount
 erpnext.patches.v10_0.recalculate_gross_margin_for_project
+erpnext.patches.v11_0.make_job_card
+erpnext.patches.v11_0.redesign_healthcare_billing_work_flow
diff --git a/erpnext/patches/v10_0/added_extra_gst_custom_field.py b/erpnext/patches/v10_0/added_extra_gst_custom_field.py
deleted file mode 100644
index 000e8fd..0000000
--- a/erpnext/patches/v10_0/added_extra_gst_custom_field.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import frappe
-from erpnext.regional.india.setup  import make_custom_fields
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company:
-		return
-
-	frappe.reload_doc("hr", "doctype", "Employee Tax Exemption Declaration")
-	frappe.reload_doc("hr", "doctype", "Employee Tax Exemption Proof Submission")
-
-	make_custom_fields(update=False)
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py b/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
index f632c94..0739671 100644
--- a/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
+++ b/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
@@ -5,7 +5,7 @@
 		frappe.reload_doc("healthcare", "doctype", "physician")
 		frappe.reload_doc("healthcare", "doctype", "physician_service_unit_schedule")
 
-		if frappe.db.has_column('Physician', 'physician_schedule'):
+		if frappe.db.has_column('Physician', 'physician_schedules'):
 			for doc in frappe.get_all('Physician'):
 				_doc = frappe.get_doc('Physician', doc.name)
 				if _doc.physician_schedule:
diff --git a/erpnext/patches/v11_0/make_job_card.py b/erpnext/patches/v11_0/make_job_card.py
new file mode 100644
index 0000000..ad9a9af
--- /dev/null
+++ b/erpnext/patches/v11_0/make_job_card.py
@@ -0,0 +1,26 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from erpnext.manufacturing.doctype.work_order.work_order import create_job_card
+
+def execute():
+	frappe.reload_doc('manufacturing', 'doctype', 'work_order')
+	frappe.reload_doc('manufacturing', 'doctype', 'work_order_item')
+	frappe.reload_doc('manufacturing', 'doctype', 'job_card')
+	frappe.reload_doc('manufacturing', 'doctype', 'job_card_item')
+
+	fieldname = frappe.db.get_value('DocField', {'fieldname': 'work_order', 'parent': 'Timesheet'}, 'fieldname')
+	if not fieldname:
+		fieldname = frappe.db.get_value('DocField', {'fieldname': 'production_order', 'parent': 'Timesheet'}, 'fieldname')
+		if not fieldname: return
+
+	for d in frappe.db.sql("""select %(fieldname)s, name from tabTimesheet
+		where (%(fieldname)s is not null and %(fieldname)s != '') and docstatus = 0""",
+		{'fieldname': fieldname}, as_dict=1):
+		if d[fieldname]:
+			doc = frappe.get_doc('Work Order', d[fieldname])
+			for row in doc.operations:
+				create_job_card(doc, row, auto_create=True)
+			frappe.delete_doc('Timesheet', d.name)
diff --git a/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py b/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py
new file mode 100644
index 0000000..dc7ff13
--- /dev/null
+++ b/erpnext/patches/v11_0/redesign_healthcare_billing_work_flow.py
@@ -0,0 +1,65 @@
+import frappe
+from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
+from erpnext.domains.healthcare import data
+from frappe.modules import scrub, get_doctype_module
+
+sales_invoice_referenced_doc = {
+	"Patient Appointment": "sales_invoice",
+	"Patient Encounter": "invoice",
+	"Lab Test": "invoice",
+	"Lab Prescription": "invoice",
+	"Sample Collection": "invoice"
+}
+
+def execute():
+	frappe.reload_doc('accounts', 'doctype', 'loyalty_program')
+	frappe.reload_doc('accounts', 'doctype', 'sales_invoice_item')
+
+	if "healthcare" not in frappe.get_active_domains():
+		return
+
+	healthcare_custom_field_in_sales_invoice()
+	for si_ref_doc in sales_invoice_referenced_doc:
+		if frappe.db.exists('DocType', si_ref_doc):
+			frappe.reload_doc(get_doctype_module(si_ref_doc), 'doctype', scrub(si_ref_doc))
+
+			if frappe.db.has_column(si_ref_doc, sales_invoice_referenced_doc[si_ref_doc]) \
+			and frappe.db.has_column(si_ref_doc, 'invoiced'):
+				# Set Reference DocType and Reference Docname
+				doc_list = frappe.db.sql("""
+							select name from `tab{0}`
+							where {1} is not null
+						""".format(si_ref_doc, sales_invoice_referenced_doc[si_ref_doc]))
+				if doc_list:
+					frappe.reload_doc(get_doctype_module("Sales Invoice"), 'doctype', 'sales_invoice')
+					for doc_id in doc_list:
+						invoice_id = frappe.db.get_value(si_ref_doc, doc_id[0], sales_invoice_referenced_doc[si_ref_doc])
+						invoice = frappe.get_doc("Sales Invoice", invoice_id)
+						if invoice.items:
+							marked = False
+							if not marked:
+								for item_line in invoice.items:
+									marked = True
+									frappe.db.sql("""
+												update `tabSales Invoice Item`
+												set reference_dt = '{0}', reference_dn = '{1}'
+												where name = '{2}'
+											""".format(si_ref_doc, doc_id[0], item_line.name))
+
+				# Documents mark invoiced for submitted sales invoice
+				frappe.db.sql("""
+							update `tab{0}` doc, `tabSales Invoice` si
+							set doc.invoiced = 1
+							where si.docstatus = 1 and doc.{1} = si.name
+						""".format(si_ref_doc, sales_invoice_referenced_doc[si_ref_doc]))
+
+def healthcare_custom_field_in_sales_invoice():
+	frappe.reload_doc('healthcare', 'doctype', 'patient')
+	frappe.reload_doc('healthcare', 'doctype', 'healthcare_practitioner')
+	if data['custom_fields']:
+		create_custom_fields(data['custom_fields'])
+
+	frappe.db.sql("""
+				delete from `tabCustom Field`
+				where fieldname = 'appointment' and options = 'Patient Appointment'
+			""")
diff --git a/erpnext/patches/v8_7/add_more_gst_fields.py b/erpnext/patches/v8_7/add_more_gst_fields.py
deleted file mode 100644
index d2085e0..0000000
--- a/erpnext/patches/v8_7/add_more_gst_fields.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import frappe
-from erpnext.regional.india.setup  import make_custom_fields
-
-def execute():
-	company = frappe.get_all('Company', filters = {'country': 'India'})
-	if not company:
-		return
-
-	frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_declaration')
-	frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_proof_submission')
-	make_custom_fields()
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py b/erpnext/patches/v8_7/sync_india_custom_fields.py
similarity index 61%
rename from erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py
rename to erpnext/patches/v8_7/sync_india_custom_fields.py
index 12aa5fd..323b5bc 100644
--- a/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py
+++ b/erpnext/patches/v8_7/sync_india_custom_fields.py
@@ -6,11 +6,14 @@
 	if not company:
 		return
 
+	frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_declaration')
+	frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_proof_submission')
+
 	for doctype in ["Sales Invoice", "Delivery Note", "Purchase Invoice"]:
 		frappe.db.sql("""delete from `tabCustom Field` where dt = %s
 			and fieldname in ('port_code', 'shipping_bill_number', 'shipping_bill_date')""", doctype)
 
-	make_custom_fields(update=False)
+	make_custom_fields()
 
 	frappe.db.sql("""
 		update `tabCustom Field`
@@ -18,4 +21,8 @@
 		where fieldname = 'reason_for_issuing_document'
 	""")
 
-
+	frappe.db.sql("""
+		update tabAddress
+		set gst_state_number=concat("0", gst_state_number)
+		where ifnull(gst_state_number, '') != '' and gst_state_number<10
+	""")
\ No newline at end of file
diff --git a/erpnext/projects/doctype/timesheet/timesheet.json b/erpnext/projects/doctype/timesheet/timesheet.json
index d1ec38c..e5198de 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.json
+++ b/erpnext/projects/doctype/timesheet/timesheet.json
@@ -457,6 +457,39 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 1, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "User", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "User", 
+   "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, 
+   "fieldname": "start_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
    "in_global_search": 0, 
    "in_list_view": 1, 
    "in_standard_filter": 0, 
@@ -514,73 +547,6 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "collapsible_depends_on": "", 
-   "columns": 0, 
-   "depends_on": "work_order", 
-   "fieldname": "work_detail", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Work Detail", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "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, 
-   "fieldname": "work_order", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Work Order", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Work Order", 
-   "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, 
    "fieldname": "section_break_5", 
    "fieldtype": "Section Break", 
@@ -1066,7 +1032,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 14:44:32.912004", 
+ "modified": "2018-08-28 14:44:32.912004", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Timesheet", 
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 7dc121c..f48c0c6 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -97,19 +97,13 @@
 		self.set_status()
 
 	def on_cancel(self):
-		self.update_work_order(None)
 		self.update_task_and_project()
 
 	def on_submit(self):
 		self.validate_mandatory_fields()
-		self.update_work_order(self.name)
 		self.update_task_and_project()
 
 	def validate_mandatory_fields(self):
-		if self.work_order:
-			work_order = frappe.get_doc("Work Order", self.work_order)
-			pending_qty = flt(work_order.qty) - flt(work_order.produced_qty)
-
 		for data in self.time_logs:
 			if not data.from_time and not data.to_time:
 				frappe.throw(_("Row {0}: From Time and To Time is mandatory.").format(data.idx))
@@ -120,41 +114,6 @@
 			if flt(data.hours) == 0.0:
 				frappe.throw(_("Row {0}: Hours value must be greater than zero.").format(data.idx))
 
-			if self.work_order and flt(data.completed_qty) == 0:
-				frappe.throw(_("Row {0}: Completed Qty must be greater than zero.").format(data.idx))
-
-			if self.work_order and flt(pending_qty) < flt(data.completed_qty) and flt(pending_qty) > 0:
-				frappe.throw(_("Row {0}: Completed Qty cannot be more than {1} for operation {2}").format(data.idx, pending_qty, data.operation),
-					OverWorkLoggedError)
-
-	def update_work_order(self, time_sheet):
-		if self.work_order:
-			pro = frappe.get_doc('Work Order', self.work_order)
-
-			for timesheet in self.time_logs:
-				for data in pro.operations:
-					if data.name == timesheet.operation_id:
-						summary = self.get_actual_timesheet_summary(timesheet.operation_id)
-						data.time_sheet = time_sheet
-						data.completed_qty = summary.completed_qty
-						data.actual_operation_time = summary.mins
-						data.actual_start_time = summary.from_time
-						data.actual_end_time = summary.to_time
-
-			pro.flags.ignore_validate_update_after_submit = True
-			pro.update_operation_status()
-			pro.calculate_operating_cost()
-			pro.set_actual_dates()
-			pro.save()
-
-	def get_actual_timesheet_summary(self, operation_id):
-		"""Returns 'Actual Operating Time'. """
-		return frappe.db.sql("""select
-			sum(tsd.hours*60) as mins, sum(tsd.completed_qty) as completed_qty, min(tsd.from_time) as from_time,
-			max(tsd.to_time) as to_time from `tabTimesheet Detail` as tsd, `tabTimesheet` as ts where
-			ts.work_order = %s and tsd.operation_id = %s and ts.docstatus=1 and ts.name = tsd.parent""",
-			(self.work_order, operation_id), as_dict=1)[0]
-
 	def update_task_and_project(self):
 		tasks, projects = [], []
 
@@ -176,16 +135,12 @@
 
 	def validate_time_logs(self):
 		for data in self.get('time_logs'):
-			self.check_workstation_timings(data)
 			self.validate_overlap(data)
 
 	def validate_overlap(self, data):
 		settings = frappe.get_single('Projects Settings')
-		if self.work_order:
-			self.validate_overlap_for("workstation", data, data.workstation, settings.ignore_workstation_time_overlap)
-		else:
-			self.validate_overlap_for("user", data, self.user, settings.ignore_user_time_overlap)
-			self.validate_overlap_for("employee", data, self.employee, settings.ignore_employee_time_overlap)
+		self.validate_overlap_for("user", data, self.user, settings.ignore_user_time_overlap)
+		self.validate_overlap_for("employee", data, self.employee, settings.ignore_employee_time_overlap)
 
 	def validate_overlap_for(self, fieldname, args, value, ignore_validation=False):
 		if not value or ignore_validation:
@@ -227,48 +182,6 @@
 
 		return existing[0] if existing else None
 
-	def check_workstation_timings(self, args):
-		"""Checks if **Time Log** is between operating hours of the **Workstation**."""
-		if args.workstation and args.from_time and args.to_time:
-			check_if_within_operating_hours(args.workstation, args.operation, args.from_time, args.to_time)
-
-	def schedule_for_work_order(self, index):
-		for data in self.time_logs:
-			if data.idx == index:
-				self.move_to_next_day(data) #check for workstation holiday
-				self.move_to_next_non_overlapping_slot(data) #check for overlap
-				break
-
-	def move_to_next_non_overlapping_slot(self, data):
-		overlapping = self.get_overlap_for("workstation", data, data.workstation)
-		if overlapping:
-			time_sheet = self.get_last_working_slot(overlapping.name, data.workstation)
-			data.from_time = get_datetime(time_sheet.to_time) + get_mins_between_operations()
-			data.to_time = self.get_to_time(data)
-			self.check_workstation_working_day(data)
-
-	def get_last_working_slot(self, time_sheet, workstation):
-		return frappe.db.sql(""" select max(from_time) as from_time, max(to_time) as to_time
-			from `tabTimesheet Detail` where workstation = %(workstation)s""",
-			{'workstation': workstation}, as_dict=True)[0]
-
-	def move_to_next_day(self, data):
-		"""Move start and end time one day forward"""
-		self.check_workstation_working_day(data)
-
-	def check_workstation_working_day(self, data):
-		while True:
-			try:
-				self.check_workstation_timings(data)
-				break
-			except WorkstationHolidayError:
-				if frappe.message_log: frappe.message_log.pop()
-				data.from_time = get_datetime(data.from_time) + timedelta(hours=24)
-				data.to_time = self.get_to_time(data)
-
-	def get_to_time(self, data):
-		return get_datetime(data.from_time) + timedelta(hours=data.hours)
-
 	def update_cost(self):
 		for data in self.time_logs:
 			if data.activity_type or data.billable:
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 07ddcb4..b3ba053 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -343,7 +343,8 @@
 							weight_per_unit: item.weight_per_unit,
 							weight_uom: item.weight_uom,
 							uom : item.uom,
-							pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : ''
+							pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '',
+							cost_center: item.cost_center
 						}
 					},
 
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index 8648687..36746cd 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -79,6 +79,37 @@
 			"options": "Finance Book"
 		},
 		{
+			"fieldname":"cost_center",
+			"label": __("Cost Center"),
+			"fieldtype": "MultiSelect",
+			get_data: function() {
+				var cost_centers = frappe.query_report.get_filter_value("cost_center") || "";
+
+				const values = cost_centers.split(/\s*,\s*/).filter(d => d);
+				const txt = cost_centers.match(/[^,\s*]*$/)[0] || '';
+				let data = [];
+
+				frappe.call({
+					type: "GET",
+					method:'frappe.desk.search.search_link',
+					async: false,
+					no_spinner: true,
+					args: {
+						doctype: "Cost Center",
+						txt: txt,
+						filters: {
+							"company": frappe.query_report.get_filter_value("company"),
+							"name": ["not in", values]
+						}
+					},
+					callback: function(r) {
+						data = r.results;
+					}
+				});
+				return data;
+			}
+		},
+		{
 			"fieldname":"from_fiscal_year",
 			"label": __("Start Year"),
 			"fieldtype": "Link",
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 682577b..434b58c 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -201,7 +201,18 @@
 		} else {
 			return options[0];
 		}
-	}
+	},
+	copy_parent_value_in_all_row: function(doc, dt, dn, table_fieldname, fieldname, parent_fieldname) {
+		var d = locals[dt][dn];
+		if(d[fieldname]){
+			var cl = doc[table_fieldname] || [];
+			for(var i = 0; i < cl.length; i++) {
+				cl[i][fieldname] = doc[parent_fieldname];
+			}
+		}
+		refresh_field(table_fieldname);
+	},
+
 });
 
 erpnext.utils.select_alternate_items = function(opts) {
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index da9e469..07a42ff 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -171,7 +171,7 @@
 			dict(fieldname='gst_state', label='GST State', fieldtype='Select',
 				options='\n'.join(states), insert_after='gstin'),
 			dict(fieldname='gst_state_number', label='GST State Number',
-				fieldtype='Int', insert_after='gst_state', read_only=1),
+				fieldtype='Data', insert_after='gst_state', read_only=1),
 		],
 		'Purchase Invoice': invoice_gst_fields + purchase_invoice_gst_fields,
 		'Sales Invoice': invoice_gst_fields + sales_invoice_gst_fields,
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index edd5519..fa2d2af 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -4,8 +4,9 @@
 from __future__ import unicode_literals
 import frappe, json
 from frappe import _
-from frappe.utils import flt
+from frappe.utils import flt, formatdate
 from datetime import date
+from six import iteritems
 
 def execute(filters=None):
 	return Gstr1Report(filters).run()
@@ -73,12 +74,17 @@
 				row.append(abs(invoice_details.base_rounded_total) or abs(invoice_details.base_grand_total))
 			elif fieldname == "invoice_value":
 				row.append(invoice_details.base_rounded_total or invoice_details.base_grand_total)
+			elif fieldname in ('posting_date', 'shipping_bill_date'):
+				row.append(formatdate(invoice_details.get(fieldname), 'dd-MMM-YY'))
+			elif fieldname == "export_type":
+				export_type = "WPAY" if invoice_details.get(fieldname)=="With Payment of Tax" else "WOPAY"
+				row.append(export_type)
 			else:
 				row.append(invoice_details.get(fieldname))
 
 		taxable_value = sum([abs(net_amount)
 			for item_code, net_amount in self.invoice_items.get(invoice).items() if item_code in items])
-		row += [tax_rate, taxable_value]
+		row += [tax_rate or 0, taxable_value]
 
 		return row, taxable_value
 
@@ -195,6 +201,12 @@
 		if unidentified_gst_accounts:
 			frappe.msgprint(_("Following accounts might be selected in GST Settings:")
 				+ "<br>" + "<br>".join(unidentified_gst_accounts), alert=True)
+		
+		# Build itemised tax for export invoices where tax table is blank
+		for invoice, items in iteritems(self.invoice_items):
+			if invoice not in self.items_based_on_tax_rate \
+				and frappe.db.get_value(self.doctype, invoice, "export_type") == "Without Payment of Tax":
+					self.items_based_on_tax_rate.setdefault(invoice, {}).setdefault(0, items.keys())
 
 	def get_gst_accounts(self):
 		self.gst_accounts = frappe._dict()
@@ -250,7 +262,7 @@
 				{
 					"fieldname": "posting_date",
 					"label": "Invoice date",
-					"fieldtype": "Date",
+					"fieldtype": "Data",
 					"width":80
 				},
 				{
@@ -261,7 +273,7 @@
 				},
 				{
 					"fieldname": "place_of_supply",
-					"label": "Place of Supply",
+					"label": "Place Of Supply",
 					"fieldtype": "Data",
 					"width":100
 				},
@@ -303,7 +315,7 @@
 				{
 					"fieldname": "posting_date",
 					"label": "Invoice date",
-					"fieldtype": "Date",
+					"fieldtype": "Data",
 					"width": 100
 				},
 				{
@@ -314,7 +326,7 @@
 				},
 				{
 					"fieldname": "place_of_supply",
-					"label": "Place of Supply",
+					"label": "Place Of Supply",
 					"fieldtype": "Data",
 					"width": 120
 				},
@@ -357,7 +369,7 @@
 				{
 					"fieldname": "posting_date",
 					"label": "Invoice/Advance Receipt date",
-					"fieldtype": "Date",
+					"fieldtype": "Data",
 					"width": 120
 				},
 				{
@@ -368,12 +380,6 @@
 					"width":120
 				},
 				{
-					"fieldname": "posting_date",
-					"label": "Invoice/Advance Receipt date",
-					"fieldtype": "Date",
-					"width": 120
-				},
-				{
 					"fieldname": "reason_for_issuing_document",
 					"label": "Reason For Issuing document",
 					"fieldtype": "Data",
@@ -381,7 +387,7 @@
 				},
 				{
 					"fieldname": "place_of_supply",
-					"label": "Place of Supply",
+					"label": "Place Of Supply",
 					"fieldtype": "Data",
 					"width": 120
 				},
@@ -416,7 +422,7 @@
 			self.invoice_columns = [
 				{
 					"fieldname": "place_of_supply",
-					"label": "Place of Supply",
+					"label": "Place Of Supply",
 					"fieldtype": "Data",
 					"width": 120
 				},
@@ -459,7 +465,7 @@
 				{
 					"fieldname": "posting_date",
 					"label": "Invoice date",
-					"fieldtype": "Date",
+					"fieldtype": "Data",
 					"width": 120
 				},
 				{
@@ -483,7 +489,7 @@
 				{
 					"fieldname": "shipping_bill_date",
 					"label": "Shipping Bill Date",
-					"fieldtype": "Date",
+					"fieldtype": "Data",
 					"width": 120
 				}
 			]
diff --git a/erpnext/selling/doctype/sales_order/sales_order_list.js b/erpnext/selling/doctype/sales_order/sales_order_list.js
index 43c91b9..69c2100 100644
--- a/erpnext/selling/doctype/sales_order/sales_order_list.js
+++ b/erpnext/selling/doctype/sales_order/sales_order_list.js
@@ -1,20 +1,25 @@
 frappe.listview_settings['Sales Order'] = {
 	add_fields: ["base_grand_total", "customer_name", "currency", "delivery_date",
 		"per_delivered", "per_billed", "status", "order_type", "name"],
-	get_indicator: function(doc) {
-		if(doc.status==="Closed"){
+	get_indicator: function (doc) {
+		if (doc.status === "Closed") {
 			return [__("Closed"), "green", "status,=,Closed"];
 
 		} else if (doc.order_type !== "Maintenance"
 			&& flt(doc.per_delivered, 6) < 100 && frappe.datetime.get_diff(doc.delivery_date) < 0) {
-			// to bill & overdue
+			// not delivered & overdue
 			return [__("Overdue"), "red", "per_delivered,<,100|delivery_date,<,Today|status,!=,Closed"];
 
 		} else if (doc.order_type !== "Maintenance"
-			&& flt(doc.per_delivered, 6) < 100 && doc.status!=="Closed") {
+			&& flt(doc.per_delivered, 6) < 100 && doc.status !== "Closed") {
 			// not delivered
 
-			if(flt(doc.per_billed, 6) < 100) {
+			if (flt(doc.grand_total) === 0) {
+				// not delivered (zero-amount order)
+
+				return [__("To Deliver"), "orange",
+					"per_delivered,<,100|grand_total,=,0|status,!=,Closed"];
+			} else if (flt(doc.per_billed, 6) < 100) {
 				// not delivered & not billed
 
 				return [__("To Deliver and Bill"), "orange",
@@ -27,13 +32,13 @@
 			}
 
 		} else if ((doc.order_type === "Maintenance" || flt(doc.per_delivered, 6) == 100)
-			&& flt(doc.per_billed, 6) < 100 && doc.status!=="Closed") {
-
+			&& flt(doc.grand_total) !== 0 && flt(doc.per_billed, 6) < 100 && doc.status !== "Closed") {
 			// to bill
+
 			return [__("To Bill"), "orange", "per_delivered,=,100|per_billed,<,100|status,!=,Closed"];
 
-		} else if((doc.order_type === "Maintenance" || flt(doc.per_delivered, 6) == 100)
-			&& flt(doc.per_billed, 6) == 100 && doc.status!=="Closed") {
+		} else if ((doc.order_type === "Maintenance" || flt(doc.per_delivered, 6) == 100)
+			&& (flt(doc.grand_total) === 0 || flt(doc.per_billed, 6) == 100) && doc.status !== "Closed") {
 
 			return [__("Completed"), "green", "per_delivered,=,100|per_billed,=,100|status,!=,Closed"];
 		}
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index f8fd1b3..538ea55 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -15,7 +15,7 @@
 
 class TestSalesOrder(unittest.TestCase):
 	def tearDown(self):
-		pass
+		frappe.set_user("Administrator")
 
 	def test_make_material_request(self):
 		so = make_sales_order(do_not_submit=True)
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 96d1116..9a245e2 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -837,7 +837,7 @@
    "label": "Create Chart Of Accounts Based On", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "\nStandard Template\nExisting Company\n\n\n", 
+   "options": "\nStandard Template\nExisting Company", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -871,7 +871,7 @@
    "label": "Chart Of Accounts Template", 
    "length": 0, 
    "no_copy": 1, 
-   "options": "\n\n\n", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -2836,7 +2836,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-09-01 16:03:30.716918", 
+ "modified": "2018-09-07 16:03:30.716918", 
  "modified_by": "cave@aperture.com", 
  "module": "Setup", 
  "name": "Company", 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 0d9dbe6..a2f87c5 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -167,7 +167,7 @@
 		}
 		erpnext.stock.delivery_note.set_print_hide(doc, dt, dn);
 
-		if(doc.docstatus==1 && !doc.auto_repeat) {
+		if(doc.docstatus==1 && !doc.is_return && !doc.auto_repeat) {
 			cur_frm.add_custom_button(__('Subscription'), function() {
 				erpnext.utils.make_subscription(doc.doctype, doc.name)
 			}, __("Make"))
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index e39c8ab..0ce6232 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -464,6 +464,39 @@
    "collapsible": 0, 
    "columns": 0, 
    "depends_on": "is_return", 
+   "fieldname": "issue_credit_note", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Issue Credit Note", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "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, 
+   "depends_on": "is_return", 
    "fieldname": "return_against", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -2790,12 +2823,12 @@
   {
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
    "fieldname": "transporter", 
-   "fieldtype": "Data", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -2806,11 +2839,12 @@
    "label": "Transporter ID", 
    "length": 0, 
    "no_copy": 0, 
+   "options": "Driver", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -2822,7 +2856,7 @@
   {
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
@@ -2844,7 +2878,7 @@
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "print_width": "150px", 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -2857,7 +2891,7 @@
   {
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
@@ -2878,7 +2912,7 @@
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -2890,7 +2924,7 @@
   {
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
@@ -2910,7 +2944,7 @@
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -2954,12 +2988,12 @@
   {
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
    "fieldname": "vehicle_no", 
-   "fieldtype": "Data", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -2970,11 +3004,12 @@
    "label": "Vehicle No", 
    "length": 0, 
    "no_copy": 0, 
+   "options": "Vehicle", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -2986,7 +3021,7 @@
   {
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
@@ -3007,7 +3042,7 @@
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -3019,13 +3054,13 @@
   {
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
    "description": "", 
    "fieldname": "lr_no", 
-   "fieldtype": "Data", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -3038,11 +3073,12 @@
    "no_copy": 0, 
    "oldfieldname": "lr_no", 
    "oldfieldtype": "Data", 
+   "options": "Delivery Trip", 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "print_width": "100px", 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -3055,7 +3091,7 @@
   {
    "allow_bulk_edit": 0, 
    "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
@@ -3079,7 +3115,7 @@
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "print_width": "100px", 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -4165,7 +4201,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-08-21 14:44:46.764951", 
+ "modified": "2018-08-30 03:50:25.791869", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Delivery Note", 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 1df07a2..6e45273 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -2,19 +2,18 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
+
 import frappe
-
-from frappe.utils import flt, cint
-
-from frappe import msgprint, _
 import frappe.defaults
-from frappe.model.utils import get_fetch_values
-from frappe.model.mapper import get_mapped_doc
 from erpnext.controllers.selling_controller import SellingController
-from frappe.desk.notifications import clear_doctype_notifications
 from erpnext.stock.doctype.batch.batch import set_batch_nos
-from frappe.contacts.doctype.address.address import get_company_address
 from erpnext.stock.doctype.serial_no.serial_no import get_delivery_note_serial_no
+from frappe import _
+from frappe.contacts.doctype.address.address import get_company_address
+from frappe.desk.notifications import clear_doctype_notifications
+from frappe.model.mapper import get_mapped_doc
+from frappe.model.utils import get_fetch_values
+from frappe.utils import cint, flt
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -170,12 +169,12 @@
 
 			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
 				if e in check_list:
-					msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
+					frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
 				else:
 					check_list.append(e)
 			else:
 				if f in chk_dupl_itm:
-					msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
+					frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
 				else:
 					chk_dupl_itm.append(f)
 
@@ -213,7 +212,8 @@
 
 		if not self.is_return:
 			self.check_credit_limit()
-
+		elif self.issue_credit_note:
+			self.make_return_invoice()
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating reserved qty in bin depends upon updated delivered qty in SO
 		self.update_stock_ledger()
@@ -311,11 +311,20 @@
 
 		for dn in set(updated_delivery_notes):
 			dn_doc = self if (dn == self.name) else frappe.get_doc("Delivery Note", dn)
-			if dn_doc.net_total > 0:
-				dn_doc.update_billing_percentage(update_modified=update_modified)
+			dn_doc.update_billing_percentage(update_modified=update_modified)
 
 		self.load_from_db()
 
+	def make_return_invoice(self):
+		try:
+			return_invoice = make_sales_invoice(self.name)
+			return_invoice.is_return = True
+			return_invoice.save()
+			return_invoice.submit()
+			frappe.msgprint(_("Credit Note {0} has been created automatically").format(return_invoice.name))
+		except:
+			frappe.throw(_("Could not create Credit Note automatically, please uncheck 'Issue Credit Note' and submit again"))
+
 def update_billed_amount_based_on_so(so_detail, update_modified=True):
 	# Billed against Sales Order directly
 	billed_against_so = frappe.db.sql("""select sum(amount) from `tabSales Invoice Item`
@@ -400,7 +409,7 @@
 		# set company address
 		target.update(get_company_address(target.company))
 		if target.company_address:
-			target.update(get_fetch_values("Sales Invoice", 'company_address', target.company_address))	
+			target.update(get_fetch_values("Sales Invoice", 'company_address', target.company_address))
 
 	def update_item(source_doc, target_doc, source_parent):
 		target_doc.qty = source_doc.qty - invoiced_qty_map.get(source_doc.name, 0)
@@ -452,6 +461,11 @@
 		target_doc.contact = source_parent.contact_person
 		target_doc.customer_contact = source_parent.contact_display
 
+		# Append unique Delivery Notes in Delivery Trip
+		delivery_notes.append(target_doc.delivery_note)
+
+	delivery_notes = []
+
 	doclist = get_mapped_doc("Delivery Note", source_name, {
 		"Delivery Note": {
 			"doctype": "Delivery Trip",
@@ -464,7 +478,8 @@
 			"field_map": {
 				"parent": "delivery_note"
 			},
-			"postprocess": update_stop_details,
+			"condition": lambda item: item.parent not in delivery_notes,
+			"postprocess": update_stop_details
 		}
 	}, target_doc)
 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_list.js b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
index f1ad929..9ec2a38 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note_list.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
@@ -1,14 +1,13 @@
 frappe.listview_settings['Delivery Note'] = {
-	add_fields: ["customer", "customer_name", "base_grand_total", "per_installed", "per_billed", 
-		"transporter_name", "grand_total", "is_return", "status"],
-	get_indicator: function(doc) {
-		if(cint(doc.is_return)==1) {
+	add_fields: ["grand_total", "is_return", "per_billed", "status"],
+	get_indicator: function (doc) {
+		if (cint(doc.is_return) == 1) {
 			return [__("Return"), "darkgrey", "is_return,=,Yes"];
-		} else if(doc.status==="Closed") {
+		} else if (doc.status === "Closed") {
 			return [__("Closed"), "green", "status,=,Closed"];
-		}  else if (flt(doc.per_billed, 2) < 100) {
+		} else if (doc.grand_total !== 0 && flt(doc.per_billed, 2) < 100) {
 			return [__("To Bill"), "orange", "per_billed,<,100"];
-		} else if (flt(doc.per_billed, 2) == 100) {
+		} else if (doc.grand_total === 0 || flt(doc.per_billed, 2) == 100) {
 			return [__("Completed"), "green", "per_billed,=,100"];
 		}
 	}
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 3683695..026d83c 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -569,6 +569,74 @@
 		dt = make_delivery_trip(dn.name)
 		self.assertEqual(dn.name, dt.delivery_stops[0].delivery_note)
 
+	def test_delivery_note_for_enable_allow_cost_center_in_entry_of_bs_account(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center for BS Account - _TC"
+		create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
+
+		company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
+		set_perpetual_inventory(1, company)
+
+		set_valuation_method("_Test Item", "FIFO")
+
+		make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100)
+
+		stock_in_hand_account = get_inventory_account('_Test Company')
+		dn = create_delivery_note(cost_center=cost_center)
+
+		gl_entries = get_gl_entries("Delivery Note", dn.name)
+		self.assertTrue(gl_entries)
+
+		expected_values = {
+			"Cost of Goods Sold - _TC": {
+				"cost_center": cost_center
+			},
+			stock_in_hand_account: {
+				"cost_center": cost_center
+			}
+		}
+		for i, gle in enumerate(gl_entries):
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+		set_perpetual_inventory(0, company)
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+
+	def test_delivery_note_for_disable_allow_cost_center_in_entry_of_bs_account(self):
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+		cost_center = "_Test Cost Center - _TC"
+
+		company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
+		set_perpetual_inventory(1, company)
+
+		set_valuation_method("_Test Item", "FIFO")
+
+		make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100)
+
+		stock_in_hand_account = get_inventory_account('_Test Company')
+		dn = create_delivery_note()
+
+		gl_entries = get_gl_entries("Delivery Note", dn.name)
+
+		self.assertTrue(gl_entries)
+		expected_values = {
+			"Cost of Goods Sold - _TC": {
+				"cost_center": cost_center
+			},
+			stock_in_hand_account: {
+				"cost_center": None
+			}
+		}
+		for i, gle in enumerate(gl_entries):
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+		set_perpetual_inventory(0, company)
+
 def create_delivery_note(**args):
 	dn = frappe.new_doc("Delivery Note")
 	args = frappe._dict(args)
@@ -589,7 +657,7 @@
 		"rate": args.rate or 100,
 		"conversion_factor": 1.0,
 		"expense_account": "Cost of Goods Sold - _TC",
-		"cost_center": "_Test Cost Center - _TC",
+		"cost_center": args.cost_center or "_Test Cost Center - _TC",
 		"serial_no": args.serial_no,
 		"target_warehouse": args.target_warehouse
 	})
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.json b/erpnext/stock/doctype/delivery_trip/delivery_trip.json
index 36f71a7..364bc6b 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.json
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.json
@@ -428,7 +428,7 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 0, 
+   "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
    "translatable": 0, 
@@ -608,7 +608,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-29 14:44:36.993178", 
+ "modified": "2018-08-30 02:31:49.400138", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Delivery Trip", 
@@ -661,6 +661,5 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 0, 
- "track_seen": 0, 
- "track_views": 0
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index 9e55f8c..5f291c3 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -3,16 +3,49 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
+
 import datetime
+
 import frappe
 from frappe import _
-from frappe.model.document import Document
-from frappe.utils.user import get_user_fullname
-from frappe.utils import getdate, cstr, get_datetime
 from frappe.contacts.doctype.address.address import get_address_display
+from frappe.model.document import Document
+from frappe.utils import cstr, get_datetime, getdate, get_link_to_form
+from frappe.utils.user import get_user_fullname
+
 
 class DeliveryTrip(Document):
-	pass
+	def on_submit(self):
+		self.update_delivery_notes()
+
+	def on_cancel(self):
+		self.update_delivery_notes(delete=True)
+
+	def update_delivery_notes(self, delete=False):
+		delivery_notes = list(set([stop.delivery_note for stop in self.delivery_stops if stop.delivery_note]))
+
+		update_fields = {
+			"transporter": self.driver,
+			"transporter_name": self.driver_name,
+			"transport_mode": "Road",
+			"vehicle_no": self.vehicle,
+			"vehicle_type": "Regular",
+			"lr_no": self.name,
+			"lr_date": self.date
+		}
+
+		for delivery_note in delivery_notes:
+			note_doc = frappe.get_doc("Delivery Note", delivery_note)
+
+			for field, value in update_fields.items():
+				value = None if delete else value
+				setattr(note_doc, field, value)
+
+			note_doc.save()
+
+		delivery_notes = [get_link_to_form("Delivery Note", note) for note in delivery_notes]
+		frappe.msgprint(_("Delivery Notes {0} updated".format(", ".join(delivery_notes))))
+
 
 
 def get_default_contact(out, name):
@@ -191,4 +224,4 @@
 def format_address(address):
 	"""Customer Address format """
 	address = frappe.get_doc('Address', address)
-	return '{}, {}, {}, {}'.format(address.address_line1, address.city, address.pincode, address.country)
\ No newline at end of file
+	return '{}, {}, {}, {}'.format(address.address_line1, address.city, address.pincode, address.country)
diff --git a/erpnext/stock/doctype/material_request/material_request.json b/erpnext/stock/doctype/material_request/material_request.json
index 9927265..c0285cb 100644
--- a/erpnext/stock/doctype/material_request/material_request.json
+++ b/erpnext/stock/doctype/material_request/material_request.json
@@ -779,6 +779,39 @@
    "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, 
+   "fieldname": "job_card", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Job Card", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Job Card", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "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
   }
  ],
  "has_web_view": 0,
@@ -793,7 +826,7 @@
  "istable": 0,
  "max_attachments": 0,
  "menu_index": 0,
- "modified": "2018-08-30 07:28:01.070112",
+ "modified": "2018-09-05 07:28:01.070112",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 730ec3e..42c8370 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -15,6 +15,7 @@
 from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
 from erpnext.buying.utils import check_for_closed_status, validate_for_items
 from erpnext.stock.doctype.item.item import get_item_defaults
+from erpnext.manufacturing.doctype.job_card.job_card import update_job_card_reference
 
 from six import string_types
 
@@ -92,6 +93,9 @@
 		if self.material_request_type == 'Purchase':
 			self.validate_budget()
 
+		if self.job_card:
+			update_job_card_reference(self.job_card, 'material_request', self.name)
+
 	def before_save(self):
 		self.set_status(update=True)
 
@@ -144,6 +148,8 @@
 	def on_cancel(self):
 		self.update_requested_qty()
 		self.update_requested_qty_in_production_plan()
+		if self.job_card:
+			update_job_card_reference(self.job_card, 'material_request', None)
 
 	def update_completed_qty(self, mr_items=None, update_modified=True):
 		if self.material_request_type == "Purchase":
@@ -407,7 +413,11 @@
 
 	def set_missing_values(source, target):
 		target.purpose = source.material_request_type
+		if source.job_card:
+			target.purpose = 'Material Transfer for Manufacture'
+
 		target.run_method("calculate_rate_and_amount")
+		target.set_job_card_data()
 
 	doclist = get_mapped_doc("Material Request", source_name, {
 		"Material Request": {
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 5c370d3..e482f58 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -470,4 +470,4 @@
 @frappe.whitelist()
 def update_purchase_receipt_status(docname, status):
 	pr = frappe.get_doc("Purchase Receipt", docname)
-	pr.update_status(status)
\ No newline at end of file
+	pr.update_status(status)
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
index 5c57fb5..e1d5b08 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
@@ -1,14 +1,13 @@
 frappe.listview_settings['Purchase Receipt'] = {
-	add_fields: ["supplier", "supplier_name", "base_grand_total", "is_subcontracted",
-		"transporter_name", "is_return", "status", "per_billed"],
-	get_indicator: function(doc) {
-		if(cint(doc.is_return)==1) {
+	add_fields: ["is_return", "grand_total", "status", "per_billed"],
+	get_indicator: function (doc) {
+		if (cint(doc.is_return) == 1) {
 			return [__("Return"), "darkgrey", "is_return,=,Yes"];
-		} else if(doc.status==="Closed") {
+		} else if (doc.status === "Closed") {
 			return [__("Closed"), "green", "status,=,Closed"];
-		}  else if (flt(doc.per_billed, 2) < 100) {
+		} else if (flt(doc.grand_total) !== 0 && flt(doc.per_billed, 2) < 100) {
 			return [__("To Bill"), "orange", "per_billed,<,100"];
-		} else if (flt(doc.per_billed, 2) == 100) {
+		} else if (flt(doc.grand_total) === 0 || flt(doc.per_billed, 2) == 100) {
 			return [__("Completed"), "green", "per_billed,=,100"];
 		}
 	}
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 6e2863e..a2da924 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -333,11 +333,78 @@
 		pr.cancel()
 		serial_nos = frappe.get_all('Serial No', {'asset': asset}, 'name') or []
 		self.assertEquals(len(serial_nos), 0)
-		frappe.db.sql("delete from `tabLocation")
+		#frappe.db.sql("delete from `tabLocation")
 		frappe.db.sql("delete from `tabAsset`")
 
+	def test_purchase_receipt_for_enable_allow_cost_center_in_entry_of_bs_account(self):
+		from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
+		accounts_settings.save()
+		cost_center = "_Test Cost Center for BS Account - _TC"
+		create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
+
+		if not frappe.db.exists('Location', 'Test Location'):
+			frappe.get_doc({
+				'doctype': 'Location',
+				'location_name': 'Test Location'
+			}).insert()
+
+		pr = make_purchase_receipt(cost_center=cost_center)
+		set_perpetual_inventory(1, pr.company)
+		stock_in_hand_account = get_inventory_account(pr.company, pr.get("items")[0].warehouse)
+		gl_entries = get_gl_entries("Purchase Receipt", pr.name)
+
+		self.assertTrue(gl_entries)
+
+		expected_values = {
+			"Stock Received But Not Billed - _TC": {
+				"cost_center": cost_center
+			},
+			stock_in_hand_account: {
+				"cost_center": cost_center
+			}
+		}
+		for i, gle in enumerate(gl_entries):
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+		set_perpetual_inventory(0, pr.company)
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+
+	def test_purchase_receipt_for_disable_allow_cost_center_in_entry_of_bs_account(self):
+		accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
+		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
+		accounts_settings.save()
+
+		if not frappe.db.exists('Location', 'Test Location'):
+			frappe.get_doc({
+				'doctype': 'Location',
+				'location_name': 'Test Location'
+			}).insert()
+
+		pr = make_purchase_receipt()
+		set_perpetual_inventory(1, pr.company)
+		stock_in_hand_account = get_inventory_account(pr.company, pr.get("items")[0].warehouse)
+		gl_entries = get_gl_entries("Purchase Receipt", pr.name)
+
+		self.assertTrue(gl_entries)
+
+		expected_values = {
+			"Stock Received But Not Billed - _TC": {
+				"cost_center": None
+			},
+			stock_in_hand_account: {
+				"cost_center": None
+			}
+		}
+		for i, gle in enumerate(gl_entries):
+			self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
+
+		set_perpetual_inventory(0, pr.company)
+
 def get_gl_entries(voucher_type, voucher_no):
-	return frappe.db.sql("""select account, debit, credit
+	return frappe.db.sql("""select account, debit, credit, cost_center
 		from `tabGL Entry` where voucher_type=%s and voucher_no=%s
 		order by account desc""", (voucher_type, voucher_no), as_dict=1)
 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index fa3501a..0356b0e 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -654,7 +654,7 @@
 	work_order: function() {
 		var me = this;
 		this.toggle_enable_bom();
-		if(!me.frm.doc.work_order) {
+		if(!me.frm.doc.work_order || me.frm.doc.job_card) {
 			return;
 		}
 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json
index 0e3fbec..35f8c27 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.json
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -1943,6 +1943,39 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fieldname": "job_card",
+   "fieldtype": "Link",
+   "hidden": 0,
+   "ignore_user_permissions": 0,
+   "ignore_xss_filter": 0,
+   "in_filter": 0,
+   "in_global_search": 0,
+   "in_list_view": 0,
+   "in_standard_filter": 0,
+   "label": "Job Card",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Job Card",
+   "permlevel": 0,
+   "precision": "",
+   "print_hide": 1,
+   "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,
    "fieldname": "amended_from",
    "fieldtype": "Link",
    "hidden": 0,
@@ -2015,7 +2048,7 @@
  "issingle": 0,
  "istable": 0,
  "max_attachments": 0,
- "modified": "2018-08-29 06:27:59.630826",
+ "modified": "2018-09-05 06:27:59.630826",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Entry",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index f723fcf..b7dbda2 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -17,6 +17,7 @@
 from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit, get_serial_nos
 
 import json
+from erpnext.manufacturing.doctype.job_card.job_card import update_job_card_reference
 
 from six import string_types, itervalues, iteritems
 
@@ -59,6 +60,7 @@
 		self.validate_batch()
 		self.validate_inspection()
 		self.validate_fg_completed_qty()
+		self.set_job_card_data()
 
 		if not self.from_bom:
 			self.fg_completed_qty = 0.0
@@ -88,6 +90,9 @@
 			self.update_so_in_serial_number()
 
 
+		if self.job_card:
+			update_job_card_reference(self.job_card, 'stock_entry', self.name)
+
 	def on_cancel(self):
 
 		if self.purchase_order and self.purpose == "Subcontract":
@@ -102,6 +107,18 @@
 		self.make_gl_entries_on_cancel()
 		self.update_cost_in_project()
 
+		if self.job_card:
+			update_job_card_reference(self.job_card, 'stock_entry', None)
+
+	def set_job_card_data(self):
+		if self.job_card and not self.work_order:
+			data = frappe.db.get_value('Job Card',
+				self.job_card, ['for_quantity', 'work_order', 'bom_no'], as_dict=1)
+			self.fg_completed_qty = data.for_quantity
+			self.work_order = data.work_order
+			self.from_bom = 1
+			self.bom_no = data.bom_no
+
 	def validate_work_order_status(self):
 		pro_doc = frappe.get_doc("Work Order", self.work_order)
 		if pro_doc.status == 'Completed':
@@ -584,6 +601,10 @@
 			if pro_doc.status == 'Stopped':
 				frappe.throw(_("Transaction not allowed against stopped Work Order {0}").format(self.work_order))
 
+		if self.job_card:
+			job_doc = frappe.get_doc('Job Card', self.job_card)
+			job_doc.set_transferred_qty()
+
 		if self.work_order:
 			pro_doc = frappe.get_doc("Work Order", self.work_order)
 			_validate_work_order(pro_doc)
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index a04d81d..c3cb437 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -392,15 +392,14 @@
 			price_list_rate = (args.rate / args.get('conversion_factor')
 				if args.get("conversion_factor") else args.rate)
 
-			name = frappe.db.get_value('Item Price',
-				{'item_code': args.item_code, 'price_list': args.price_list, 'currency': args.currency}, 'name')
-
-			if name:
-				item_price = frappe.get_doc('Item Price', name)
-				item_price.price_list_rate = price_list_rate
-				item_price.save()
-				frappe.msgprint(_("Item Price updated for {0} in Price List {1}").format(args.item_code,
-					args.price_list))
+			item_price = frappe.db.get_value('Item Price',
+				{'item_code': args.item_code, 'price_list': args.price_list, 'currency': args.currency},
+				['name', 'price_list_rate'], as_dict=1)
+			if item_price and item_price.name:
+				if item_price.price_list_rate != price_list_rate:
+					frappe.db.set_value('Item Price', item_price.name, "price_list_rate", price_list_rate)
+					frappe.msgprint(_("Item Price updated for {0} in Price List {1}").format(args.item_code,
+						args.price_list), alert=True)
 			else:
 				item_price = frappe.get_doc({
 					"doctype": "Item Price",
diff --git a/erpnext/stock/report/stock_balance/stock_balance.json b/erpnext/stock/report/stock_balance/stock_balance.json
index 4afbf75..2f20b20 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.json
+++ b/erpnext/stock/report/stock_balance/stock_balance.json
@@ -1,17 +1,17 @@
 {
  "add_total_row": 1, 
- "apply_user_permissions": 1, 
  "creation": "2014-10-10 17:58:11.577901", 
  "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 2, 
  "is_standard": "Yes", 
- "modified": "2017-02-24 20:10:13.764665", 
+ "modified": "2018-08-14 15:24:41.395557", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Stock Balance", 
  "owner": "Administrator", 
+ "prepared_report": 1, 
  "ref_doctype": "Stock Ledger Entry", 
  "report_name": "Stock Balance", 
  "report_type": "Script Report", 
diff --git a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.js b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.js
index 937c0a2..51b9b0c 100644
--- a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.js
+++ b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.js
@@ -27,10 +27,16 @@
 			}
 		},
 		{
+			"fieldname":"item_group",
+			"label": __("Item Group"),
+			"fieldtype": "Link",
+			"options": "Item Group"
+		},
+		{
 			"fieldname":"brand",
 			"label": __("Brand"),
 			"fieldtype": "Link",
 			"options": "Brand"
 		}
 	]
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
index 89a256c..3e6e5a5 100644
--- a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
+++ b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
@@ -39,6 +39,9 @@
 
 		if filters.brand and filters.brand != item.brand:
 			continue
+			
+		elif filters.item_group and filters.item_group != item.item_group:
+			continue
 
 		elif filters.company and filters.company != company:
 			continue