Merge branch 'develop' of https://github.com/frappe/erpnext into notification
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 7ab7f14..d224961 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -285,6 +285,7 @@
 	is_paid: function() {
 		hide_fields(this.frm.doc);
 		if(cint(this.frm.doc.is_paid)) {
+			this.frm.set_value("allocate_advances_automatically", 0);
 			if(!this.frm.doc.company) {
 				this.frm.set_value("is_paid", 0)
 				frappe.msgprint(__("Please specify Company to proceed"));
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 0af273c..95d49a4 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -21,8 +21,8 @@
 from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_disabled
 from frappe.model.mapper import get_mapped_doc
 from six import iteritems
-from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_invoice,\
-	unlink_inter_company_invoice
+from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
+	unlink_inter_company_doc
 from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
 from erpnext.accounts.deferred_revenue import validate_service_stop_date
 
@@ -348,7 +348,7 @@
 		self.make_gl_entries()
 
 		self.update_project()
-		update_linked_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
+		update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 
 	def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
 		if not self.grand_total:
@@ -778,7 +778,7 @@
 		self.update_project()
 		frappe.db.set(self, 'status', 'Cancelled')
 
-		unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
+		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 
 	def update_project(self):
 		project_list = []
@@ -917,5 +917,5 @@
 
 @frappe.whitelist()
 def make_inter_company_sales_invoice(source_name, target_doc=None):
-	from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_invoice
-	return make_inter_company_invoice("Purchase Invoice", source_name, target_doc)
+	from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
+	return make_inter_company_transaction("Purchase Invoice", source_name, target_doc)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 44af743..f21fbd9 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -369,6 +369,7 @@
 
 	set_pos_data: function() {
 		if(this.frm.doc.is_pos) {
+			this.frm.set_value("allocate_advances_automatically", 0);
 			if(!this.frm.doc.company) {
 				this.frm.set_value("is_pos", 0);
 				frappe.msgprint(__("Please specify Company to proceed"));
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 2089f15..31a9c66 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -179,7 +179,7 @@
 		if frappe.db.get_single_value('Selling Settings', 'sales_update_frequency') == "Each Transaction":
 			update_company_current_month_sales(self.company)
 			self.update_project()
-		update_linked_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
+		update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 
 		# create the loyalty point ledger entry if the customer is enrolled in any loyalty program
 		if not self.is_return and self.loyalty_program:
@@ -243,7 +243,7 @@
 			against_si_doc.delete_loyalty_point_entry()
 			against_si_doc.make_loyalty_point_entry()
 
-		unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
+		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference)
 
 		# Healthcare Service Invoice.
 		domain_settings = frappe.get_doc('Domain Settings')
@@ -1165,21 +1165,29 @@
 
 		self.set_missing_values(for_validate = True)
 
-def validate_inter_company_party(doctype, party, company, inter_company_invoice_reference):
-	if doctype == "Sales Invoice":
+def validate_inter_company_party(doctype, party, company, inter_company_reference):
+	if doctype in ["Sales Invoice", "Sales Order"]:
 		partytype, ref_partytype, internal = "Customer", "Supplier", "is_internal_customer"
-		ref_doc =  "Purchase Invoice"
+
+		if doctype == "Sales Invoice":
+			ref_doc = "Purchase Invoice"
+		else:
+			ref_doc = "Purchase Order"
 	else:
 		partytype, ref_partytype, internal = "Supplier", "Customer", "is_internal_supplier"
-		ref_doc =  "Sales Invoice"
 
-	if inter_company_invoice_reference:
-		doc = frappe.get_doc(ref_doc, inter_company_invoice_reference)
-		ref_party = doc.supplier if doctype == "Sales Invoice" else doc.customer
+		if doctype == "Purchase Invoice":
+			ref_doc = "Sales Invoice"
+		else:
+			ref_doc = "Sales Order"
+
+	if inter_company_reference:
+		doc = frappe.get_doc(ref_doc, inter_company_reference)
+		ref_party = doc.supplier if doctype in ["Sales Invoice", "Sales Order"] else doc.customer
 		if not frappe.db.get_value(partytype, {"represents_company": doc.company}, "name") == party:
-			frappe.throw(_("Invalid {0} for Inter Company Invoice.").format(partytype))
+			frappe.throw(_("Invalid {0} for Inter Company Transaction.").format(partytype))
 		if not frappe.get_cached_value(ref_partytype, ref_party, "represents_company") == company:
-			frappe.throw(_("Invalid Company for Inter Company Invoice."))
+			frappe.throw(_("Invalid Company for Inter Company Transaction."))
 
 	elif frappe.db.get_value(partytype, {"name": party, internal: 1}, "name") == party:
 		companies = frappe.db.sql("""select company from `tabAllowed To Transact With`
@@ -1188,18 +1196,29 @@
 		if not company in companies:
 			frappe.throw(_("{0} not allowed to transact with {1}. Please change the Company.").format(partytype, company))
 
-def update_linked_invoice(doctype, name, inter_company_invoice_reference):
-	if inter_company_invoice_reference:
-		frappe.db.set_value(doctype, inter_company_invoice_reference,\
-			"inter_company_invoice_reference", name)
+def update_linked_doc(doctype, name, inter_company_reference):
 
-def unlink_inter_company_invoice(doctype, name, inter_company_invoice_reference):
-	ref_doc = "Purchase Invoice" if doctype == "Sales Invoice" else "Sales Invoice"
-	if inter_company_invoice_reference:
-		frappe.db.set_value(doctype, name,\
-			"inter_company_invoice_reference", "")
-		frappe.db.set_value(ref_doc, inter_company_invoice_reference,\
-			"inter_company_invoice_reference", "")
+	if doctype in ["Sales Invoice", "Purchase Invoice"]:
+		ref_field = "inter_company_invoice_reference"
+	else:
+		ref_field = "inter_company_order_reference"
+
+	if inter_company_reference:
+		frappe.db.set_value(doctype, inter_company_reference,\
+			ref_field, name)
+
+def unlink_inter_company_doc(doctype, name, inter_company_reference):
+
+	if doctype in ["Sales Invoice", "Purchase Invoice"]:
+		ref_doc = "Purchase Invoice" if doctype == "Sales Invoice" else "Sales Invoice"
+		ref_field = "inter_company_invoice_reference"
+	else:
+		ref_doc = "Purchase Order" if doctype == "Sales Order" else "Sales Order"
+		ref_field = "inter_company_order_reference"
+
+	if inter_company_reference:
+		frappe.db.set_value(doctype, name, ref_field, "")
+		frappe.db.set_value(ref_doc, inter_company_reference, ref_field, "")
 
 def get_list_context(context=None):
 	from erpnext.controllers.website_list_for_contact import get_list_context
@@ -1299,7 +1318,7 @@
 			data.account = get_bank_cash_account(data.mode_of_payment, self.company).get("account")
 
 def get_inter_company_details(doc, doctype):
-	if doctype == "Sales Invoice":
+	if doctype in ["Sales Invoice", "Sales Order"]:
 		party = frappe.db.get_value("Supplier", {"disabled": 0, "is_internal_supplier": 1, "represents_company": doc.company}, "name")
 		company = frappe.get_cached_value("Customer", doc.customer, "represents_company")
 	else:
@@ -1312,21 +1331,21 @@
 	}
 
 
-def validate_inter_company_invoice(doc, doctype):
+def validate_inter_company_transaction(doc, doctype):
 
 	details = get_inter_company_details(doc, doctype)
-	price_list = doc.selling_price_list if doctype == "Sales Invoice" else doc.buying_price_list
+	price_list = doc.selling_price_list if doctype in ["Sales Invoice", "Sales Order"] else doc.buying_price_list
 	valid_price_list = frappe.db.get_value("Price List", {"name": price_list, "buying": 1, "selling": 1})
 	if not valid_price_list:
 		frappe.throw(_("Selected Price List should have buying and selling fields checked."))
 
 	party = details.get("party")
 	if not party:
-		partytype = "Supplier" if doctype == "Sales Invoice" else "Customer"
+		partytype = "Supplier" if doctype in ["Sales Invoice", "Sales Order"] else "Customer"
 		frappe.throw(_("No {0} found for Inter Company Transactions.").format(partytype))
 
 	company = details.get("company")
-	default_currency = frappe.get_cached_value('Company',  company,  "default_currency")
+	default_currency = frappe.get_cached_value('Company', company, "default_currency")
 	if default_currency != doc.currency:
 		frappe.throw(_("Company currencies of both the companies should match for Inter Company Transactions."))
 
@@ -1334,17 +1353,17 @@
 
 @frappe.whitelist()
 def make_inter_company_purchase_invoice(source_name, target_doc=None):
-	return make_inter_company_invoice("Sales Invoice", source_name, target_doc)
+	return make_inter_company_transaction("Sales Invoice", source_name, target_doc)
 
-def make_inter_company_invoice(doctype, source_name, target_doc=None):
-	if doctype == "Sales Invoice":
-		source_doc = frappe.get_doc("Sales Invoice", source_name)
-		target_doctype = "Purchase Invoice"
+def make_inter_company_transaction(doctype, source_name, target_doc=None):
+	if doctype in ["Sales Invoice", "Sales Order"]:
+		source_doc = frappe.get_doc(doctype, source_name)
+		target_doctype = "Purchase Invoice" if doctype == "Sales Invoice" else "Purchase Order"
 	else:
-		source_doc = frappe.get_doc("Purchase Invoice", source_name)
-		target_doctype = "Sales Invoice"
+		source_doc = frappe.get_doc(doctype, source_name)
+		target_doctype = "Sales Invoice" if doctype == "Purchase Invoice" else "Sales Order"
 
-	validate_inter_company_invoice(source_doc, doctype)
+	validate_inter_company_transaction(source_doc, doctype)
 	details = get_inter_company_details(source_doc, doctype)
 
 	def set_missing_values(source, target):
@@ -1352,7 +1371,7 @@
 
 	def update_details(source_doc, target_doc, source_parent):
 		target_doc.inter_company_invoice_reference = source_doc.name
-		if target_doc.doctype == "Purchase Invoice":
+		if target_doc.doctype in ["Purchase Invoice", "Purchase Order"]:
 			target_doc.company = details.get("company")
 			target_doc.supplier = details.get("party")
 			target_doc.buying_price_list = source_doc.selling_price_list
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 74c5f0e..47c6083 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -18,6 +18,7 @@
 from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
 from erpnext.stock.doctype.item.test_item import create_item
 from six import iteritems
+from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
 class TestSalesInvoice(unittest.TestCase):
 	def make(self):
 		w = frappe.copy_doc(test_records[0])
@@ -1625,6 +1626,61 @@
 			self.assertEqual(expected_gle[i][2], gle.credit)
 			self.assertEqual(getdate(expected_gle[i][3]), gle.posting_date)
 
+	def test_inter_company_transaction(self):
+
+		if not frappe.db.exists("Customer", "_Test Internal Customer"):
+			customer = frappe.get_doc({
+				"customer_group": "_Test Customer Group",
+				"customer_name": "_Test Internal Customer",
+				"customer_type": "Individual",
+				"doctype": "Customer",
+				"territory": "_Test Territory",
+				"is_internal_customer": 1,
+				"represents_company": "_Test Company 1"
+			})
+
+			customer.append("companies", {
+				"company": "Wind Power LLC"
+			})
+
+			customer.insert()
+
+		if not frappe.db.exists("Supplier", "_Test Internal Supplier"):
+			supplier = frappe.get_doc({
+				"supplier_group": "_Test Supplier Group",
+				"supplier_name": "_Test Internal Supplier",
+				"doctype": "Supplier",
+				"is_internal_supplier": 1,
+				"represents_company": "Wind Power LLC"
+			})
+
+			supplier.append("companies", {
+				"company": "_Test Company 1"
+			})
+
+			supplier.insert()
+
+		si = create_sales_invoice(
+			company = "Wind Power LLC",
+			customer = "_Test Internal Customer",
+			debit_to = "Debtors - WP",
+			warehouse = "Stores - WP",
+			income_account = "Sales - WP",
+			expense_account = "Cost of Goods Sold - WP",
+			cost_center = "Main - WP",
+			currency = "USD",
+			do_not_save = 1
+		)
+
+		si.selling_price_list = "_Test Price List Rest of the World"
+		si.submit()
+
+		target_doc = make_inter_company_transaction("Sales Invoice", si.name)
+		target_doc.submit()
+
+		self.assertEqual(target_doc.company, "_Test Company 1")
+		self.assertEqual(target_doc.supplier, "_Test Internal Supplier")
+
 def create_sales_invoice(**args):
 	si = frappe.new_doc("Sales Invoice")
 	args = frappe._dict(args)
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index f358b4a..48663ca 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -359,7 +359,8 @@
 			"from_date": from_date,
 			"to_date": to_date,
 			"cost_center": filters.cost_center,
-			"project": filters.project
+			"project": filters.project,
+			"finance_book": filters.get("finance_book")
 		},
 		as_dict=True)
 
diff --git a/erpnext/accounts/report/share_ledger/share_ledger.json b/erpnext/accounts/report/share_ledger/share_ledger.json
index d374bb7..fe158a6 100644
--- a/erpnext/accounts/report/share_ledger/share_ledger.json
+++ b/erpnext/accounts/report/share_ledger/share_ledger.json
@@ -1,23 +1,27 @@
 {
  "add_total_row": 0, 
- "apply_user_permissions": 1, 
  "creation": "2017-12-27 16:15:52.615453", 
+ "disable_prepared_report": 0, 
  "disabled": 0, 
  "docstatus": 0, 
  "doctype": "Report", 
  "idx": 0, 
  "is_standard": "Yes", 
- "modified": "2017-12-27 16:46:54.422356", 
+ "modified": "2019-04-19 10:50:36.061588", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Share Ledger", 
  "owner": "Administrator", 
+ "prepared_report": 0, 
  "ref_doctype": "Share Transfer", 
  "report_name": "Share Ledger", 
  "report_type": "Script Report", 
  "roles": [
   {
    "role": "Administrator"
+  }, 
+  {
+   "role": "System Manager"
   }
  ]
 }
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index e9a0f70..2d78d26 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -296,6 +296,12 @@
 		frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
 	},
 
+	gross_purchase_amount: function(frm) {
+		frm.doc.finance_books.forEach(d => {
+			frm.events.set_depreciation_rate(frm, d);
+		})
+	},
+
 	set_depreciation_rate: function(frm, row) {
 		if (row.total_number_of_depreciations && row.frequency_of_depreciation) {
 			frappe.call({
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 8011038..72f5c62 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -101,7 +101,7 @@
 
 	def set_depreciation_rate(self):
 		for d in self.get("finance_books"):
-			d.rate_of_depreciation = self.get_depreciation_rate(d)
+			d.rate_of_depreciation = self.get_depreciation_rate(d, on_validate=True)
 
 	def make_depreciation_schedule(self):
 		depreciation_method = [d.depreciation_method for d in self.finance_books]
@@ -125,7 +125,7 @@
 					no_of_depreciations * cint(d.frequency_of_depreciation))
 
 				total_days = date_diff(end_date, self.available_for_use_date)
-				rate_per_day = value_after_depreciation / total_days
+				rate_per_day = (value_after_depreciation - d.get("expected_value_after_useful_life")) / total_days
 
 				number_of_pending_depreciations = cint(d.total_number_of_depreciations) - \
 					cint(self.number_of_depreciations_booked)
@@ -291,8 +291,8 @@
 
 	def validate_expected_value_after_useful_life(self):
 		for row in self.get('finance_books'):
-			accumulated_depreciation_after_full_schedule = \
-				max([d.accumulated_depreciation_amount for d in self.get("schedules") if d.finance_book_id == row.idx])
+			accumulated_depreciation_after_full_schedule = max([d.accumulated_depreciation_amount
+				for d in self.get("schedules") if cint(d.finance_book_id) == row.idx])
 
 			asset_value_after_full_schedule = flt(flt(self.gross_purchase_amount) -
 				flt(accumulated_depreciation_after_full_schedule),
@@ -403,7 +403,7 @@
 			make_gl_entries(gl_entries)
 			self.db_set('booked_fixed_asset', 1)
 
-	def get_depreciation_rate(self, args):
+	def get_depreciation_rate(self, args, on_validate=False):
 		if isinstance(args, string_types):
 			args = json.loads(args)
 
@@ -420,7 +420,10 @@
 		if args.get("depreciation_method") == 'Double Declining Balance':
 			return 200.0 / args.get("total_number_of_depreciations")
 
-		if args.get("depreciation_method") == "Written Down Value" and not args.get("rate_of_depreciation"):
+		if args.get("depreciation_method") == "Written Down Value":
+			if args.get("rate_of_depreciation") and on_validate:
+				return args.get("rate_of_depreciation")
+
 			no_of_years = flt(args.get("total_number_of_depreciations") * flt(args.get("frequency_of_depreciation"))) / 12
 			value = flt(args.get("expected_value_after_useful_life")) / flt(self.gross_purchase_amount)
 
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 985097b..ef85ffa 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -102,9 +102,9 @@
 		asset.save()
 		self.assertEqual(asset.status, "Draft")
 		expected_schedules = [
-			["2020-06-06", 163.93, 163.93],
-			["2021-04-06", 49836.07, 50000.0],
-			["2022-02-06", 40000.0, 90000.00]
+			["2020-06-06", 147.54, 147.54],
+			["2021-04-06", 44852.46, 45000.0],
+			["2022-02-06", 45000.0, 90000.00]
 		]
 
 		schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
@@ -130,8 +130,8 @@
 		self.assertEqual(asset.status, "Draft")
 		asset.save()
 		expected_schedules = [
-			["2020-06-06", 197.37, 40197.37],
-			["2021-04-06", 49802.63, 90000.00]
+			["2020-06-06", 164.47, 40164.47],
+			["2021-04-06", 49835.53, 90000.00]
 		]
 		schedules = [[cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount]
 			for d in asset.get("schedules")]
@@ -266,8 +266,8 @@
 		self.assertEqual(asset.get("schedules")[0].journal_entry[:4], "DEPR")
 
 		expected_gle = (
-			("_Test Accumulated Depreciations - _TC", 0.0, 35699.15),
-			("_Test Depreciations - _TC", 35699.15, 0.0)
+			("_Test Accumulated Depreciations - _TC", 0.0, 32129.24),
+			("_Test Depreciations - _TC", 32129.24, 0.0)
 		)
 
 		gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 28ceab5..e63ef60 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -138,6 +138,20 @@
 							erpnext.utils.make_subscription(doc.doctype, doc.name)
 						}, __('Create'))
 					}
+
+					if (doc.docstatus === 1 && !doc.inter_company_order_reference) {
+						let me = this;
+						frappe.model.with_doc("Supplier", me.frm.doc.supplier, () => {
+							let supplier = frappe.model.get_doc("Supplier", me.frm.doc.supplier);
+							let internal = supplier.is_internal_supplier;
+							let disabled = supplier.disabled;
+							if (internal === 1 && disabled === 0) {
+								me.frm.add_custom_button("Inter Company Order", function() {
+									me.make_inter_company_order(me.frm);
+								}, __('Create'));
+							}
+						});
+					}
 				}
 				if(flt(doc.per_billed)==0) {
 					this.frm.add_custom_button(__('Payment Request'),
@@ -296,6 +310,13 @@
 		});
 	},
 
+	make_inter_company_order: function(frm) {
+		frappe.model.open_mapped_doc({
+			method: "erpnext.buying.doctype.purchase_order.purchase_order.make_inter_company_sales_order",
+			frm: frm
+		});
+	},
+
 	make_purchase_receipt: function() {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_receipt",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 46f48fb..13a097a 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -298,6 +298,7 @@
    "collapsible": 0,
    "columns": 0,
    "default": "Today",
+   "fetch_if_empty": 0,
    "fieldname": "transaction_date",
    "fieldtype": "Date",
    "hidden": 0,
@@ -332,6 +333,7 @@
    "collapsible": 0,
    "columns": 0,
    "default": "",
+   "fetch_if_empty": 0,
    "fieldname": "schedule_date",
    "fieldtype": "Date",
    "hidden": 0,
@@ -365,6 +367,7 @@
    "collapsible": 0,
    "columns": 0,
    "depends_on": "eval:doc.docstatus===1",
+   "fetch_if_empty": 0,
    "fieldname": "order_confirmation_no",
    "fieldtype": "Data",
    "hidden": 0,
@@ -398,6 +401,7 @@
    "collapsible": 0,
    "columns": 0,
    "depends_on": "eval:doc.order_confirmation_no",
+   "fetch_if_empty": 0,
    "fieldname": "order_confirmation_date",
    "fieldtype": "Date",
    "hidden": 0,
@@ -430,6 +434,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "amended_from",
    "fieldtype": "Link",
    "hidden": 0,
@@ -465,6 +470,7 @@
    "collapsible": 0,
    "collapsible_depends_on": "",
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "drop_ship",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -498,6 +504,7 @@
    "collapsible": 0,
    "columns": 0,
    "depends_on": "",
+   "fetch_if_empty": 0,
    "fieldname": "customer",
    "fieldtype": "Link",
    "hidden": 0,
@@ -532,6 +539,7 @@
    "collapsible": 0,
    "columns": 0,
    "depends_on": "",
+   "fetch_if_empty": 0,
    "fieldname": "customer_name",
    "fieldtype": "Data",
    "hidden": 0,
@@ -564,6 +572,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "column_break_19",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -596,6 +605,7 @@
    "collapsible": 0,
    "columns": 0,
    "depends_on": "",
+   "fetch_if_empty": 0,
    "fieldname": "customer_contact_person",
    "fieldtype": "Link",
    "hidden": 0,
@@ -629,6 +639,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "customer_contact_display",
    "fieldtype": "Small Text",
    "hidden": 1,
@@ -661,6 +672,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "customer_contact_mobile",
    "fieldtype": "Small Text",
    "hidden": 1,
@@ -693,6 +705,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "customer_contact_email",
    "fieldtype": "Code",
    "hidden": 1,
@@ -726,6 +739,7 @@
    "bold": 0,
    "collapsible": 1,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "section_addresses",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -758,6 +772,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "supplier_address",
    "fieldtype": "Link",
    "hidden": 0,
@@ -790,6 +805,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "contact_person",
    "fieldtype": "Link",
    "hidden": 0,
@@ -823,6 +839,7 @@
    "collapsible": 0,
    "columns": 0,
    "depends_on": "",
+   "fetch_if_empty": 0,
    "fieldname": "address_display",
    "fieldtype": "Small Text",
    "hidden": 0,
@@ -854,6 +871,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "contact_display",
    "fieldtype": "Small Text",
    "hidden": 0,
@@ -885,6 +903,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "contact_mobile",
    "fieldtype": "Small Text",
    "hidden": 0,
@@ -916,6 +935,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "contact_email",
    "fieldtype": "Small Text",
    "hidden": 0,
@@ -947,6 +967,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "col_break_address",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -979,6 +1000,7 @@
    "collapsible": 0,
    "columns": 0,
    "depends_on": "",
+   "fetch_if_empty": 0,
    "fieldname": "shipping_address",
    "fieldtype": "Link",
    "hidden": 0,
@@ -1012,6 +1034,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "shipping_address_display",
    "fieldtype": "Small Text",
    "hidden": 0,
@@ -1044,6 +1067,7 @@
    "bold": 0,
    "collapsible": 1,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "currency_and_price_list",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1076,6 +1100,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "currency",
    "fieldtype": "Link",
    "hidden": 0,
@@ -1111,6 +1136,7 @@
    "collapsible": 0,
    "columns": 0,
    "description": "",
+   "fetch_if_empty": 0,
    "fieldname": "conversion_rate",
    "fieldtype": "Float",
    "hidden": 0,
@@ -1145,6 +1171,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "cb_price_list",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -1175,6 +1202,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "buying_price_list",
    "fieldtype": "Link",
    "hidden": 0,
@@ -1207,6 +1235,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "price_list_currency",
    "fieldtype": "Link",
    "hidden": 0,
@@ -1239,6 +1268,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "plc_conversion_rate",
    "fieldtype": "Float",
    "hidden": 0,
@@ -1271,6 +1301,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "ignore_pricing_rule",
    "fieldtype": "Check",
    "hidden": 0,
@@ -1302,6 +1333,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "sec_warehouse",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1333,6 +1365,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "set_warehouse",
    "fieldtype": "Link",
    "hidden": 0,
@@ -1366,6 +1399,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "col_break_warehouse",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -1398,6 +1432,7 @@
    "collapsible": 0,
    "columns": 0,
    "default": "No",
+   "fetch_if_empty": 0,
    "fieldname": "is_subcontracted",
    "fieldtype": "Select",
    "hidden": 0,
@@ -1431,6 +1466,7 @@
    "collapsible": 0,
    "columns": 0,
    "depends_on": "eval:doc.is_subcontracted==\"Yes\"",
+   "fetch_if_empty": 0,
    "fieldname": "supplier_warehouse",
    "fieldtype": "Link",
    "hidden": 0,
@@ -1464,6 +1500,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "items_section",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1497,6 +1534,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "scan_barcode",
    "fieldtype": "Data",
    "hidden": 0,
@@ -1529,6 +1567,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "items",
    "fieldtype": "Table",
    "hidden": 0,
@@ -1563,6 +1602,7 @@
    "bold": 0,
    "collapsible": 1,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "section_break_48",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1596,6 +1636,7 @@
    "collapsible": 0,
    "collapsible_depends_on": "",
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "pricing_rules",
    "fieldtype": "Table",
    "hidden": 0,
@@ -1630,6 +1671,7 @@
    "collapsible": 0,
    "collapsible_depends_on": "supplied_items",
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "raw_material_details",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1663,6 +1705,7 @@
    "collapsible": 0,
    "columns": 0,
    "depends_on": "",
+   "fetch_if_empty": 0,
    "fieldname": "supplied_items",
    "fieldtype": "Table",
    "hidden": 0,
@@ -1697,6 +1740,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "sb_last_purchase",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1727,6 +1771,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "total_qty",
    "fieldtype": "Float",
    "hidden": 0,
@@ -1759,6 +1804,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "base_total",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -1792,6 +1838,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "base_net_total",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -1826,6 +1873,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "column_break_26",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -1856,6 +1904,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "total",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -1889,6 +1938,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "net_total",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -1923,6 +1973,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "total_net_weight",
    "fieldtype": "Float",
    "hidden": 0,
@@ -1955,6 +2006,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "taxes_section",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1989,6 +2041,7 @@
    "collapsible": 0,
    "columns": 0,
    "description": "",
+   "fetch_if_empty": 0,
    "fieldname": "taxes_and_charges",
    "fieldtype": "Link",
    "hidden": 0,
@@ -2023,6 +2076,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "column_break_50",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -2054,6 +2108,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "shipping_rule",
    "fieldtype": "Link",
    "hidden": 0,
@@ -2087,6 +2142,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "section_break_52",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -2118,6 +2174,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "taxes",
    "fieldtype": "Table",
    "hidden": 0,
@@ -2152,6 +2209,7 @@
    "bold": 0,
    "collapsible": 1,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "sec_tax_breakup",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -2184,6 +2242,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "other_charges_calculation",
    "fieldtype": "Text",
    "hidden": 0,
@@ -2216,6 +2275,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "totals",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -2249,6 +2309,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "base_taxes_and_charges_added",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2283,6 +2344,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "base_taxes_and_charges_deducted",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2317,6 +2379,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "base_total_taxes_and_charges",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2351,6 +2414,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "column_break_39",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -2382,6 +2446,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "taxes_and_charges_added",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2416,6 +2481,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "taxes_and_charges_deducted",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2450,6 +2516,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "total_taxes_and_charges",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2484,6 +2551,7 @@
    "collapsible": 1,
    "collapsible_depends_on": "discount_amount",
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "discount_section",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -2517,6 +2585,7 @@
    "collapsible": 0,
    "columns": 0,
    "default": "Grand Total",
+   "fetch_if_empty": 0,
    "fieldname": "apply_discount_on",
    "fieldtype": "Select",
    "hidden": 0,
@@ -2550,6 +2619,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "base_discount_amount",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2583,6 +2653,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "column_break_45",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -2614,6 +2685,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "additional_discount_percentage",
    "fieldtype": "Float",
    "hidden": 0,
@@ -2646,6 +2718,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "discount_amount",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2679,6 +2752,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "totals_section",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -2710,6 +2784,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "base_grand_total",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2744,6 +2819,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "base_rounding_adjustment",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2778,6 +2854,7 @@
    "collapsible": 0,
    "columns": 0,
    "description": "In Words will be visible once you save the Purchase Order.",
+   "fetch_if_empty": 0,
    "fieldname": "base_in_words",
    "fieldtype": "Data",
    "hidden": 0,
@@ -2811,6 +2888,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "base_rounded_total",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2845,6 +2923,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "column_break4",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -2876,6 +2955,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "grand_total",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2910,6 +2990,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "rounding_adjustment",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2943,6 +3024,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "rounded_total",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -2975,6 +3057,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "disable_rounded_total",
    "fieldtype": "Check",
    "hidden": 0,
@@ -3007,6 +3090,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "in_words",
    "fieldtype": "Data",
    "hidden": 0,
@@ -3040,6 +3124,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "advance_paid",
    "fieldtype": "Currency",
    "hidden": 0,
@@ -3072,6 +3157,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "payment_schedule_section",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -3104,6 +3190,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "payment_terms_template",
    "fieldtype": "Link",
    "hidden": 0,
@@ -3137,6 +3224,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "payment_schedule",
    "fieldtype": "Table",
    "hidden": 0,
@@ -3171,6 +3259,7 @@
    "collapsible": 1,
    "collapsible_depends_on": "terms",
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "terms_section_break",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -3204,6 +3293,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "tc_name",
    "fieldtype": "Link",
    "hidden": 0,
@@ -3238,6 +3328,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "terms",
    "fieldtype": "Text Editor",
    "hidden": 0,
@@ -3271,6 +3362,7 @@
    "bold": 0,
    "collapsible": 1,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "more_info",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -3304,6 +3396,7 @@
    "collapsible": 0,
    "columns": 0,
    "default": "Draft",
+   "fetch_if_empty": 0,
    "fieldname": "status",
    "fieldtype": "Select",
    "hidden": 0,
@@ -3338,6 +3431,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "ref_sq",
    "fieldtype": "Data",
    "hidden": 1,
@@ -3371,6 +3465,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "party_account_currency",
    "fieldtype": "Link",
    "hidden": 1,
@@ -3404,6 +3499,41 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "inter_company_order_reference",
+   "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": "Inter Company Order Reference",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Sales Order",
+   "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,
+   "fetch_if_empty": 0,
    "fieldname": "column_break_74",
    "fieldtype": "Column Break",
    "hidden": 0,
@@ -3437,6 +3567,7 @@
    "columns": 0,
    "depends_on": "eval:!doc.__islocal",
    "description": "",
+   "fetch_if_empty": 0,
    "fieldname": "per_received",
    "fieldtype": "Percent",
    "hidden": 0,
@@ -3472,6 +3603,7 @@
    "columns": 0,
    "depends_on": "eval:!doc.__islocal",
    "description": "",
+   "fetch_if_empty": 0,
    "fieldname": "per_billed",
    "fieldtype": "Percent",
    "hidden": 0,
@@ -3505,6 +3637,7 @@
    "bold": 0,
    "collapsible": 1,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "column_break5",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -3906,17 +4039,15 @@
   }
  ],
  "has_web_view": 0,
- "hide_heading": 0,
  "hide_toolbar": 0,
  "icon": "fa fa-file-text",
  "idx": 105,
- "image_view": 0,
  "in_create": 0,
  "is_submittable": 1,
  "issingle": 0,
  "istable": 0,
  "max_attachments": 0,
- "modified": "2019-02-14 19:36:49.390935",
+ "modified": "2019-04-18 19:43:17.239390",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order",
@@ -4001,7 +4132,6 @@
  ],
  "quick_entry": 0,
  "read_only": 0,
- "read_only_onload": 1,
  "search_fields": "status, transaction_date, supplier,grand_total",
  "show_name_in_global_search": 1,
  "sort_field": "modified",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 1c3469e..4353976 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -17,6 +17,8 @@
 from six import string_types
 from erpnext.stock.doctype.item.item import get_item_defaults
 from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
+from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
+	unlink_inter_company_doc
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -56,6 +58,7 @@
 		self.validate_bom_for_subcontracting_items()
 		self.create_raw_materials_supplied("supplied_items")
 		self.set_received_qty_for_drop_ship_items()
+		validate_inter_company_party(self.doctype, self.supplier, self.company, self.inter_company_order_reference)
 
 	def validate_with_previous_doc(self):
 		super(PurchaseOrder, self).validate_with_previous_doc({
@@ -219,6 +222,7 @@
 
 		self.update_blanket_order()
 
+		update_linked_doc(self.doctype, self.name, self.inter_company_order_reference)
 
 	def on_cancel(self):
 		super(PurchaseOrder, self).on_cancel()
@@ -244,6 +248,7 @@
 
 		self.update_blanket_order()
 
+		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_order_reference)
 
 	def on_update(self):
 		pass
@@ -492,3 +497,9 @@
 	po = frappe.get_doc("Purchase Order", name)
 	po.update_status(status)
 	po.update_delivered_qty_in_sales_order()
+
+@frappe.whitelist()
+def make_inter_company_sales_order(source_name, target_doc=None):
+	from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
+	return make_inter_company_transaction("Purchase Order", source_name, target_doc)
+
diff --git a/erpnext/config/accounting.py b/erpnext/config/accounting.py
index 1b8bf27..6664c4d 100644
--- a/erpnext/config/accounting.py
+++ b/erpnext/config/accounting.py
@@ -78,6 +78,11 @@
 					"name": "Payment Entry",
 					"description": _("Bank/Cash transactions against party or for internal transfer")
 				},
+				{
+					"type": "doctype",
+					"name": "Payment Term",
+					"description": _("Payment Terms based on conditions")
+				},
 
 				# Reports
 				{
@@ -133,6 +138,11 @@
 				},
 				{
 					"type": "doctype",
+					"name": "Exchange Rate Revaluation",
+					"description": _("Exchange Rate Revaluation master.")
+				},
+				{
+					"type": "doctype",
 					"name": "Payment Gateway Account",
 					"description": _("Setup Gateway accounts.")
 				},
diff --git a/erpnext/config/education.py b/erpnext/config/education.py
index d5f9e2d..4efaaa6 100644
--- a/erpnext/config/education.py
+++ b/erpnext/config/education.py
@@ -35,6 +35,10 @@
 				},
 				{
 					"type": "doctype",
+					"name": "Web Academy Applicant"
+				},
+				{
+					"type": "doctype",
 					"name": "Student Admission"
 				},
 				{
@@ -182,12 +186,16 @@
 			"items": [
 				{
 					"type": "doctype",
+					"name": "Program",
+				},
+				{
+					"type": "doctype",
 					"name": "Course",
 					"onboard": 1,
 				},
 				{
 					"type": "doctype",
-					"name": "Program"
+					"name": "Topic",
 				},
 				{
 					"type": "doctype",
@@ -202,6 +210,40 @@
 			]
 		},
 		{
+			"label": _("Content Masters"),
+			"items": [
+				{
+					"type": "doctype",
+					"name": "Article"
+				},
+				{
+					"type": "doctype",
+					"name": "Video"
+				},
+				{
+					"type": "doctype",
+					"name": "Quiz"
+				}
+			]
+		},
+		{
+			"label": _("LMS Activity"),
+			"items": [
+				{
+					"type": "doctype",
+					"name": "Course Enrollment"
+				},
+				{
+					"type": "doctype",
+					"name": "Course Activity"
+				},
+				{
+					"type": "doctype",
+					"name": "Quiz Activity"
+				}
+			]
+		},
+		{
 			"label": _("Settings"),
 			"items": [
 				{
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 63ea259..155a996 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -89,7 +89,8 @@
 			self.validate_paid_amount()
 
 		if self.doctype in ['Purchase Invoice', 'Sales Invoice']:
-			if cint(self.allocate_advances_automatically):
+			pos_check_field = "is_pos" if self.doctype=="Sales Invoice" else "is_paid"
+			if cint(self.allocate_advances_automatically) and not cint(self.get(pos_check_field)):
 				self.set_advances()
 
 			if self.is_return:
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index 442b6c2..d42502d 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -10,6 +10,7 @@
 from erpnext.controllers.selling_controller import SellingController
 from frappe.contacts.address_and_contact import load_address_and_contact
 from erpnext.accounts.party import set_taxes
+from frappe.email.inbox import link_communication_to_document
 
 sender_field = "email_id"
 
@@ -199,3 +200,29 @@
 		out['taxes_and_charges'] = taxes_and_charges
 
 	return out
+
+@frappe.whitelist()
+def make_lead_from_communication(communication, ignore_communication_links=False):
+	""" raise a issue from email """
+
+	doc = frappe.get_doc("Communication", communication)
+	lead_name = None
+	if doc.sender:
+		lead_name = frappe.db.get_value("Lead", {"email_id": doc.sender})
+	if not lead_name and doc.phone_no:
+		lead_name = frappe.db.get_value("Lead", {"mobile_no": doc.phone_no})
+	if not lead_name:
+		lead = frappe.get_doc({
+			"doctype": "Lead",
+			"lead_name": doc.sender_full_name,
+			"email_id": doc.sender,
+			"mobile_no": doc.phone_no
+		})
+		lead.flags.ignore_mandatory = True
+		lead.flags.ignore_permissions = True
+		lead.insert()
+
+		lead_name = lead.name
+
+	link_communication_to_document(doc, "Lead", lead_name, ignore_communication_links)
+	return lead_name
\ No newline at end of file
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 2e02e75..4d45936 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -10,6 +10,7 @@
 from erpnext.utilities.transaction_base import TransactionBase
 from erpnext.accounts.party import get_party_account_currency
 from frappe.desk.form import assign_to
+from frappe.email.inbox import link_communication_to_document
 
 subject_field = "title"
 sender_field = "contact_email"
@@ -349,3 +350,23 @@
 				"name": doc.name,
 				"description": doc.get(subject_field)
 			})
+@frappe.whitelist()
+def make_opportunity_from_communication(communication, ignore_communication_links=False):
+	from erpnext.crm.doctype.lead.lead import make_lead_from_communication
+	doc = frappe.get_doc("Communication", communication)
+
+	lead = doc.reference_name if doc.reference_doctype == "Lead" else None
+	if not lead:
+		lead = make_lead_from_communication(communication, ignore_communication_links=True)
+
+	enquiry_from = "Lead"
+
+	opportunity = frappe.get_doc({
+		"doctype": "Opportunity",
+		"enquiry_from": enquiry_from,
+		"lead": lead
+	}).insert(ignore_permissions=True)
+
+	link_communication_to_document(doc, "Opportunity", opportunity.name, ignore_communication_links)
+
+	return opportunity.name
diff --git a/erpnext/domains/education.py b/erpnext/domains/education.py
index c640576..55e4eed 100644
--- a/erpnext/domains/education.py
+++ b/erpnext/domains/education.py
@@ -14,7 +14,7 @@
 		'Student Attendance Tool',
 		'Student Applicant'
 	],
-	'default_portal_role': 'Guardian',
+	'default_portal_role': 'LMS User',
 	'restricted_roles': [
 		'Student',
 		'Instructor',
diff --git a/erpnext/education/api.py b/erpnext/education/api.py
index 30d5588..1a19716 100644
--- a/erpnext/education/api.py
+++ b/erpnext/education/api.py
@@ -38,7 +38,7 @@
 	program_enrollment.student = student.name
 	program_enrollment.student_name = student.title
 	program_enrollment.program = frappe.db.get_value("Student Applicant", source_name, "program")
-	frappe.publish_realtime('enroll_student_progress', {"progress": [4, 4]}, user=frappe.session.user)	
+	frappe.publish_realtime('enroll_student_progress', {"progress": [2, 4]}, user=frappe.session.user)
 	return program_enrollment
 
 
@@ -69,7 +69,7 @@
 
 	present = json.loads(students_present)
 	absent = json.loads(students_absent)
-	
+
 	for d in present:
 		make_attendance_records(d["student"], d["student_name"], "Present", course_schedule, student_group, date)
 
@@ -89,7 +89,7 @@
 	:param status: Status (Present/Absent)
 	"""
 	student_attendance = frappe.get_doc({
-		"doctype": "Student Attendance", 
+		"doctype": "Student Attendance",
 		"student": student,
 		"course_schedule": course_schedule,
 		"student_group": student_group,
@@ -112,7 +112,7 @@
 
 	:param student: Student.
 	"""
-	guardians = frappe.get_list("Student Guardian", fields=["guardian"] , 
+	guardians = frappe.get_list("Student Guardian", fields=["guardian"] ,
 		filters={"parent": student})
 	return guardians
 
@@ -353,7 +353,7 @@
 		for guard in get_student_guardians(stud.student):
 			email = frappe.db.get_value("Guardian", guard.guardian, "email_address")
 			if email:
-				email_list.append(email)	
+				email_list.append(email)
 	add_subscribers(name, email_list)
 
 @frappe.whitelist()
diff --git a/erpnext/education/doctype/article/__init__.py b/erpnext/education/doctype/article/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/article/__init__.py
diff --git a/erpnext/education/doctype/article/article.js b/erpnext/education/doctype/article/article.js
new file mode 100644
index 0000000..4c9c6f0
--- /dev/null
+++ b/erpnext/education/doctype/article/article.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Article', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/article/article.json b/erpnext/education/doctype/article/article.json
new file mode 100644
index 0000000..c30cd18
--- /dev/null
+++ b/erpnext/education/doctype/article/article.json
@@ -0,0 +1,230 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "field:title",
+ "beta": 0,
+ "creation": "2018-10-17 05:45:38.471670",
+ "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": "title",
+   "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": "Title",
+   "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,
+   "fieldname": "author",
+   "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": "Author",
+   "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": "content",
+   "fieldtype": "Text Editor",
+   "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": "Content",
+   "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": "publish_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": "Publish 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
+  }
+ ],
+ "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-11-25 19:06:56.016865",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Article",
+ "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": "Academics User",
+   "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": "Instructor",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "LMS User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  }
+ ],
+ "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/education/doctype/article/article.py b/erpnext/education/doctype/article/article.py
new file mode 100644
index 0000000..7dc850b
--- /dev/null
+++ b/erpnext/education/doctype/article/article.py
@@ -0,0 +1,15 @@
+# -*- 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.model.document import Document
+
+class Article(Document):
+
+
+	def get_article(self):
+		pass
+
+
diff --git a/erpnext/education/doctype/article/test_article.js b/erpnext/education/doctype/article/test_article.js
new file mode 100644
index 0000000..9dbf063
--- /dev/null
+++ b/erpnext/education/doctype/article/test_article.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: Article", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Article
+		() => frappe.tests.make('Article', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/article/test_article.py b/erpnext/education/doctype/article/test_article.py
new file mode 100644
index 0000000..2fce07f
--- /dev/null
+++ b/erpnext/education/doctype/article/test_article.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestArticle(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/content_activity/__init__.py b/erpnext/education/doctype/content_activity/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/content_activity/__init__.py
diff --git a/erpnext/education/doctype/content_activity/content_activity.json b/erpnext/education/doctype/content_activity/content_activity.json
new file mode 100644
index 0000000..b4c95da
--- /dev/null
+++ b/erpnext/education/doctype/content_activity/content_activity.json
@@ -0,0 +1,141 @@
+{
+ "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-10-16 03:55:53.283893", 
+ "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": "content", 
+   "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": "Content", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Content", 
+   "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, 
+   "fetch_from": "content.content_type", 
+   "fieldname": "content_type", 
+   "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": "Content Type", 
+   "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": "last_activity", 
+   "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": "Last Activity ", 
+   "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-10-16 03:55:58.202436", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Content Activity", 
+ "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/education/doctype/content_activity/content_activity.py b/erpnext/education/doctype/content_activity/content_activity.py
new file mode 100644
index 0000000..2ae7a5c
--- /dev/null
+++ b/erpnext/education/doctype/content_activity/content_activity.py
@@ -0,0 +1,10 @@
+# -*- 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.model.document import Document
+
+class ContentActivity(Document):
+	pass
diff --git a/erpnext/education/doctype/content_question/__init__.py b/erpnext/education/doctype/content_question/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/content_question/__init__.py
diff --git a/erpnext/education/doctype/content_question/content_question.js b/erpnext/education/doctype/content_question/content_question.js
new file mode 100644
index 0000000..7615f5e
--- /dev/null
+++ b/erpnext/education/doctype/content_question/content_question.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Content Question', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/content_question/content_question.json b/erpnext/education/doctype/content_question/content_question.json
new file mode 100644
index 0000000..d390e8e
--- /dev/null
+++ b/erpnext/education/doctype/content_question/content_question.json
@@ -0,0 +1,76 @@
+{
+ "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-10-15 14:35:40.728454", 
+ "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": "question_link", 
+   "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": "Question Link", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Question", 
+   "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
+  }
+ ], 
+ "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-10-15 14:41:31.729083", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Content Question", 
+ "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/education/doctype/content_question/content_question.py b/erpnext/education/doctype/content_question/content_question.py
new file mode 100644
index 0000000..b239d21
--- /dev/null
+++ b/erpnext/education/doctype/content_question/content_question.py
@@ -0,0 +1,10 @@
+# -*- 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.model.document import Document
+
+class ContentQuestion(Document):
+	pass
diff --git a/erpnext/education/doctype/content_question/test_content_question.js b/erpnext/education/doctype/content_question/test_content_question.js
new file mode 100644
index 0000000..cc869a8
--- /dev/null
+++ b/erpnext/education/doctype/content_question/test_content_question.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: Content Question", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Content Question
+		() => frappe.tests.make('Content Question', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/content_question/test_content_question.py b/erpnext/education/doctype/content_question/test_content_question.py
new file mode 100644
index 0000000..268b9be
--- /dev/null
+++ b/erpnext/education/doctype/content_question/test_content_question.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestContentQuestion(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/course/course.json b/erpnext/education/doctype/course/course.json
index 15360f8..072e8b4 100644
--- a/erpnext/education/doctype/course/course.json
+++ b/erpnext/education/doctype/course/course.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 1, 
@@ -15,10 +16,12 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "course_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -41,14 +44,17 @@
    "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "department", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -72,14 +78,17 @@
    "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "parent_course", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -102,14 +111,17 @@
    "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "column_break_3", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -131,14 +143,17 @@
    "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "course_code", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -161,14 +176,17 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "unique": 0
+   "translatable": 0, 
+   "unique": 1
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "course_abbreviation", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -191,14 +209,17 @@
    "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_6", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -220,16 +241,53 @@
    "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "topics", 
+   "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": "Topics", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Course Topic", 
+   "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "course_intro", 
-   "fieldtype": "Text Editor", 
+   "fieldtype": "Small Text", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -250,14 +308,50 @@
    "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "hero_image", 
+   "fieldtype": "Attach Image", 
+   "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": "Hero Image", 
+   "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "assessment", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -280,14 +374,17 @@
    "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "default_grading_scale", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -311,14 +408,17 @@
    "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "assessment_criteria", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -342,21 +442,20 @@
    "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, 
  "menu_index": 0, 
- "modified": "2017-11-10 19:06:28.909585", 
+ "modified": "2019-04-09 11:35:27.354877", 
  "modified_by": "Administrator", 
  "module": "Education", 
  "name": "Course", 
@@ -365,7 +464,6 @@
  "permissions": [
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 1, 
    "delete": 1, 
@@ -385,7 +483,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 1, 
    "delete": 1, 
@@ -397,7 +494,7 @@
    "print": 1, 
    "read": 1, 
    "report": 1, 
-   "role": "HR Manager", 
+   "role": "Instructor", 
    "set_user_permissions": 0, 
    "share": 1, 
    "submit": 0, 
@@ -406,12 +503,12 @@
  ], 
  "quick_entry": 0, 
  "read_only": 0, 
- "read_only_onload": 0, 
  "restrict_to_domain": "Education", 
  "search_fields": "course_name", 
  "show_name_in_global_search": 1, 
  "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/education/doctype/course/course.py b/erpnext/education/doctype/course/course.py
index 69d2fca..987823a 100644
--- a/erpnext/education/doctype/course/course.py
+++ b/erpnext/education/doctype/course/course.py
@@ -10,7 +10,7 @@
 class Course(Document):
 	def validate(self):
 		self.validate_assessment_criteria()
-	
+
 	def validate_assessment_criteria(self):
 		if self.assessment_criteria:
 			total_weightage = 0
@@ -18,3 +18,11 @@
 				total_weightage += criteria.weightage or 0
 			if total_weightage != 100:
 				frappe.throw(_("Total Weightage of all Assessment Criteria must be 100%"))
+
+	def get_topics(self):
+		try:
+			topic_list = self.get_all_children()
+			topic_data = [frappe.get_doc("Topic", topic.topic) for topic in topic_list]
+		except frappe.DoesNotExistError:
+			return None
+		return topic_data
\ No newline at end of file
diff --git a/erpnext/education/doctype/course/test_course.py b/erpnext/education/doctype/course/test_course.py
index b18f4a9..a24ba8a 100644
--- a/erpnext/education/doctype/course/test_course.py
+++ b/erpnext/education/doctype/course/test_course.py
@@ -2,6 +2,7 @@
 # Copyright (c) 2015, Frappe Technologies and Contributors
 # See license.txt
 from __future__ import unicode_literals
+from erpnext.education.doctype.topic.test_topic import make_topic
 
 import frappe
 import unittest
@@ -9,4 +10,35 @@
 # test_records = frappe.get_test_records('Course')
 
 class TestCourse(unittest.TestCase):
-	pass
+	def setUp(self):
+		make_course_and_linked_topic("_Test Course 1", ["_Test Topic 1", "_Test Topic 2"])
+
+	def test_get_topics(self):
+		course = frappe.get_doc("Course", "_Test Course 1")
+		topics = course.get_topics()
+		self.assertEqual(topics[0].name, "_Test Topic 1")
+		self.assertEqual(topics[1].name, "_Test Topic 2")
+		frappe.db.rollback()
+
+def make_course(name):
+	try:
+		course = frappe.get_doc("Course", name)
+	except frappe.DoesNotExistError:
+		course = frappe.get_doc({
+			"doctype": "Course",
+			"course_name": name,
+			"course_code": name
+		}).insert()
+	return course.name
+
+def make_course_and_linked_topic(course_name, topic_name_list):
+	try:
+		course = frappe.get_doc("Course", course_name)
+	except frappe.DoesNotExistError:
+		make_course(course_name)
+		course = frappe.get_doc("Course", course_name)
+	topic_list = [make_topic(topic_name) for topic_name in topic_name_list]
+	for topic in topic_list:
+		course.append("topics", {"topic": topic})
+	course.save()
+	return course
diff --git a/erpnext/education/doctype/course_activity/__init__.py b/erpnext/education/doctype/course_activity/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/course_activity/__init__.py
diff --git a/erpnext/education/doctype/course_activity/course_activity.js b/erpnext/education/doctype/course_activity/course_activity.js
new file mode 100644
index 0000000..5115fc4
--- /dev/null
+++ b/erpnext/education/doctype/course_activity/course_activity.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Course Activity', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/course_activity/course_activity.json b/erpnext/education/doctype/course_activity/course_activity.json
new file mode 100644
index 0000000..99ae9ae
--- /dev/null
+++ b/erpnext/education/doctype/course_activity/course_activity.json
@@ -0,0 +1,301 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "format:EDU-CA-{YYYY}-{#####}",
+ "beta": 1,
+ "creation": "2018-10-01 17:35:54.391413",
+ "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": "enrollment",
+   "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": "Enrollment",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Course Enrollment",
+   "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": 1,
+   "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": "enrollment.course",
+   "fieldname": "course",
+   "fieldtype": "Data",
+   "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": "Course",
+   "length": 0,
+   "no_copy": 0,
+   "options": "",
+   "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": 1,
+   "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": "enrollment.student",
+   "fieldname": "student",
+   "fieldtype": "Data",
+   "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": "Student",
+   "length": 0,
+   "no_copy": 0,
+   "options": "",
+   "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": 1,
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "content_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": "Content Type",
+   "length": 0,
+   "no_copy": 0,
+   "options": "\nArticle\nVideo",
+   "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": 1,
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "content",
+   "fieldtype": "Dynamic 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": "Content",
+   "length": 0,
+   "no_copy": 0,
+   "options": "content_type",
+   "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": 1,
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "activity_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": "Activity 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": 1,
+   "search_index": 0,
+   "set_only_once": 1,
+   "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-12-06 11:53:08.006123",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Course Activity",
+ "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": "Academics User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 1,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 1,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "LMS User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Instructor",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  }
+ ],
+ "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/education/doctype/course_activity/course_activity.py b/erpnext/education/doctype/course_activity/course_activity.py
new file mode 100644
index 0000000..054b192
--- /dev/null
+++ b/erpnext/education/doctype/course_activity/course_activity.py
@@ -0,0 +1,19 @@
+# -*- 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.model.document import Document
+
+class CourseActivity(Document):
+	def validate(self):
+		self.check_if_enrolled()
+
+
+	def check_if_enrolled(self):
+		if frappe.db.exists("Course Enrollment", self.enrollment):
+			return True
+		else:
+			frappe.throw(_("Course Enrollment {0} does not exists".format(self.enrollment)))
\ No newline at end of file
diff --git a/erpnext/education/doctype/course_activity/test_course_activity.js b/erpnext/education/doctype/course_activity/test_course_activity.js
new file mode 100644
index 0000000..c89c89e
--- /dev/null
+++ b/erpnext/education/doctype/course_activity/test_course_activity.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: Course Activity", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Course Activity
+		() => frappe.tests.make('Course Activity', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/course_activity/test_course_activity.py b/erpnext/education/doctype/course_activity/test_course_activity.py
new file mode 100644
index 0000000..5269a6b
--- /dev/null
+++ b/erpnext/education/doctype/course_activity/test_course_activity.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestCourseActivity(unittest.TestCase):
+	pass
+
+def make_course_activity(enrollment, content_type, content):
+	activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content})
+	try:
+		activity = frappe.get_doc("Course Activity", activity[0]['name'])
+	except (IndexError, frappe.DoesNotExistError):
+		activity = frappe.get_doc({
+			"doctype": "Course Activity",
+			"enrollment": enrollment,
+			"content_type": content_type,
+			"content": content,
+			"activity_date": frappe.utils.datetime.datetime.now()
+		}).insert()
+	return activity
diff --git a/erpnext/education/doctype/course_content/__init__.py b/erpnext/education/doctype/course_content/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/course_content/__init__.py
diff --git a/erpnext/education/doctype/course_content/course_content.js b/erpnext/education/doctype/course_content/course_content.js
new file mode 100644
index 0000000..b9faf99
--- /dev/null
+++ b/erpnext/education/doctype/course_content/course_content.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Course Content', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/course_content/course_content.json b/erpnext/education/doctype/course_content/course_content.json
new file mode 100644
index 0000000..378e560
--- /dev/null
+++ b/erpnext/education/doctype/course_content/course_content.json
@@ -0,0 +1,142 @@
+{
+ "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-10-01 13:04:09.313771", 
+ "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, 
+   "fetch_from": "", 
+   "fieldname": "content_type", 
+   "fieldtype": "Select", 
+   "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": "Content Type", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "\nArticle\nVideo\nQuiz", 
+   "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_2", 
+   "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, 
+   "label": "", 
+   "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": "content", 
+   "fieldtype": "Dynamic 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": "Content", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "content_type", 
+   "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
+  }
+ ], 
+ "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-10-17 07:36:04.029818", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Course Content", 
+ "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/education/doctype/course_content/course_content.py b/erpnext/education/doctype/course_content/course_content.py
new file mode 100644
index 0000000..0d2f85a
--- /dev/null
+++ b/erpnext/education/doctype/course_content/course_content.py
@@ -0,0 +1,10 @@
+# -*- 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.model.document import Document
+
+class CourseContent(Document):
+	pass
diff --git a/erpnext/education/doctype/course_content/test_course_content.js b/erpnext/education/doctype/course_content/test_course_content.js
new file mode 100644
index 0000000..786e67e
--- /dev/null
+++ b/erpnext/education/doctype/course_content/test_course_content.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: Course Content", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Course Content
+		() => frappe.tests.make('Course Content', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/course_content/test_course_content.py b/erpnext/education/doctype/course_content/test_course_content.py
new file mode 100644
index 0000000..9be4b1f
--- /dev/null
+++ b/erpnext/education/doctype/course_content/test_course_content.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestCourseContent(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/course_enrollment/__init__.py b/erpnext/education/doctype/course_enrollment/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/course_enrollment/__init__.py
diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.js b/erpnext/education/doctype/course_enrollment/course_enrollment.js
new file mode 100644
index 0000000..b5d3cc5
--- /dev/null
+++ b/erpnext/education/doctype/course_enrollment/course_enrollment.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Course Enrollment', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.json b/erpnext/education/doctype/course_enrollment/course_enrollment.json
new file mode 100644
index 0000000..6286ec1
--- /dev/null
+++ b/erpnext/education/doctype/course_enrollment/course_enrollment.json
@@ -0,0 +1,233 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "format:EDU-CE-{YYYY}-{#####}",
+ "beta": 1,
+ "creation": "2018-10-15 15:35:39.375161",
+ "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": "program_enrollment",
+   "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": "Program Enrollment",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Program Enrollment",
+   "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": 1,
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "student",
+   "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": 1,
+   "label": "Student",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Student",
+   "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": 1,
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "course",
+   "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": "Course",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Course",
+   "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": 1,
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "enrollment_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": "Enrollment 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": 1,
+   "search_index": 0,
+   "set_only_once": 1,
+   "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-11-25 18:59:01.742377",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Course Enrollment",
+ "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": "Academics User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 1,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "LMS User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Instructor",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  }
+ ],
+ "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/education/doctype/course_enrollment/course_enrollment.py b/erpnext/education/doctype/course_enrollment/course_enrollment.py
new file mode 100644
index 0000000..9508636
--- /dev/null
+++ b/erpnext/education/doctype/course_enrollment/course_enrollment.py
@@ -0,0 +1,76 @@
+# -*- 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.model.document import Document
+from functools import reduce
+
+class CourseEnrollment(Document):
+	def get_progress(self, student):
+		"""
+		Returns Progress of given student for a particular course enrollment
+
+			:param self: Course Enrollment Object
+			:param student: Student Object
+		"""
+		course = frappe.get_doc('Course', self.course)
+		topics = course.get_topics()
+		progress = []
+		for topic in topics:
+			progress.append(student.get_topic_progress(self.name, topic))
+		return reduce(lambda x,y: x+y, progress) # Flatten out the List
+
+	def validate_duplication(self):
+		enrollment = frappe.get_all("Course Enrollment", filters={
+			"student": self.student,
+			"course": self.course,
+			"program_enrollment": self.program_enrollment
+		})
+		if enrollment:
+			frappe.throw(_("Student is already enrolled."))
+
+	def add_quiz_activity(self, quiz_name, quiz_response,answers, score, status):
+		result = {k: ('Correct' if v else 'Wrong') for k,v in answers.items()}
+		result_data = []
+		for key in answers:
+			item = {}
+			item['question'] = key
+			item['quiz_result'] = result[key]
+			try:
+				if isinstance(quiz_response[key], list):
+					item['selected_option'] = ', '.join(frappe.get_value('Options', res, 'option') for res in quiz_response[key])
+				else:
+					item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option')
+			except KeyError:
+				item['selected_option'] = "Unattempted"
+			result_data.append(item)
+
+		quiz_activity = frappe.get_doc({
+			"doctype": "Quiz Activity",
+			"enrollment": self.name,
+			"quiz": quiz_name,
+			"activity_date": frappe.utils.datetime.datetime.now(),
+			"result": result_data,
+			"score": score,
+			"status": status
+			}).insert()
+
+	def add_activity(self, content_type, content):
+		if check_activity_exists(self.name, content_type, content):
+			pass
+		else:
+			activity = frappe.get_doc({
+				"doctype": "Course Activity",
+				"enrollment": self.name,
+				"content_type": content_type,
+				"content": content,
+				"activity_date": frappe.utils.datetime.datetime.now()
+				})
+			activity.insert()
+
+def check_activity_exists(enrollment, content_type, content):
+	activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content})
+	return bool(activity)
\ No newline at end of file
diff --git a/erpnext/education/doctype/course_enrollment/test_course_enrollment.js b/erpnext/education/doctype/course_enrollment/test_course_enrollment.js
new file mode 100644
index 0000000..216cc30
--- /dev/null
+++ b/erpnext/education/doctype/course_enrollment/test_course_enrollment.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: Course Enrollment", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Course Enrollment
+		() => frappe.tests.make('Course Enrollment', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/course_enrollment/test_course_enrollment.py b/erpnext/education/doctype/course_enrollment/test_course_enrollment.py
new file mode 100644
index 0000000..5ecace2
--- /dev/null
+++ b/erpnext/education/doctype/course_enrollment/test_course_enrollment.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+
+from erpnext.education.doctype.student.test_student import create_student
+from erpnext.education.doctype.student.test_student import get_student
+from erpnext.education.doctype.program.test_program import setup_program
+from erpnext.education.doctype.course_activity.test_course_activity import make_course_activity
+
+class TestCourseEnrollment(unittest.TestCase):
+	def setUp(self):
+		setup_program()
+		student = create_student({"first_name": "_Test First", "last_name": "_Test Last", "email": "_test_student_1@example.com"})
+		program_enrollment = student.enroll_in_program("_Test Program")
+		course_enrollment = student.enroll_in_course("_Test Course 1", program_enrollment.name)
+		make_course_activity(course_enrollment.name, "Article", "_Test Article 1-1")
+
+	def test_get_progress(self):
+		student = get_student("_test_student_1@example.com")
+		program_enrollment_name = frappe.get_list("Program Enrollment", filters={"student": student.name, "Program": "_Test Program"})[0].name
+		course_enrollment_name = frappe.get_list("Course Enrollment", filters={"student": student.name, "course": "_Test Course 1", "program_enrollment": program_enrollment_name})[0].name
+		course_enrollment = frappe.get_doc("Course Enrollment", course_enrollment_name)
+		progress = course_enrollment.get_progress(student)
+		finished = {'content': '_Test Article 1-1', 'content_type': 'Article', 'is_complete': True}
+		self.assertTrue(finished in progress)
+		frappe.db.rollback()
+
+
+
diff --git a/erpnext/education/doctype/course_topic/__init__.py b/erpnext/education/doctype/course_topic/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/course_topic/__init__.py
diff --git a/erpnext/education/doctype/course_topic/course_topic.js b/erpnext/education/doctype/course_topic/course_topic.js
new file mode 100644
index 0000000..7d03ba3
--- /dev/null
+++ b/erpnext/education/doctype/course_topic/course_topic.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Course Topic', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/course_topic/course_topic.json b/erpnext/education/doctype/course_topic/course_topic.json
new file mode 100644
index 0000000..3fcddc1
--- /dev/null
+++ b/erpnext/education/doctype/course_topic/course_topic.json
@@ -0,0 +1,109 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-12-12 11:51:25.952740",
+ "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": "topic",
+   "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": "Topic",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Topic",
+   "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,
+   "fetch_from": "topic.topic_name",
+   "fieldname": "topic_name",
+   "fieldtype": "Data",
+   "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": "Topic 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": 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-12-12 13:01:58.960425",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Course Topic",
+ "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/education/doctype/course_topic/course_topic.py b/erpnext/education/doctype/course_topic/course_topic.py
new file mode 100644
index 0000000..2364f17
--- /dev/null
+++ b/erpnext/education/doctype/course_topic/course_topic.py
@@ -0,0 +1,10 @@
+# -*- 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.model.document import Document
+
+class CourseTopic(Document):
+	pass
diff --git a/erpnext/education/doctype/course_topic/test_course_topic.js b/erpnext/education/doctype/course_topic/test_course_topic.js
new file mode 100644
index 0000000..d8d154f
--- /dev/null
+++ b/erpnext/education/doctype/course_topic/test_course_topic.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: Course Topic", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Course Topic
+		() => frappe.tests.make('Course Topic', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/course_topic/test_course_topic.py b/erpnext/education/doctype/course_topic/test_course_topic.py
new file mode 100644
index 0000000..7ce46d2
--- /dev/null
+++ b/erpnext/education/doctype/course_topic/test_course_topic.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestCourseTopic(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/education_settings/education_settings.json b/erpnext/education/doctype/education_settings/education_settings.json
index c1eaa11..3be4988 100644
--- a/erpnext/education/doctype/education_settings/education_settings.json
+++ b/erpnext/education/doctype/education_settings/education_settings.json
@@ -1,359 +1,492 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2017-04-05 13:33:04.519313", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-04-05 13:33:04.519313",
+ "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": "current_academic_year", 
-   "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": "Current Academic Year", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Academic Year", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "current_academic_year",
+   "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": "Current Academic Year",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Academic Year",
+   "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": "current_academic_term", 
-   "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": "Current Academic Term", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Academic Term", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "current_academic_term",
+   "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": "Current Academic Term",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Academic Term",
+   "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": "attendance_freeze_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": "Attendance Freeze 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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "attendance_freeze_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": "Attendance Freeze 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_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, 
+   "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_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "description": "For Batch based Student Group, the Student Batch will be validated for every Student from the Program Enrollment.", 
-   "fieldname": "validate_batch", 
-   "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": "Validate Batch for Students in Student Group", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "description": "For Batch based Student Group, the Student Batch will be validated for every Student from the Program Enrollment.",
+   "fieldname": "validate_batch",
+   "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": "Validate Batch for Students in Student Group",
+   "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, 
-   "description": "For Course based Student Group, the Course will be validated for every Student from the enrolled Courses in Program Enrollment.", 
-   "fieldname": "validate_course", 
-   "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": "Validate Enrolled Course for Students in Student Group", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "description": "For Course based Student Group, the Course will be validated for every Student from the enrolled Courses in Program Enrollment.",
+   "fieldname": "validate_course",
+   "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": "Validate Enrolled Course for Students in Student Group",
+   "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, 
-   "default": "0", 
-   "description": "If enabled, field Academic Term will be Mandatory in Program Enrollment Tool.", 
-   "fieldname": "academic_term_reqd", 
-   "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": "Make Academic Term Mandatory", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "default": "0",
+   "description": "If enabled, field Academic Term will be Mandatory in Program Enrollment Tool.",
+   "fieldname": "academic_term_reqd",
+   "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": "Make Academic Term Mandatory",
+   "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": "section_break_7", 
-   "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, 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "section_break_7",
+   "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,
+   "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, 
-   "default": "Full Name", 
-   "fieldname": "instructor_created_by", 
-   "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": "Instructor Records to be created by", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Full Name\nNaming Series\nEmployee Number", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "default": "Full Name",
+   "fieldname": "instructor_created_by",
+   "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": "Instructor Records to be created by",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Full Name\nNaming Series\nEmployee Number",
+   "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": "web_academy_settings_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": "LMS Settings",
+   "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": "portal_title",
+   "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": "Portal Title",
+   "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": "description",
+   "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": "Description",
+   "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": 1, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-07-26 04:43:35.406690", 
- "modified_by": "Administrator", 
- "module": "Education", 
- "name": "Education Settings", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 1,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-12-11 15:49:15.045116",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Education Settings",
+ "name_case": "",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 0, 
-   "role": "System Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "amend": 0,
+   "cancel": 0,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 0,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 0,
+   "role": "System Manager",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
    "write": 1
-  }, 
+  },
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 0, 
-   "role": "Education Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "amend": 0,
+   "cancel": 0,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 0,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 0,
+   "role": "Education Manager",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
    "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 0,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 0,
+   "role": "Guest",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
   }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Education", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Education",
+ "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/education/doctype/options/__init__.py b/erpnext/education/doctype/options/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/options/__init__.py
diff --git a/erpnext/education/doctype/options/options.json b/erpnext/education/doctype/options/options.json
new file mode 100644
index 0000000..59deab7
--- /dev/null
+++ b/erpnext/education/doctype/options/options.json
@@ -0,0 +1,107 @@
+{
+ "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-10-15 14:05:28.601274", 
+ "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": "option", 
+   "fieldtype": "Small Text", 
+   "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": "Option", 
+   "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": "is_correct", 
+   "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": "Is Correct", 
+   "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-10-15 14:16:18.303156", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Options", 
+ "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/education/doctype/options/options.py b/erpnext/education/doctype/options/options.py
new file mode 100644
index 0000000..a11d77a
--- /dev/null
+++ b/erpnext/education/doctype/options/options.py
@@ -0,0 +1,10 @@
+# -*- 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.model.document import Document
+
+class Options(Document):
+	pass
diff --git a/erpnext/education/doctype/program/program.js b/erpnext/education/doctype/program/program.js
index 5146a19..98263b5 100644
--- a/erpnext/education/doctype/program/program.js
+++ b/erpnext/education/doctype/program/program.js
@@ -4,40 +4,5 @@
 cur_frm.add_fetch('fee_structure', 'total_amount', 'amount');
 
 frappe.ui.form.on("Program", "refresh", function(frm) {
-	if(!frm.doc.__islocal) {
-		frm.add_custom_button(__("Student Applicant"), function() {
-			frappe.route_options = {
-				program: frm.doc.name
-			}
-			frappe.set_route("List", "Student Applicant");
-		});
-		
-		frm.add_custom_button(__("Program Enrollment"), function() {
-			frappe.route_options = {
-				program: frm.doc.name
-			}
-			frappe.set_route("List", "Program Enrollment");
-		});
-		
-		frm.add_custom_button(__("Student Group"), function() {
-			frappe.route_options = {
-				program: frm.doc.name
-			}
-			frappe.set_route("List", "Student Group");
-		});
-		
-		frm.add_custom_button(__("Fee Structure"), function() {
-			frappe.route_options = {
-				program: frm.doc.name
-			}
-			frappe.set_route("List", "Fee Structure");
-		});
-		
-		frm.add_custom_button(__("Fees"), function() {
-			frappe.route_options = {
-				program: frm.doc.name
-			}
-			frappe.set_route("List", "Fees");
-		});
-	}
+	
 });
\ No newline at end of file
diff --git a/erpnext/education/doctype/program/program.json b/erpnext/education/doctype/program/program.json
index 05e35a2..cb8d778 100644
--- a/erpnext/education/doctype/program/program.json
+++ b/erpnext/education/doctype/program/program.json
@@ -1,277 +1,627 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:program_code", 
- "beta": 0, 
- "creation": "2015-09-07 12:54:03.609282", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 0, 
- "engine": "InnoDB", 
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:program_code",
+ "beta": 0,
+ "creation": "2015-09-07 12:54:03.609282",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 0,
+ "engine": "InnoDB",
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "program_name", 
-   "fieldtype": "Data", 
-   "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": "Program 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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "program_name",
+   "fieldtype": "Data",
+   "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": "Program 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": 1,
+   "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": "department", 
-   "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": "Department", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Department", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "department",
+   "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": "Department",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Department",
+   "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": "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 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_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "program_code", 
-   "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": "Program Code", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "program_code",
+   "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": "Program Code",
+   "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": 1
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "program_abbreviation",
+   "fieldtype": "Data",
+   "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": "Program Abbreviation",
+   "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": "program_abbreviation", 
-   "fieldtype": "Data", 
-   "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": "Program Abbreviation", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "depends_on": "",
+   "fetch_if_empty": 0,
+   "fieldname": "section_break_5",
+   "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": "Portal Settings",
+   "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": "section_break_5", 
-   "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": "Course", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "courses",
+   "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": "Courses",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Program Course",
+   "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": "courses", 
-   "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": "Courses", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Program Course", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "section_break_9",
+   "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,
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "description",
+   "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": "Description",
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "intro_video",
+   "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": "Intro Video",
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "hero_image",
+   "fieldtype": "Attach Image",
+   "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": "Hero Image",
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "column_break_11",
+   "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": "0",
+   "fetch_if_empty": 0,
+   "fieldname": "is_published",
+   "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": "Is Published",
+   "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",
+   "fetch_if_empty": 0,
+   "fieldname": "is_featured",
+   "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": "Is Featured",
+   "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": 0, 
- "max_attachments": 0, 
- "menu_index": 0, 
- "modified": "2017-11-10 18:56:18.413911", 
- "modified_by": "Administrator", 
- "module": "Education", 
- "name": "Program", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "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,
+ "menu_index": 0,
+ "modified": "2019-03-18 15:26:56.737903",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Program",
+ "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": "Academics User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "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": "Academics User",
+   "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": "Instructor",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Guest",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "LMS User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Student",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  },
+  {
+   "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": "System Manager",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Education", 
- "search_fields": "program_name", 
- "show_name_in_global_search": 1, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 0, 
- "track_seen": 0
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Education",
+ "route": "",
+ "search_fields": "program_name",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 0,
+ "track_seen": 0,
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/education/doctype/program/program.py b/erpnext/education/doctype/program/program.py
index f626880..dbeda40 100644
--- a/erpnext/education/doctype/program/program.py
+++ b/erpnext/education/doctype/program/program.py
@@ -7,4 +7,8 @@
 from frappe.model.document import Document
 
 class Program(Document):
-	pass
\ No newline at end of file
+
+	def get_course_list(self):
+		program_course_list = self.get_all_children()
+		course_list = [frappe.get_doc("Course", program_course.course) for program_course in program_course_list]
+		return course_list
\ No newline at end of file
diff --git a/erpnext/education/doctype/program/program_dashboard.py b/erpnext/education/doctype/program/program_dashboard.py
new file mode 100644
index 0000000..cb8f742
--- /dev/null
+++ b/erpnext/education/doctype/program/program_dashboard.py
@@ -0,0 +1,20 @@
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'program',
+		'transactions': [
+			{
+				'label': _('Admission and Enrollment'),
+				'items': ['Student Applicant', 'Program Enrollment']
+			},
+			{
+				'label': _('Student Activity'),
+				'items': ['Student Group' ]
+			},
+			{
+				'label': _('Fee'),
+				'items': ['Fees','Fee Structure']
+			}
+		]
+	}
\ No newline at end of file
diff --git a/erpnext/education/doctype/program/test_program.py b/erpnext/education/doctype/program/test_program.py
index a4accda..3bcca3a 100644
--- a/erpnext/education/doctype/program/test_program.py
+++ b/erpnext/education/doctype/program/test_program.py
@@ -2,11 +2,85 @@
 # Copyright (c) 2015, Frappe Technologies and Contributors
 # See license.txt
 from __future__ import unicode_literals
+from erpnext.education.doctype.course.test_course import make_course
+from erpnext.education.doctype.topic.test_topic import make_topic_and_linked_content
+from erpnext.education.doctype.course.test_course import make_course_and_linked_topic
 
 import frappe
 import unittest
 
-# test_records = frappe.get_test_records('Program')
+test_data = {
+	"program_name": "_Test Program",
+	"description": "_Test Program",
+	"course": [{
+		"course_name": "_Test Course 1",
+		"topic": [{
+				"topic_name": "_Test Topic 1-1",
+				"content": [{
+					"type": "Article",
+					"name": "_Test Article 1-1"
+				}, {
+					"type": "Article",
+					"name": "_Test Article 1-2"
+				}]
+			},
+			{
+				"topic_name": "_Test Topic 1-2",
+				"content": [{
+					"type": "Article",
+					"name": "_Test Article 1-3"
+				}, {
+					"type": "Article",
+					"name": "_Test Article 1-4"
+				}]
+			}
+		]
+	}]
+}
 
 class TestProgram(unittest.TestCase):
-	pass
+	def setUp(self):
+		make_program_and_linked_courses("_Test Program 1", ["_Test Course 1", "_Test Course 2"])
+
+	def test_get_course_list(self):
+		program = frappe.get_doc("Program", "_Test Program 1")
+		course = program.get_course_list()
+		self.assertEqual(course[0].name, "_Test Course 1")
+		self.assertEqual(course[1].name, "_Test Course 2")
+		frappe.db.rollback()
+
+def make_program(name):
+	program = frappe.get_doc({
+		"doctype": "Program",
+		"program_name": name,
+		"program_code": name,
+		"description": "_test description",
+		"is_published": True,
+		"is_featured": True,
+	}).insert()
+	return program.name
+
+def make_program_and_linked_courses(program_name, course_name_list):
+	try:
+		program = frappe.get_doc("Program", program_name)
+	except frappe.DoesNotExistError:
+		make_program(program_name)
+		program = frappe.get_doc("Program", program_name)
+	course_list = [make_course(course_name) for course_name in course_name_list]
+	for course in course_list:
+		program.append("courses", {"course": course})
+	program.save()
+	return program
+
+def setup_program():
+	topic_list = [course['topic'] for course in test_data['course']]
+	for topic in topic_list[0]:
+		make_topic_and_linked_content(topic['topic_name'], topic['content'])
+
+	all_courses_list = [{'course': course['course_name'], 'topic': [topic['topic_name'] for topic in course['topic']]} for course in test_data['course']] # returns [{'course': 'Applied Math', 'topic': ['Trignometry', 'Geometry']}]
+	for course in all_courses_list:
+		make_course_and_linked_topic(course['course'], course['topic'])
+
+	course_list = [course['course_name'] for course in test_data['course']]
+	program = make_program_and_linked_courses(test_data['program_name'], course_list)
+	return program
\ No newline at end of file
diff --git a/erpnext/education/doctype/program/test_records.json b/erpnext/education/doctype/program/test_records.json
index e5eda70..7901db3 100644
--- a/erpnext/education/doctype/program/test_records.json
+++ b/erpnext/education/doctype/program/test_records.json
@@ -1,12 +1,14 @@
 [
 	{
-		"program_name": "_Test Program",
+		"program_name": "_Test Program 1",
 		"program_code": "_TP1",
+		"description": "Test Description",
 		"program_abbreviation": "TP1"
 	},
 	{
 		"program_name": "_Test Program 2",
 		"program_code": "_TP2",
+		"description": "Test Description",
 		"program_abbreviation": "TP2"
 	}
-]
+]
\ No newline at end of file
diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.json b/erpnext/education/doctype/program_enrollment/program_enrollment.json
index 5f4621f..1d8a434 100644
--- a/erpnext/education/doctype/program_enrollment/program_enrollment.json
+++ b/erpnext/education/doctype/program_enrollment/program_enrollment.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 0, 
@@ -714,7 +715,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-08-21 16:15:35.014952", 
+ "modified": "2018-11-07 21:13:06.502279", 
  "modified_by": "Administrator", 
  "module": "Education", 
  "name": "Program Enrollment", 
@@ -739,6 +740,25 @@
    "share": 1, 
    "submit": 1, 
    "write": 1
+  }, 
+  {
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 0, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "LMS User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
   }
  ], 
  "quick_entry": 0, 
diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.py b/erpnext/education/doctype/program_enrollment/program_enrollment.py
index 320a58a..22cca86 100644
--- a/erpnext/education/doctype/program_enrollment/program_enrollment.py
+++ b/erpnext/education/doctype/program_enrollment/program_enrollment.py
@@ -8,6 +8,7 @@
 from frappe.model.document import Document
 from frappe.desk.reportview import get_match_cond, get_filters_cond
 from frappe.utils import comma_and
+import erpnext.www.lms as lms
 
 class ProgramEnrollment(Document):
 	def validate(self):
@@ -16,11 +17,12 @@
 			self.student_name = frappe.db.get_value("Student", self.student, "title")
 		if not self.courses:
 			self.extend("courses", self.get_courses())
-	
+
 	def on_submit(self):
 		self.update_student_joining_date()
 		self.make_fee_records()
-	
+		self.create_course_enrollments()
+
 	def validate_duplication(self):
 		enrollment = frappe.get_all("Program Enrollment", filters={
 			"student": self.student,
@@ -31,11 +33,11 @@
 		})
 		if enrollment:
 			frappe.throw(_("Student is already enrolled."))
-	
+
 	def update_student_joining_date(self):
 		date = frappe.db.sql("select min(enrollment_date) from `tabProgram Enrollment` where student= %s", self.student)
 		frappe.db.set_value("Student", self.student, "joining_date", date)
-		
+
 	def make_fee_records(self):
 		from erpnext.education.api import get_fee_components
 		fee_list = []
@@ -54,7 +56,7 @@
 					"program_enrollment": self.name,
 					"components": fee_components
 				})
-				
+
 				fees.save()
 				fees.submit()
 				fee_list.append(fees.name)
@@ -66,6 +68,56 @@
 	def get_courses(self):
 		return frappe.db.sql('''select course, course_name from `tabProgram Course` where parent = %s and required = 1''', (self.program), as_dict=1)
 
+	def create_course_enrollments(self):
+		student = frappe.get_doc("Student", self.student)
+		program = frappe.get_doc("Program", self.program)
+		course_list = [course.course for course in program.get_all_children()]
+		for course_name in course_list:
+			student.enroll_in_course(course_name=course_name, program_enrollment=self.name)
+
+	def get_all_course_enrollments(self):
+		course_enrollment_names = frappe.get_list("Course Enrollment", filters={'program_enrollment': self.name})
+		return [frappe.get_doc('Course Enrollment', course_enrollment.name) for course_enrollment in course_enrollment_names]
+
+	def get_quiz_progress(self):
+		student = frappe.get_doc("Student", self.student)
+		quiz_progress = frappe._dict()
+		progress_list = []
+		for course_enrollment in self.get_all_course_enrollments():
+			course_progress = course_enrollment.get_progress(student)
+			for progress_item in course_progress:
+				if progress_item['content_type'] == "Quiz":
+					progress_item['course'] = course_enrollment.course
+					progress_list.append(progress_item)
+		if not progress_list:
+			return None
+		quiz_progress.quiz_attempt = progress_list
+		quiz_progress.name = self.program
+		quiz_progress.program = self.program
+		return quiz_progress
+
+	def get_program_progress(self):
+		import math
+		program = frappe.get_doc("Program", self.program)
+		program_progress = {}
+		progress = []
+		for course in program.get_all_children():
+			course_progress = lms.get_student_course_details(course.course, self.program)
+			is_complete = False
+			if course_progress['flag'] == "Completed":
+				is_complete = True
+			progress.append({'course_name': course.course_name, 'name': course.course, 'is_complete': is_complete})
+
+		program_progress['progress'] = progress
+		program_progress['name'] = self.program
+		program_progress['program'] = frappe.get_value("Program", self.program, 'program_name')
+
+		try:
+			program_progress['percentage'] = math.ceil((sum([item['is_complete'] for item in progress] * 100)/len(progress)))
+		except ZeroDivisionError:
+			program_progress['percentage'] = 0
+
+		return program_progress
 
 @frappe.whitelist()
 def get_program_courses(doctype, txt, searchfield, start, page_len, filters):
@@ -102,11 +154,11 @@
 
 	return frappe.db.sql("""select
 			name, title from tabStudent
-		where 
+		where
 			name not in (%s)
-		and 
+		and
 			`%s` LIKE %s
-		order by 
+		order by
 			idx desc, name
 		limit %s, %s"""%(
 			", ".join(['%s']*len(students)), searchfield, "%s", "%s", "%s"),
diff --git a/erpnext/education/doctype/program_enrollment/test_program_enrollment.py b/erpnext/education/doctype/program_enrollment/test_program_enrollment.py
index c26e899..c6cbee1 100644
--- a/erpnext/education/doctype/program_enrollment/test_program_enrollment.py
+++ b/erpnext/education/doctype/program_enrollment/test_program_enrollment.py
@@ -6,7 +6,21 @@
 import frappe
 import unittest
 
-# test_records = frappe.get_test_records('Program Enrollment')
+from erpnext.education.doctype.student.test_student import create_student
+from erpnext.education.doctype.student.test_student import get_student
+from erpnext.education.doctype.program.test_program import make_program_and_linked_courses
+from erpnext.education.doctype.course_activity.test_course_activity import make_course_activity
 
 class TestProgramEnrollment(unittest.TestCase):
-	pass
+
+	def setUp(self):
+		create_student({"first_name": "_Test Name", "last_name": "_Test Last Name", "email": "_test_student@example.com"})
+		make_program_and_linked_courses("_Test Program 1", ["_Test Course 1", "_Test Course 2"])
+
+	def test_create_course_enrollments(self):
+		student = get_student("_test_student@example.com")
+		enrollment = student.enroll_in_program("_Test Program 1")
+		course_enrollments = student.get_all_course_enrollments()
+		self.assertTrue("_Test Course 1" in course_enrollments.keys())
+		self.assertTrue("_Test Course 2" in course_enrollments.keys())
+		frappe.db.rollback()
\ No newline at end of file
diff --git a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py b/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py
index db23ac7..9f8f9f4 100644
--- a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py
+++ b/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py
@@ -48,7 +48,7 @@
 			return students
 		else:
 			frappe.throw(_("No students Found"))
-			
+
 	def enroll_students(self):
 		total = len(self.students)
 		for i, stud in enumerate(self.students):
diff --git a/erpnext/education/doctype/question/__init__.py b/erpnext/education/doctype/question/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/question/__init__.py
diff --git a/erpnext/education/doctype/question/question.js b/erpnext/education/doctype/question/question.js
new file mode 100644
index 0000000..01b3091
--- /dev/null
+++ b/erpnext/education/doctype/question/question.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Question', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json
new file mode 100644
index 0000000..14a9f3c
--- /dev/null
+++ b/erpnext/education/doctype/question/question.json
@@ -0,0 +1,167 @@
+{
+ "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 1, 
+ "allow_rename": 0, 
+ "autoname": "format:QUESTION-{#####}", 
+ "beta": 0, 
+ "creation": "2018-10-01 15:58:00.696815", 
+ "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "question", 
+   "fieldtype": "Small Text", 
+   "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": "Question", 
+   "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, 
+   "description": "", 
+   "fetch_if_empty": 0, 
+   "fieldname": "options", 
+   "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": "Options", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Options", 
+   "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
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2019-04-22 14:02:08.140652", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Question", 
+ "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": "Academics User", 
+   "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": "Instructor", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 1
+  }, 
+  {
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 0, 
+   "delete": 0, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "LMS User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 0
+  }
+ ], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 0, 
+ "track_seen": 0, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/education/doctype/question/question.py b/erpnext/education/doctype/question/question.py
new file mode 100644
index 0000000..8cd2398
--- /dev/null
+++ b/erpnext/education/doctype/question/question.py
@@ -0,0 +1,38 @@
+# -*- 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.model.document import Document
+
+class Question(Document):
+
+	def validate(self):
+		self.check_at_least_one_option()
+		self.check_minimum_one_correct_answer()
+
+	def check_at_least_one_option(self):
+		if len(self.options) <= 1:
+			frappe.throw(_("A question must have more than one options"))
+		else:
+			pass
+
+	def check_minimum_one_correct_answer(self):
+		correct_options = [option.is_correct for option in self.options]
+		if bool(sum(correct_options)):
+			pass
+		else:
+			frappe.throw(_("A qustion must have at least one correct options"))
+
+	def get_answer(self):
+		options = self.options
+		answers = [item.name for item in options if item.is_correct == True]
+		if len(answers) == 0:
+			frappe.throw("No correct answer is set for {0}".format(self.name))
+			return None
+		elif len(answers) == 1:
+			return answers[0]
+		else:
+			return answers
\ No newline at end of file
diff --git a/erpnext/education/doctype/question/test_question.js b/erpnext/education/doctype/question/test_question.js
new file mode 100644
index 0000000..509939c
--- /dev/null
+++ b/erpnext/education/doctype/question/test_question.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: Question", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Question
+		() => frappe.tests.make('Question', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/question/test_question.py b/erpnext/education/doctype/question/test_question.py
new file mode 100644
index 0000000..552872e
--- /dev/null
+++ b/erpnext/education/doctype/question/test_question.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestQuestion(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/quiz/__init__.py b/erpnext/education/doctype/quiz/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/quiz/__init__.py
diff --git a/erpnext/education/doctype/quiz/quiz.js b/erpnext/education/doctype/quiz/quiz.js
new file mode 100644
index 0000000..122cf37
--- /dev/null
+++ b/erpnext/education/doctype/quiz/quiz.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Quiz', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/quiz/quiz.json b/erpnext/education/doctype/quiz/quiz.json
new file mode 100644
index 0000000..f91bc0f
--- /dev/null
+++ b/erpnext/education/doctype/quiz/quiz.json
@@ -0,0 +1,299 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:title",
+ "beta": 0,
+ "creation": "2018-10-17 05:52:50.149904",
+ "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": "title",
+   "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": "Title",
+   "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": 1
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "question",
+   "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": "Question",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Quiz Question",
+   "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": "quiz_configuration_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": "Quiz Configuration",
+   "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": "passing_score",
+   "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": "Passing Score",
+   "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": "1",
+   "description": "Enter 0 to waive limit",
+   "fieldname": "max_attempts",
+   "fieldtype": "Int",
+   "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": "Max Attempts",
+   "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": "Last Highest Score",
+   "fieldname": "grading_basis",
+   "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": "Grading Basis",
+   "length": 0,
+   "no_copy": 0,
+   "options": "\nLast Attempt\nLast Highest Score",
+   "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-11-25 19:07:36.190116",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Quiz",
+ "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": "Academics User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "LMS User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  },
+  {
+   "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": "Instructor",
+   "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/education/doctype/quiz/quiz.py b/erpnext/education/doctype/quiz/quiz.py
new file mode 100644
index 0000000..6da50a6
--- /dev/null
+++ b/erpnext/education/doctype/quiz/quiz.py
@@ -0,0 +1,64 @@
+# -*- 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.model.document import Document
+
+class Quiz(Document):
+
+	def validate_quiz_attempts(self, enrollment, quiz_name):
+		if self.max_attempts > 0:
+			try:
+				if len(frappe.get_all("Quiz Activity", {'enrollment': enrollment.name, 'quiz': quiz_name})) >= self.max_attempts:
+					frappe.throw('Maximum attempts reached!')
+			except Exception as e:
+				pass
+
+
+	def evaluate(self, response_dict, quiz_name):
+		# self.validate_quiz_attempts(enrollment, quiz_name)
+		questions = [frappe.get_doc('Question', question.question_link) for question in self.question]
+		answers = {q.name:q.get_answer() for q in questions}
+		correct_answers = {}
+		for key in answers:
+			try:
+				if isinstance(response_dict[key], list):
+					result = compare_list_elementwise(response_dict[key], answers[key])
+				else:
+					result = (response_dict[key] == answers[key])
+			except:
+				result = False
+			correct_answers[key] = result
+		score = (sum(correct_answers.values()) * 100 ) / len(answers)
+		if score >= self.passing_score:
+			status = "Pass"
+		else:
+			status = "Fail"
+		return correct_answers, score, status
+
+
+	def get_questions(self):
+		quiz_question = self.get_all_children()
+		if quiz_question:
+			questions = [frappe.get_doc('Question', question.question_link).as_dict() for question in quiz_question]
+			for question in questions:
+				correct_options = [option.is_correct for option in question.options]
+				if sum(correct_options) > 1:
+					question['type'] = "MultipleChoice"
+				else:
+					question['type'] = "SingleChoice"
+			return questions
+		else:
+			return None
+
+def compare_list_elementwise(*args):
+	try:
+		if all(len(args[0]) == len(_arg) for _arg in args[1:]):
+			return all(all([element in (item) for element in args[0]]) for item in args[1:])
+		else:
+			return False
+	except TypeError:
+		frappe.throw("Compare List function takes on list arguments")
+
diff --git a/erpnext/education/doctype/quiz/test_quiz.js b/erpnext/education/doctype/quiz/test_quiz.js
new file mode 100644
index 0000000..147d139
--- /dev/null
+++ b/erpnext/education/doctype/quiz/test_quiz.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: Quiz", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Quiz
+		() => frappe.tests.make('Quiz', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/quiz/test_quiz.py b/erpnext/education/doctype/quiz/test_quiz.py
new file mode 100644
index 0000000..344fd54
--- /dev/null
+++ b/erpnext/education/doctype/quiz/test_quiz.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestQuiz(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/quiz_activity/__init__.py b/erpnext/education/doctype/quiz_activity/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/quiz_activity/__init__.py
diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.js b/erpnext/education/doctype/quiz_activity/quiz_activity.js
new file mode 100644
index 0000000..f6ba12c
--- /dev/null
+++ b/erpnext/education/doctype/quiz_activity/quiz_activity.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Quiz Activity', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.json b/erpnext/education/doctype/quiz_activity/quiz_activity.json
new file mode 100644
index 0000000..e78db42
--- /dev/null
+++ b/erpnext/education/doctype/quiz_activity/quiz_activity.json
@@ -0,0 +1,490 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "format:EDU-QA-{YYYY}-{#####}",
+ "beta": 1,
+ "creation": "2018-10-15 15:48:40.482821",
+ "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": "enrollment",
+   "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": "Enrollment",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Course Enrollment",
+   "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": 1,
+   "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": "enrollment.student",
+   "fieldname": "student",
+   "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": "Student",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Student",
+   "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_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,
+   "fetch_from": "enrollment.course",
+   "fieldname": "course",
+   "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": "Course",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Course",
+   "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": 1,
+   "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",
+   "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": "quiz",
+   "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": "Quiz",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Quiz",
+   "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": 1,
+   "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_7",
+   "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": "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": "\nPass\nFail",
+   "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_9",
+   "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,
+   "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": "result",
+   "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": "Result",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Quiz Result",
+   "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": 1,
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "activity_date",
+   "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": "Activity 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": 1,
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "score",
+   "fieldtype": "Data",
+   "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": "Score",
+   "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": 1,
+   "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-11-25 19:05:52.434437",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Quiz Activity",
+ "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": "Academics User",
+   "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": "LMS User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Instructor",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  }
+ ],
+ "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/education/doctype/quiz_activity/quiz_activity.py b/erpnext/education/doctype/quiz_activity/quiz_activity.py
new file mode 100644
index 0000000..24c7175
--- /dev/null
+++ b/erpnext/education/doctype/quiz_activity/quiz_activity.py
@@ -0,0 +1,10 @@
+# -*- 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.model.document import Document
+
+class QuizActivity(Document):
+	pass
diff --git a/erpnext/education/doctype/quiz_activity/test_quiz_activity.js b/erpnext/education/doctype/quiz_activity/test_quiz_activity.js
new file mode 100644
index 0000000..94b5ab7
--- /dev/null
+++ b/erpnext/education/doctype/quiz_activity/test_quiz_activity.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: Quiz Activity", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Quiz Activity
+		() => frappe.tests.make('Quiz Activity', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/quiz_activity/test_quiz_activity.py b/erpnext/education/doctype/quiz_activity/test_quiz_activity.py
new file mode 100644
index 0000000..fb0425d
--- /dev/null
+++ b/erpnext/education/doctype/quiz_activity/test_quiz_activity.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestQuizActivity(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/quiz_question/__init__.py b/erpnext/education/doctype/quiz_question/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/quiz_question/__init__.py
diff --git a/erpnext/education/doctype/quiz_question/quiz_question.json b/erpnext/education/doctype/quiz_question/quiz_question.json
new file mode 100644
index 0000000..3857c5c
--- /dev/null
+++ b/erpnext/education/doctype/quiz_question/quiz_question.json
@@ -0,0 +1,110 @@
+{
+ "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-10-17 06:13:00.098883", 
+ "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": "question_link", 
+   "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": "Question Link", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Question", 
+   "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, 
+   "fetch_from": "question_link.question", 
+   "fieldname": "question", 
+   "fieldtype": "Data", 
+   "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": "Question", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "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, 
+ "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-10-18 15:35:12.195250", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Quiz Question", 
+ "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/education/doctype/quiz_question/quiz_question.py b/erpnext/education/doctype/quiz_question/quiz_question.py
new file mode 100644
index 0000000..317e75b
--- /dev/null
+++ b/erpnext/education/doctype/quiz_question/quiz_question.py
@@ -0,0 +1,10 @@
+# -*- 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.model.document import Document
+
+class QuizQuestion(Document):
+	pass
diff --git a/erpnext/education/doctype/quiz_result/__init__.py b/erpnext/education/doctype/quiz_result/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/quiz_result/__init__.py
diff --git a/erpnext/education/doctype/quiz_result/quiz_result.js b/erpnext/education/doctype/quiz_result/quiz_result.js
new file mode 100644
index 0000000..a018749
--- /dev/null
+++ b/erpnext/education/doctype/quiz_result/quiz_result.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Quiz Result', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/quiz_result/quiz_result.json b/erpnext/education/doctype/quiz_result/quiz_result.json
new file mode 100644
index 0000000..86505ac
--- /dev/null
+++ b/erpnext/education/doctype/quiz_result/quiz_result.json
@@ -0,0 +1,145 @@
+{
+ "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-10-15 15:52:25.766374", 
+ "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "question", 
+   "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": "Question", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Question", 
+   "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": 1, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "selected_option", 
+   "fieldtype": "Data", 
+   "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": "Selected Option", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "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": 1, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "quiz_result", 
+   "fieldtype": "Select", 
+   "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": "Result", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "\nCorrect\nWrong", 
+   "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": 1, 
+   "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": "2019-03-27 17:58:54.388848", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Quiz Result", 
+ "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/education/doctype/quiz_result/quiz_result.py b/erpnext/education/doctype/quiz_result/quiz_result.py
new file mode 100644
index 0000000..a4fd9f0
--- /dev/null
+++ b/erpnext/education/doctype/quiz_result/quiz_result.py
@@ -0,0 +1,10 @@
+# -*- 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.model.document import Document
+
+class QuizResult(Document):
+	pass
diff --git a/erpnext/education/doctype/quiz_result/test_quiz_result.js b/erpnext/education/doctype/quiz_result/test_quiz_result.js
new file mode 100644
index 0000000..43f53a1
--- /dev/null
+++ b/erpnext/education/doctype/quiz_result/test_quiz_result.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: Quiz Result", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Quiz Result
+		() => frappe.tests.make('Quiz Result', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/quiz_result/test_quiz_result.py b/erpnext/education/doctype/quiz_result/test_quiz_result.py
new file mode 100644
index 0000000..86ee52d
--- /dev/null
+++ b/erpnext/education/doctype/quiz_result/test_quiz_result.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestQuizResult(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/student/student.json b/erpnext/education/doctype/student/student.json
index af6c8b1..bee915e 100644
--- a/erpnext/education/doctype/student/student.json
+++ b/erpnext/education/doctype/student/student.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 1, 
@@ -20,6 +21,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_1", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -52,6 +54,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "default": "1", 
+   "fetch_if_empty": 0, 
    "fieldname": "enabled", 
    "fieldtype": "Check", 
    "hidden": 0, 
@@ -84,6 +87,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_3", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -115,6 +119,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "first_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -147,6 +152,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "middle_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -179,6 +185,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "last_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -211,6 +218,41 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "user", 
+   "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": "User ID", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "User", 
+   "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "column_break_4", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -243,6 +285,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "default": "", 
+   "fetch_if_empty": 0, 
    "fieldname": "naming_series", 
    "fieldtype": "Select", 
    "hidden": 0, 
@@ -276,6 +319,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "student_email_id", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -295,7 +339,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, 
@@ -308,6 +352,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "student_mobile_number", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -342,6 +387,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "default": "Today", 
+   "fetch_if_empty": 0, 
    "fieldname": "joining_date", 
    "fieldtype": "Date", 
    "hidden": 0, 
@@ -374,6 +420,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "image", 
    "fieldtype": "Attach Image", 
    "hidden": 1, 
@@ -408,6 +455,7 @@
    "collapsible": 0, 
    "collapsible_depends_on": "", 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_7", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -440,6 +488,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "date_of_birth", 
    "fieldtype": "Date", 
    "hidden": 0, 
@@ -472,6 +521,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "blood_group", 
    "fieldtype": "Select", 
    "hidden": 0, 
@@ -505,6 +555,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "column_break_3", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -536,6 +587,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "gender", 
    "fieldtype": "Select", 
    "hidden": 0, 
@@ -569,6 +621,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "nationality", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -602,6 +655,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "student_applicant", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -635,6 +689,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_22", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -667,6 +722,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "address_line_1", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -699,6 +755,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "address_line_2", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -731,6 +788,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "pincode", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -763,6 +821,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "column_break_20", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -794,6 +853,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "city", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -826,6 +886,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "state", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -858,6 +919,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_18", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -890,6 +952,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "guardians", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -923,6 +986,7 @@
    "bold": 0, 
    "collapsible": 1, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_20", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -956,6 +1020,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "siblings", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -989,6 +1054,7 @@
    "bold": 0, 
    "collapsible": 1, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "exit", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -1021,6 +1087,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "date_of_leaving", 
    "fieldtype": "Date", 
    "hidden": 0, 
@@ -1053,6 +1120,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "leaving_certificate_number", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -1085,6 +1153,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "column_break_31", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -1116,6 +1185,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "reason_for_leaving", 
    "fieldtype": "Text", 
    "hidden": 0, 
@@ -1149,6 +1219,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "default": "", 
+   "fetch_if_empty": 0, 
    "fieldname": "title", 
    "fieldtype": "Data", 
    "hidden": 1, 
@@ -1176,18 +1247,16 @@
   }
  ], 
  "has_web_view": 0, 
- "hide_heading": 0, 
  "hide_toolbar": 0, 
  "idx": 0, 
  "image_field": "image", 
- "image_view": 0, 
  "in_create": 0, 
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-08-21 14:44:35.278833", 
+ "modified": "2019-04-10 17:46:26.893020", 
  "modified_by": "Administrator", 
  "module": "Education", 
  "name": "Student", 
@@ -1231,11 +1300,48 @@
    "share": 1, 
    "submit": 0, 
    "write": 1
+  }, 
+  {
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 0, 
+   "delete": 0, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Student", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 0
+  }, 
+  {
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 0, 
+   "delete": 0, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "LMS User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 0
   }
  ], 
  "quick_entry": 0, 
  "read_only": 0, 
- "read_only_onload": 0, 
  "restrict_to_domain": "Education", 
  "show_name_in_global_search": 1, 
  "sort_field": "modified", 
diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py
index 53bf6f7..cf8407c 100644
--- a/erpnext/education/doctype/student/student.py
+++ b/erpnext/education/doctype/student/student.py
@@ -7,7 +7,7 @@
 from frappe.model.document import Document
 from frappe import _
 from frappe.desk.form.linked_with import get_linked_doctypes
-
+from erpnext.education.utils import check_content_completion, check_quiz_completion
 class Student(Document):
 	def validate(self):
 		self.title = " ".join(filter(None, [self.first_name, self.middle_name, self.last_name]))
@@ -39,11 +39,99 @@
 		if student:
 			frappe.throw(_("Student {0} exist against student applicant {1}").format(student[0][0], self.student_applicant))
 
+	def after_insert(self):
+		self.create_student_user()
+
+	def create_student_user(self):
+		"""Create a website user for student creation if not already exists"""
+		if not frappe.db.exists("User", self.student_email_id):
+			student_user = frappe.get_doc({
+				'doctype':'User',
+				'first_name': self.first_name,
+				'last_name': self.last_name,
+				'email': self.student_email_id,
+				'gender': self.gender,
+				'send_welcome_email': 1,
+				'user_type': 'Website User'
+				})
+			student_user.add_roles("Student", "LMS User")
+			student_user.save()
+			update_password_link = student_user.reset_password()
+
 	def update_applicant_status(self):
 		"""Updates Student Applicant status to Admitted"""
 		if self.student_applicant:
 			frappe.db.set_value("Student Applicant", self.student_applicant, "application_status", "Admitted")
 
+	def get_all_course_enrollments(self):
+		"""Returns a list of course enrollments linked with the current student"""
+		course_enrollments = frappe.get_all("Course Enrollment", filters={"student": self.name}, fields=['course', 'name'])
+		if not course_enrollments:
+			return None
+		else:
+			enrollments = {item['course']:item['name'] for item in course_enrollments}
+			return enrollments
+
+	def get_program_enrollments(self):
+		"""Returns a list of course enrollments linked with the current student"""
+		program_enrollments = frappe.get_all("Program Enrollment", filters={"student": self.name}, fields=['program'])
+		if not program_enrollments:
+			return None
+		else:
+			enrollments = [item['program'] for item in program_enrollments]
+			return enrollments
+
+	def get_topic_progress(self, course_enrollment_name, topic):
+		"""
+		Get Progress Dictionary of a student for a particular topic
+			:param self: Student Object
+			:param course_enrollment_name: Name of the Course Enrollment
+			:param topic: Topic DocType Object
+		"""
+		contents = topic.get_contents()
+		progress = []
+		for content in contents:
+			if content.doctype in ('Article', 'Video'):
+				status = check_content_completion(content.name, content.doctype, course_enrollment_name)
+				progress.append({'content': content.name, 'content_type': content.doctype, 'is_complete': status})
+			elif content.doctype == 'Quiz':
+				status, score, result = check_quiz_completion(content, course_enrollment_name)
+				progress.append({'content': content.name, 'content_type': content.doctype, 'is_complete': status, 'score': score, 'result': result})
+		return progress
+
+	def enroll_in_program(self, program_name):
+		try:
+			enrollment = frappe.get_doc({
+					"doctype": "Program Enrollment",
+					"student": self.name,
+					"academic_year": frappe.get_last_doc("Academic Year").name,
+					"program": program_name,
+					"enrollment_date": frappe.utils.datetime.datetime.now()
+				})
+			enrollment.save(ignore_permissions=True)
+		except frappe.exceptions.ValidationError:
+			enrollment_name = frappe.get_list("Program Enrollment", filters={"student": self.name, "Program": program_name})[0].name
+			return frappe.get_doc("Program Enrollment", enrollment_name)
+		else:
+			enrollment.submit()
+			return enrollment
+
+	def enroll_in_course(self, course_name, program_enrollment, enrollment_date=frappe.utils.datetime.datetime.now()):
+		try:
+			enrollment = frappe.get_doc({
+					"doctype": "Course Enrollment",
+					"student": self.name,
+					"course": course_name,
+					"program_enrollment": program_enrollment,
+					"enrollment_date": enrollment_date
+				})
+			enrollment.save(ignore_permissions=True)
+		except frappe.exceptions.ValidationError:
+			enrollment_name = frappe.get_list("Course Enrollment", filters={"student": self.name, "course": course_name, "program_enrollment": program_enrollment})[0].name
+			return frappe.get_doc("Program Enrollment", enrollment_name)
+		else:
+			return enrollment
+
 def get_timeline_data(doctype, name):
 	'''Return timeline for attendance'''
 	return dict(frappe.db.sql('''select unix_timestamp(`date`), count(*)
diff --git a/erpnext/education/doctype/student/student_dashboard.py b/erpnext/education/doctype/student/student_dashboard.py
index d86f4f2..0cbd17b 100644
--- a/erpnext/education/doctype/student/student_dashboard.py
+++ b/erpnext/education/doctype/student/student_dashboard.py
@@ -9,7 +9,7 @@
 		'transactions': [
 			{
 				'label': _('Admission'),
-				'items': ['Program Enrollment']
+				'items': ['Program Enrollment', 'Course Enrollment']
 			},
 			{
 				'label': _('Student Activity'),
@@ -20,6 +20,10 @@
 				'items': ['Assessment Result']
 			},
 			{
+				'label': _('Student LMS Activity'),
+				'items': ['Course Activity', 'Quiz Activity' ]
+			},
+			{
 				'label': _('Attendance'),
 				'items': ['Student Attendance', 'Student Leave Application']
 			},
diff --git a/erpnext/education/doctype/student/test_records.json b/erpnext/education/doctype/student/test_records.json
index 6acc4b6..8ad3afa 100644
--- a/erpnext/education/doctype/student/test_records.json
+++ b/erpnext/education/doctype/student/test_records.json
@@ -6,6 +6,7 @@
 		"program": "TC101",
 		"date_of_birth": "2000-01-01",
 		"gender": "Male",
+		"student_email_id": "_test_student@example.com",
 		"blood_group": "A+"
 
 	},
@@ -16,6 +17,7 @@
 		"program": "TC101",
 		"date_of_birth": "2000-01-01",
 		"gender": "Male",
+		"student_email_id": "_test_student_1@example.com",
 		"blood_group": "A+"
 
 	},
@@ -25,27 +27,8 @@
 		"last_name": "Name 2",
 		"program": "TC101",
 		"date_of_birth": "2000-01-01",
-		"gender": "Male",
-		"blood_group": "A+"
-
-	},
-	{
-		"first_name": "_Test",
-		"middle_name": "Student",
-		"last_name": "Name 3",
-		"program": "TC101",
-		"date_of_birth": "2000-01-01",
-		"gender": "Male",
-		"blood_group": "A+"
-
-	},
-	{
-		"first_name": "_Test",
-		"middle_name": "Student",
-		"last_name": "Name 4",
-		"program": "TC101",
-		"date_of_birth": "2000-01-01",
-		"gender": "Male",
+		"gender": "Female",
+		"student_email_id": "_test_student_2@example.com",
 		"blood_group": "A+"
 
 	}
diff --git a/erpnext/education/doctype/student/test_student.py b/erpnext/education/doctype/student/test_student.py
index cc6537f..8610edb 100644
--- a/erpnext/education/doctype/student/test_student.py
+++ b/erpnext/education/doctype/student/test_student.py
@@ -2,11 +2,60 @@
 # Copyright (c) 2015, Frappe Technologies and Contributors
 # See license.txt
 from __future__ import unicode_literals
+from frappe.test_runner import make_test_records
+from erpnext.education.doctype.program.test_program import make_program_and_linked_courses
+from erpnext.education.doctype.course.test_course import make_course
 
 import frappe
 import unittest
 
-# test_records = frappe.get_test_records('Student')
-
+test_records = frappe.get_test_records('Student')
 class TestStudent(unittest.TestCase):
-	pass
+	def setUp(self):
+		create_student({"first_name": "_Test Name", "last_name": "_Test Last Name", "email": "_test_student@example.com"})
+		make_program_and_linked_courses("_Test Program 1", ["_Test Course 1", "_Test Course 2"])
+
+	def test_create_student_user(self):
+		self.assertTrue(bool(frappe.db.exists("User", "_test_student@example.com")))
+		frappe.db.rollback()
+
+	def test_enroll_in_program(self):
+		student = get_student("_test_student@example.com")
+		enrollment = student.enroll_in_program("_Test Program 1")
+		test_enrollment = frappe.get_all("Program Enrollment", filters={"student": student.name, "Program": "_Test Program 1"})
+		self.assertTrue(len(test_enrollment))
+		self.assertEqual(test_enrollment[0]['name'], enrollment.name)
+		frappe.db.rollback()
+
+	def test_get_program_enrollments(self):
+		student = get_student("_test_student@example.com")
+		enrollment = student.enroll_in_program("_Test Program 1")
+		program_enrollments = student.get_program_enrollments()
+		self.assertTrue("_Test Program 1" in program_enrollments)
+		frappe.db.rollback()
+
+	def test_get_all_course_enrollments(self):
+		student = get_student("_test_student@example.com")
+		enrollment = student.enroll_in_program("_Test Program 1")
+		course_enrollments = student.get_all_course_enrollments()
+		self.assertTrue("_Test Course 1" in course_enrollments.keys())
+		self.assertTrue("_Test Course 2" in course_enrollments.keys())
+		frappe.db.rollback()
+
+def create_student(student_dict):
+	student = get_student(student_dict['email'])
+	if not student:
+		student = frappe.get_doc({
+			"doctype": "Student",
+			"first_name": student_dict['first_name'],
+			"last_name": student_dict['last_name'],
+			"student_email_id": student_dict['email']
+		}).insert()
+	return student
+
+def get_student(email):
+	try:
+		student_id = frappe.get_all("Student", {"student_email_id": email}, ["name"])[0].name
+		return frappe.get_doc("Student", student_id)
+	except IndexError:
+		return None
\ No newline at end of file
diff --git a/erpnext/education/doctype/student_applicant/student_applicant.json b/erpnext/education/doctype/student_applicant/student_applicant.json
index 297821f..71134e0 100644
--- a/erpnext/education/doctype/student_applicant/student_applicant.json
+++ b/erpnext/education/doctype/student_applicant/student_applicant.json
@@ -150,6 +150,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "0", 
+   "fieldname": "lms_only", 
+   "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": "LMS Only", 
+   "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": "paid", 
    "fieldtype": "Check", 
    "hidden": 0, 
@@ -627,7 +660,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, 
@@ -1160,7 +1193,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-08-21 14:44:30.146264", 
+ "modified": "2018-10-05 13:15:59.283862", 
  "modified_by": "Administrator", 
  "module": "Education", 
  "name": "Student Applicant", 
diff --git a/erpnext/education/doctype/topic/__init__.py b/erpnext/education/doctype/topic/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/topic/__init__.py
diff --git a/erpnext/education/doctype/topic/test_topic.js b/erpnext/education/doctype/topic/test_topic.js
new file mode 100644
index 0000000..4460b79
--- /dev/null
+++ b/erpnext/education/doctype/topic/test_topic.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: Topic", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Topic
+		() => frappe.tests.make('Topic', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/topic/test_topic.py b/erpnext/education/doctype/topic/test_topic.py
new file mode 100644
index 0000000..d03db1c
--- /dev/null
+++ b/erpnext/education/doctype/topic/test_topic.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestTopic(unittest.TestCase):
+	def setUp(self):
+		make_topic_and_linked_content("_Test Topic 1", [{"type":"Article", "name": "_Test Article 1"}])
+
+	def test_get_contents(self):
+		topic = frappe.get_doc("Topic", "_Test Topic 1")
+		contents = topic.get_contents()
+		self.assertEqual(contents[0].doctype, "Article")
+		self.assertEqual(contents[0].name, "_Test Article 1")
+		frappe.db.rollback()
+
+def make_topic(name):
+	try:
+		topic = frappe.get_doc("Topic", name)
+	except frappe.DoesNotExistError:
+		topic = frappe.get_doc({
+			"doctype": "Topic",
+			"topic_name": name,
+			"topic_code": name,
+		}).insert()
+	return topic.name
+
+def make_topic_and_linked_content(topic_name, content_dict_list):
+	try:
+		topic = frappe.get_doc("Topic", topic_name)
+	except frappe.DoesNotExistError:
+		make_topic(topic_name)
+		topic = frappe.get_doc("Topic", topic_name)
+	content_list = [make_content(content['type'], content['name']) for content in content_dict_list]
+	for content in content_list:
+		topic.append("topic_content", {"content": content.title, "content_type": content.doctype})
+	topic.save()
+	return topic
+
+
+def make_content(type, name):
+	try:
+		content = frappe.get_doc(type, name)
+	except frappe.DoesNotExistError:
+		content = frappe.get_doc({"doctype": type, "title": name}).insert()
+	return content
diff --git a/erpnext/education/doctype/topic/topic.js b/erpnext/education/doctype/topic/topic.js
new file mode 100644
index 0000000..695c174
--- /dev/null
+++ b/erpnext/education/doctype/topic/topic.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Topic', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/topic/topic.json b/erpnext/education/doctype/topic/topic.json
new file mode 100644
index 0000000..f47b10d
--- /dev/null
+++ b/erpnext/education/doctype/topic/topic.json
@@ -0,0 +1,297 @@
+{
+ "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "autoname": "field:topic_code", 
+ "beta": 0, 
+ "creation": "2018-12-12 11:37:39.917760", 
+ "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "topic_name", 
+   "fieldtype": "Data", 
+   "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": "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": 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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "column_break_2", 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "topic_code", 
+   "fieldtype": "Data", 
+   "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": "Code", 
+   "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": 1
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "section_break_4", 
+   "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, 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "topic_content", 
+   "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": "Topic Content", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Topic Content", 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "hero_image", 
+   "fieldtype": "Attach Image", 
+   "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": "Hero Image", 
+   "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_toolbar": 0, 
+ "idx": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "menu_index": 0, 
+ "modified": "2019-04-09 11:35:34.137040", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Topic", 
+ "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": "System 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": "Administrator", 
+   "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": "Instructor", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 1, 
+ "read_only": 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/education/doctype/topic/topic.py b/erpnext/education/doctype/topic/topic.py
new file mode 100644
index 0000000..339fc7d
--- /dev/null
+++ b/erpnext/education/doctype/topic/topic.py
@@ -0,0 +1,17 @@
+# -*- 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.model.document import Document
+
+class Topic(Document):
+	def get_contents(self):
+		try:
+			topic_content_list = self.get_all_children()
+			content_data = [frappe.get_doc(topic_content.content_type, topic_content.content) for topic_content in topic_content_list]
+		except Exception as e:
+			frappe.log_error(frappe.get_traceback())
+			return None
+		return content_data
\ No newline at end of file
diff --git a/erpnext/education/doctype/topic_content/__init__.py b/erpnext/education/doctype/topic_content/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/topic_content/__init__.py
diff --git a/erpnext/education/doctype/topic_content/test_topic_content.js b/erpnext/education/doctype/topic_content/test_topic_content.js
new file mode 100644
index 0000000..bf9a62d
--- /dev/null
+++ b/erpnext/education/doctype/topic_content/test_topic_content.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: Topic Content", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Topic Content
+		() => frappe.tests.make('Topic Content', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/topic_content/test_topic_content.py b/erpnext/education/doctype/topic_content/test_topic_content.py
new file mode 100644
index 0000000..cf304f6
--- /dev/null
+++ b/erpnext/education/doctype/topic_content/test_topic_content.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestTopicContent(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/topic_content/topic_content.js b/erpnext/education/doctype/topic_content/topic_content.js
new file mode 100644
index 0000000..9cda0ca
--- /dev/null
+++ b/erpnext/education/doctype/topic_content/topic_content.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Topic Content', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/topic_content/topic_content.json b/erpnext/education/doctype/topic_content/topic_content.json
new file mode 100644
index 0000000..5220788
--- /dev/null
+++ b/erpnext/education/doctype/topic_content/topic_content.json
@@ -0,0 +1,140 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-12-12 11:42:57.987434",
+ "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": "content_type",
+   "fieldtype": "Select",
+   "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": "Content Type",
+   "length": 0,
+   "no_copy": 0,
+   "options": "\nArticle\nVideo\nQuiz",
+   "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,
+   "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": "content",
+   "fieldtype": "Dynamic 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": "Content",
+   "length": 0,
+   "no_copy": 0,
+   "options": "content_type",
+   "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-12-12 11:46:46.112018",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Topic Content",
+ "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/education/doctype/topic_content/topic_content.py b/erpnext/education/doctype/topic_content/topic_content.py
new file mode 100644
index 0000000..9b2c90b
--- /dev/null
+++ b/erpnext/education/doctype/topic_content/topic_content.py
@@ -0,0 +1,10 @@
+# -*- 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.model.document import Document
+
+class TopicContent(Document):
+	pass
diff --git a/erpnext/education/doctype/video/__init__.py b/erpnext/education/doctype/video/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/video/__init__.py
diff --git a/erpnext/education/doctype/video/test_video.js b/erpnext/education/doctype/video/test_video.js
new file mode 100644
index 0000000..a82a221
--- /dev/null
+++ b/erpnext/education/doctype/video/test_video.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: Video", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Video
+		() => frappe.tests.make('Video', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/video/test_video.py b/erpnext/education/doctype/video/test_video.py
new file mode 100644
index 0000000..ecb09a2
--- /dev/null
+++ b/erpnext/education/doctype/video/test_video.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestVideo(unittest.TestCase):
+	pass
diff --git a/erpnext/education/doctype/video/video.js b/erpnext/education/doctype/video/video.js
new file mode 100644
index 0000000..c35c19b
--- /dev/null
+++ b/erpnext/education/doctype/video/video.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Video', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/education/doctype/video/video.json b/erpnext/education/doctype/video/video.json
new file mode 100644
index 0000000..cc8f718
--- /dev/null
+++ b/erpnext/education/doctype/video/video.json
@@ -0,0 +1,262 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "field:title",
+ "beta": 0,
+ "creation": "2018-10-17 05:47:13.087395",
+ "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": "title",
+   "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": "Title",
+   "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,
+   "fieldname": "description",
+   "fieldtype": "Text Editor",
+   "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": 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": "duration",
+   "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": "Duration",
+   "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": "url",
+   "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": "URL",
+   "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": "publish_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": "Publish 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
+  }
+ ],
+ "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-11-25 19:07:17.134288",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Video",
+ "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": "Academics User",
+   "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": "Instructor",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 0,
+   "delete": 0,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "LMS User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 0
+  }
+ ],
+ "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/education/doctype/video/video.py b/erpnext/education/doctype/video/video.py
new file mode 100644
index 0000000..b19f812
--- /dev/null
+++ b/erpnext/education/doctype/video/video.py
@@ -0,0 +1,13 @@
+# -*- 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.model.document import Document
+
+class Video(Document):
+
+
+	def get_video(self):
+		pass
diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py
index 1b93c9d..bf766ad 100644
--- a/erpnext/education/utils.py
+++ b/erpnext/education/utils.py
@@ -2,7 +2,7 @@
 # Copyright (c) 2015, Frappe Technologies and contributors
 # For lice
 
-from __future__ import unicode_literals
+from __future__ import unicode_literals, division
 import frappe
 from frappe import _
 
@@ -10,19 +10,19 @@
 
 def validate_overlap_for(doc, doctype, fieldname, value=None):
 	"""Checks overlap for specified field.
-	
-	:param fieldname: Checks Overlap for this field 
+
+	:param fieldname: Checks Overlap for this field
 	"""
-	
+
 	existing = get_overlap_for(doc, doctype, fieldname, value)
 	if existing:
 		frappe.throw(_("This {0} conflicts with {1} for {2} {3}").format(doc.doctype, existing.name,
 			doc.meta.get_label(fieldname) if not value else fieldname , value or doc.get(fieldname)), OverlapError)
-	
+
 def get_overlap_for(doc, doctype, fieldname, value=None):
 	"""Returns overlaping document for specified field.
-	
-	:param fieldname: Checks Overlap for this field 
+
+	:param fieldname: Checks Overlap for this field
 	"""
 
 	existing = frappe.db.sql("""select name, from_time, to_time from `tab{0}`
@@ -42,7 +42,8 @@
 		}, as_dict=True)
 
 	return existing[0] if existing else None
-	
+
+
 def validate_duplicate_student(students):
 	unique_students= []
 	for stud in students:
@@ -51,3 +52,93 @@
 				.format(stud.student, stud.student_name, unique_students.index(stud.student)+1, stud.idx))
 		else:
 			unique_students.append(stud.student)
+
+		return None
+
+# LMS Utils
+def get_current_student():
+	"""
+	Returns student user name, example EDU-STU-2018-00001 (Based on the naming series).
+	Takes email from from frappe.session.user
+	"""
+	email = frappe.session.user
+	if email in ('Administrator', 'Guest'):
+		return None
+	try:
+		student_id = frappe.get_all("Student", {"student_email_id": email}, ["name"])[0].name
+		return frappe.get_doc("Student", student_id)
+	except (IndexError, frappe.DoesNotExistError):
+		return None
+
+def check_super_access():
+	current_user = frappe.get_doc('User', frappe.session.user)
+	roles = set([role.role for role in current_user.roles])
+	return bool(roles & {'Administrator', 'Instructor', 'Education Manager', 'System Manager', 'Academic User'})
+
+def get_program_enrollment(program_name):
+	"""
+	Function to get program enrollments for a particular student for a program
+	"""
+	student = get_current_student()
+	if not student:
+		return None
+	else:
+		enrollment = frappe.get_all("Program Enrollment", filters={'student':student.name, 'program': program_name})
+		if enrollment:
+			return enrollment[0].name
+		else:
+			return None
+
+def get_program_and_enrollment_status(program_name):
+	program = frappe.get_doc('Program', program_name)
+	is_enrolled = bool(get_program_enrollment(program_name)) or check_super_access()
+	return {'program': program, 'is_enrolled': is_enrolled}
+
+def get_course_enrollment(course_name):
+	student = get_current_student()
+	if not student:
+		return None
+	enrollment_name = frappe.get_all("Course Enrollment", filters={'student': student.name, 'course':course_name})
+	try:
+		name = enrollment_name[0].name
+		enrollment = frappe.get_doc("Course Enrollment", name)
+		return enrollment
+	except:
+		return None
+
+def create_student_from_current_user():
+	user = frappe.get_doc("User", frappe.session.user)
+	student = frappe.get_doc({
+		"doctype": "Student",
+		"first_name": user.first_name,
+		"last_name": user.last_name,
+		"student_email_id": user.email,
+		"user": frappe.session.user
+		})
+	student.save(ignore_permissions=True)
+	return student
+
+def enroll_in_course(course_name, program_name):
+	student = get_current_student()
+	return student.enroll_in_course(course_name=course_name, program_enrollment=get_program_enrollment(program_name))
+
+def check_content_completion(content_name, content_type, enrollment_name):
+	activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment_name, 'content_type': content_type, 'content': content_name})
+	if activity:
+		return True
+	else:
+		return False
+
+def check_quiz_completion(quiz, enrollment_name):
+	attempts = frappe.get_all("Quiz Activity", filters={'enrollment': enrollment_name, 'quiz': quiz.name}, fields=["name", "activity_date", "score", "status"])
+	status = False if quiz.max_attempts == 0 else bool(len(attempts) == quiz.max_attempts)
+	score = None
+	result = None
+	if attempts:
+		if quiz.grading_basis == 'Last Highest Score':
+			attempts = sorted(attempts, key = lambda i: int(i.score), reverse=True)
+		score = attempts[0]['score']
+		result = attempts[0]['status']
+		if result == 'Pass':
+			status = True
+	return status, score, result
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 608e8b2..47d2056 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -11,6 +11,7 @@
 app_license = "GNU General Public License (v3)"
 source_link = "https://github.com/frappe/erpnext"
 
+
 develop_version = '12.x.x-develop'
 
 error_report_email = "support@erpnext.com"
diff --git a/erpnext/hr/doctype/designation/designation.json b/erpnext/hr/doctype/designation/designation.json
index 1d4a3cf..4c3888b 100644
--- a/erpnext/hr/doctype/designation/designation.json
+++ b/erpnext/hr/doctype/designation/designation.json
@@ -1,119 +1,194 @@
 {
- "allow_copy": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:designation_name", 
- "beta": 0, 
- "creation": "2013-01-10 16:34:13", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Setup", 
- "editable_grid": 0, 
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:designation_name",
+ "beta": 0,
+ "creation": "2013-01-10 16:34:13",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 0,
  "fields": [
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "designation_name", 
-   "fieldtype": "Data", 
-   "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": "Designation", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "designation_name", 
-   "oldfieldtype": "Data", 
-   "permlevel": 0, 
-   "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_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "designation_name",
+   "fieldtype": "Data",
+   "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": "Designation",
+   "length": 0,
+   "no_copy": 0,
+   "oldfieldname": "designation_name",
+   "oldfieldtype": "Data",
+   "permlevel": 0,
+   "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": 1
+  },
   {
-   "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": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 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": 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,
+   "fetch_if_empty": 0,
+   "fieldname": "required_skills_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": "Required Skills",
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "skills",
+   "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": "Skills",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Designation Skill",
+   "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
   }
- ], 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "icon": "fa fa-bookmark", 
- "idx": 1, 
- "image_view": 0, 
- "in_create": 0, 
-
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-02-17 16:53:43.895882", 
- "modified_by": "Administrator", 
- "module": "HR", 
- "name": "Designation", 
- "owner": "Administrator", 
+ ],
+ "has_web_view": 0,
+ "hide_toolbar": 0,
+ "icon": "fa fa-bookmark",
+ "idx": 1,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "menu_index": 0,
+ "modified": "2019-04-16 10:02:23.277734",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Designation",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "HR User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "amend": 0,
+   "cancel": 0,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 0,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "HR 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": 1, 
- "sort_order": "ASC", 
- "track_changes": 0, 
- "track_seen": 0
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "show_name_in_global_search": 1,
+ "sort_order": "ASC",
+ "track_changes": 0,
+ "track_seen": 0,
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/designation_skill/__init__.py b/erpnext/hr/doctype/designation_skill/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/designation_skill/__init__.py
diff --git a/erpnext/hr/doctype/designation_skill/designation_skill.json b/erpnext/hr/doctype/designation_skill/designation_skill.json
new file mode 100644
index 0000000..30e23d0
--- /dev/null
+++ b/erpnext/hr/doctype/designation_skill/designation_skill.json
@@ -0,0 +1,74 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2019-04-16 10:01:05.259881",
+ "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,
+   "fetch_if_empty": 0,
+   "fieldname": "skill",
+   "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": "Skill",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Skill",
+   "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_toolbar": 0,
+ "idx": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2019-04-16 13:42:10.760449",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Designation Skill",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/designation_skill/designation_skill.py b/erpnext/hr/doctype/designation_skill/designation_skill.py
new file mode 100644
index 0000000..c37d21f
--- /dev/null
+++ b/erpnext/hr/doctype/designation_skill/designation_skill.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class DesignationSkill(Document):
+	pass
diff --git a/erpnext/hr/doctype/employee_skill/__init__.py b/erpnext/hr/doctype/employee_skill/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/employee_skill/__init__.py
diff --git a/erpnext/hr/doctype/employee_skill/employee_skill.json b/erpnext/hr/doctype/employee_skill/employee_skill.json
new file mode 100644
index 0000000..4b1419e
--- /dev/null
+++ b/erpnext/hr/doctype/employee_skill/employee_skill.json
@@ -0,0 +1,141 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2019-04-16 09:57:52.751635",
+ "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,
+   "fetch_if_empty": 0,
+   "fieldname": "skill",
+   "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": "Skill",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Skill",
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "proficiency",
+   "fieldtype": "Rating",
+   "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": "Proficiency",
+   "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": "Today",
+   "fetch_if_empty": 0,
+   "fieldname": "evaluation_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,
+   "label": "Evaluation 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
+  }
+ ],
+ "has_web_view": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2019-04-16 14:13:17.111035",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Employee Skill",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_skill/employee_skill.py b/erpnext/hr/doctype/employee_skill/employee_skill.py
new file mode 100644
index 0000000..ac05fba
--- /dev/null
+++ b/erpnext/hr/doctype/employee_skill/employee_skill.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class EmployeeSkill(Document):
+	pass
diff --git a/erpnext/hr/doctype/employee_skill_map/__init__.py b/erpnext/hr/doctype/employee_skill_map/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/employee_skill_map/__init__.py
diff --git a/erpnext/hr/doctype/employee_skill_map/employee_skill_map.js b/erpnext/hr/doctype/employee_skill_map/employee_skill_map.js
new file mode 100644
index 0000000..b82b18d
--- /dev/null
+++ b/erpnext/hr/doctype/employee_skill_map/employee_skill_map.js
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Employee Skill Map', {
+	// refresh: function(frm) {
+
+	// }
+	designation: (frm) => {
+		frm.set_value('employee_skills', null);
+		if (frm.doc.designation) {
+			frappe.db.get_doc('Designation', frm.doc.designation).then((designation) => {
+				designation.skills.forEach(designation_skill => {
+					let row = frappe.model.add_child(frm.doc, 'Employee Skill', 'employee_skills');
+					row.skill = designation_skill.skill;
+					row.proficiency = 1;
+				});
+				refresh_field('employee_skills');
+			});
+		}
+	}
+});
diff --git a/erpnext/hr/doctype/employee_skill_map/employee_skill_map.json b/erpnext/hr/doctype/employee_skill_map/employee_skill_map.json
new file mode 100644
index 0000000..624145f
--- /dev/null
+++ b/erpnext/hr/doctype/employee_skill_map/employee_skill_map.json
@@ -0,0 +1,298 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:employee",
+ "beta": 0,
+ "creation": "2019-04-16 10:07:48.303426",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 0,
+ "engine": "InnoDB",
+ "fields": [
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 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": 1
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_from": "employee.employee_name",
+   "fetch_if_empty": 0,
+   "fieldname": "employee_name",
+   "fieldtype": "Read Only",
+   "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 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": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_from": "employee.designation",
+   "fetch_if_empty": 0,
+   "fieldname": "designation",
+   "fieldtype": "Read Only",
+   "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": "Designation",
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "skills_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": "Skills",
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "employee_skills",
+   "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": "Employee Skills",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Employee Skill",
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "trainings_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": "Trainings",
+   "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,
+   "fetch_if_empty": 0,
+   "fieldname": "trainings",
+   "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": "Trainings",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Employee Training",
+   "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_toolbar": 0,
+ "idx": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2019-04-16 16:16:40.058429",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Employee Skill Map",
+ "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": "System Manager",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "title_field": "employee_name",
+ "track_changes": 0,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_skill_map/employee_skill_map.py b/erpnext/hr/doctype/employee_skill_map/employee_skill_map.py
new file mode 100644
index 0000000..073f02f
--- /dev/null
+++ b/erpnext/hr/doctype/employee_skill_map/employee_skill_map.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class EmployeeSkillMap(Document):
+	pass
diff --git a/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json b/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json
index 7b2804b..66fac5b 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 1, 
@@ -20,6 +21,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "max_amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -29,7 +31,7 @@
    "in_global_search": 0, 
    "in_list_view": 1, 
    "in_standard_filter": 0, 
-   "label": "Max Amount", 
+   "label": "Max Exemption Amount", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -39,7 +41,7 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
    "translatable": 0, 
@@ -52,6 +54,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "1", 
+   "fetch_if_empty": 0, 
    "fieldname": "is_active", 
    "fieldtype": "Check", 
    "hidden": 0, 
@@ -88,7 +92,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-06-19 16:33:48.419267", 
+ "modified": "2019-04-25 13:20:31.367158", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Employee Tax Exemption Category", 
@@ -159,6 +163,7 @@
  "show_name_in_global_search": 0, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0
+ "track_changes": 0, 
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js
index 9560df5..a827eca 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js
@@ -10,6 +10,7 @@
 				}
 			}
 		});
+
 		frm.set_query('payroll_period', function() {
 			const fields = {'employee': 'Employee', 'company': 'Company'};
 
@@ -27,6 +28,7 @@
 				}
 			}
 		});
+
 		frm.set_query('exemption_sub_category', 'declarations', function() {
 			return {
 				filters: {
@@ -34,5 +36,16 @@
 				}
 			}
 		});
+	},
+
+	refresh: function(frm) {
+		if(frm.doc.docstatus==1) {
+			frm.add_custom_button(__('Submit Proof'), function() {
+				frappe.model.open_mapped_doc({
+					method: "erpnext.hr.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration.make_proof_submission",
+					frm: frm
+				});
+			}).addClass("btn-primary");
+		}
 	}
 });
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json
index 865e821..8891b97 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 1, 
@@ -20,6 +21,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "employee", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -53,9 +55,10 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fetch_from": "employee.company", 
-   "fieldname": "company", 
-   "fieldtype": "Link", 
+   "fetch_from": "employee.employee_name", 
+   "fetch_if_empty": 0, 
+   "fieldname": "employee_name", 
+   "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -63,104 +66,7 @@
    "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": 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, 
-   "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": "payroll_period", 
-   "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": "Payroll Period", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Payroll Period", 
-   "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": "total_exemption_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": "Total Exemption Amount", 
+   "label": "Employee Name", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -184,6 +90,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "fetch_from": "employee.department", 
+   "fetch_if_empty": 0, 
    "fieldname": "department", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -217,6 +124,108 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "column_break_2", 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "payroll_period", 
+   "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": "Payroll Period", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Payroll Period", 
+   "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, 
+   "fetch_from": "employee.company", 
+   "fetch_if_empty": 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": 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, 
+   "fetch_if_empty": 0, 
    "fieldname": "amended_from", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -249,6 +258,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "section_break_8", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -280,6 +290,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "declarations", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -300,7 +311,137 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "section_break_10", 
+   "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, 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "total_declared_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": "Total Declared 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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "column_break_12", 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "total_exemption_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": "Total Exemption 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, 
@@ -317,7 +458,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 16:15:49.363307", 
+ "modified": "2019-04-25 16:38:05.847925", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Employee Tax Exemption Declaration", 
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py
index 186b2e1..cbdfcf8 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py
@@ -6,28 +6,61 @@
 import frappe
 from frappe.model.document import Document
 from frappe import _
-from erpnext.hr.utils import validate_tax_declaration, calculate_annual_eligible_hra_exemption
+from frappe.utils import flt
+from frappe.model.mapper import get_mapped_doc
+from erpnext.hr.utils import validate_tax_declaration, get_total_exemption_amount, calculate_annual_eligible_hra_exemption
+
+class DuplicateDeclarationError(frappe.ValidationError): pass
 
 class EmployeeTaxExemptionDeclaration(Document):
 	def validate(self):
 		validate_tax_declaration(self.declarations)
-		self.total_exemption_amount = 0
+		self.validate_duplicate()
+		self.set_total_declared_amount()
+		self.set_total_exemption_amount()
 		self.calculate_hra_exemption()
-		for item in self.declarations:
-			self.total_exemption_amount += item.amount
 
-	def before_submit(self):
-		if frappe.db.exists({"doctype": "Employee Tax Exemption Declaration",
-							"employee": self.employee,
-							"payroll_period": self.payroll_period,
-							"docstatus": 1}):
-			frappe.throw(_("Tax Declaration of {0} for period {1} already submitted.")\
-			.format(self.employee, self.payroll_period), frappe.DocstatusTransitionError)
+	def validate_duplicate(self):
+		duplicate = frappe.db.get_value("Employee Tax Exemption Declaration",
+			filters = {
+				"employee": self.employee,
+				"payroll_period": self.payroll_period,
+				"name": ["!=", self.name]
+			}
+		)
+		if duplicate:
+			frappe.throw(_("Duplicate Tax Declaration of {0} for period {1}")
+				.format(self.employee, self.payroll_period), DuplicateDeclarationError)
+
+	def set_total_declared_amount(self):
+		self.total_declared_amount = 0.0
+		for d in self.declarations:
+			self.total_declared_amount += flt(d.amount)
+
+	def set_total_exemption_amount(self):
+		self.total_exemption_amount = get_total_exemption_amount(self.declarations)
 
 	def calculate_hra_exemption(self):
-		hra_exemption = calculate_annual_eligible_hra_exemption(self)
-		if hra_exemption:
-			self.total_exemption_amount += hra_exemption["annual_exemption"]
-			self.salary_structure_hra = hra_exemption["hra_amount"]
-			self.annual_hra_exemption = hra_exemption["annual_exemption"]
-			self.monthly_hra_exemption = hra_exemption["monthly_exemption"]
+		self.salary_structure_hra, self.annual_hra_exemption, self.monthly_hra_exemption = 0, 0, 0
+		if self.get("monthly_house_rent"):
+			hra_exemption = calculate_annual_eligible_hra_exemption(self)
+			if hra_exemption:
+				self.total_exemption_amount += hra_exemption["annual_exemption"]
+				self.salary_structure_hra = hra_exemption["hra_amount"]
+				self.annual_hra_exemption = hra_exemption["annual_exemption"]
+				self.monthly_hra_exemption = hra_exemption["monthly_exemption"]
+
+@frappe.whitelist()
+def make_proof_submission(source_name, target_doc=None):
+	doclist = get_mapped_doc("Employee Tax Exemption Declaration", source_name, {
+		"Employee Tax Exemption Declaration": {
+			"doctype": "Employee Tax Exemption Proof Submission",
+			"field_no_map": ["monthly_house_rent", "monthly_hra_exemption"]
+		},
+		"Employee Tax Exemption Declaration Category": {
+			"doctype": "Employee Tax Exemption Proof Submission Detail",
+			"add_if_empty": True
+		}
+	}, target_doc)
+
+	return doclist
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py b/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py
index beaddd9..9c87bbd 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py
@@ -6,6 +6,7 @@
 import frappe, erpnext
 import unittest
 from erpnext.hr.doctype.employee.test_employee import make_employee
+from erpnext.hr.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration import DuplicateDeclarationError
 
 class TestEmployeeTaxExemptionDeclaration(unittest.TestCase):
 	def setUp(self):
@@ -15,71 +16,71 @@
 		create_exemption_category()
 		frappe.db.sql("""delete from `tabEmployee Tax Exemption Declaration`""")
 
-	def test_exemption_amount_greater_than_category_max(self):
-		declaration = frappe.get_doc({
-			"doctype": "Employee Tax Exemption Declaration",
-			"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
-			"payroll_period": "_Test Payroll Period",
-			"declarations": [dict(exemption_sub_category = "_Test Sub Category",
-							exemption_category = "_Test Category",
-							amount = 150000)]
-		})
-		self.assertRaises(frappe.ValidationError, declaration.save)
-		declaration = frappe.get_doc({
-			"doctype": "Employee Tax Exemption Declaration",
-			"payroll_period": "_Test Payroll Period",
-			"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
-			"declarations": [dict(exemption_sub_category = "_Test Sub Category",
-							exemption_category = "_Test Category",
-							amount = 90000)]
-		})
-		self.assertTrue(declaration.save)
-
 	def test_duplicate_category_in_declaration(self):
 		declaration = frappe.get_doc({
 			"doctype": "Employee Tax Exemption Declaration",
 			"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
 			"company": erpnext.get_default_company(),
 			"payroll_period": "_Test Payroll Period",
-			"declarations": [dict(exemption_sub_category = "_Test Sub Category",
-							exemption_category = "_Test Category",
-							amount = 100000),
-							dict(exemption_sub_category = "_Test Sub Category",
-							exemption_category = "_Test Category",
-							amount = 50000),
-							]
+			"declarations": [
+				dict(exemption_sub_category = "_Test Sub Category",
+					exemption_category = "_Test Category",
+					amount = 100000),
+				dict(exemption_sub_category = "_Test Sub Category",
+					exemption_category = "_Test Category",
+					amount = 50000)
+			]
 		})
 		self.assertRaises(frappe.ValidationError, declaration.save)
 
-	def test_duplicate_submission_for_payroll_period(self):
+	def test_duplicate_entry_for_payroll_period(self):
 		declaration = frappe.get_doc({
 			"doctype": "Employee Tax Exemption Declaration",
 			"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
 			"company":  erpnext.get_default_company(),
 			"payroll_period": "_Test Payroll Period",
-			"declarations": [dict(exemption_sub_category = "_Test Sub Category",
-							exemption_category = "_Test Category",
-							amount = 100000),
-							dict(exemption_sub_category = "_Test1 Sub Category",
-							exemption_category = "_Test Category",
-							amount = 50000),
-							]
+			"declarations": [
+				dict(exemption_sub_category = "_Test Sub Category",
+					exemption_category = "_Test Category",
+					amount = 100000),
+				dict(exemption_sub_category = "_Test1 Sub Category",
+					exemption_category = "_Test Category",
+					amount = 50000),
+			]
 		}).insert()
-		declaration.submit()
-		self.assertEquals(declaration.docstatus, 1)
+
 		duplicate_declaration = frappe.get_doc({
 			"doctype": "Employee Tax Exemption Declaration",
 			"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
 			"company":  erpnext.get_default_company(),
 			"payroll_period": "_Test Payroll Period",
-			"declarations": [dict(exemption_sub_category = "_Test Sub Category",
-							exemption_category = "_Test Category",
-							amount = 100000)
-							]
-		}).insert()
-		self.assertRaises(frappe.DocstatusTransitionError, duplicate_declaration.submit)
+			"declarations": [
+				dict(exemption_sub_category = "_Test Sub Category",
+					exemption_category = "_Test Category",
+					amount = 100000)
+			]
+		})
+		self.assertRaises(DuplicateDeclarationError, duplicate_declaration.insert)
 		duplicate_declaration.employee = frappe.get_value("Employee", {"user_id":"employee1@taxexepmtion.com"}, "name")
-		self.assertTrue(duplicate_declaration.submit)
+		self.assertTrue(duplicate_declaration.insert)
+
+	def test_exemption_amount(self):
+		declaration = frappe.get_doc({
+			"doctype": "Employee Tax Exemption Declaration",
+			"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
+			"company":  erpnext.get_default_company(),
+			"payroll_period": "_Test Payroll Period",
+			"declarations": [
+				dict(exemption_sub_category = "_Test Sub Category",
+					exemption_category = "_Test Category",
+					amount = 80000),
+				dict(exemption_sub_category = "_Test1 Sub Category",
+					exemption_category = "_Test Category",
+					amount = 60000),
+			]
+		}).insert()
+
+		self.assertEqual(declaration.total_exemption_amount, 100000)
 
 def create_payroll_period():
 	if not frappe.db.exists("Payroll Period", "_Test Payroll Period"):
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json b/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json
index ebde4c9..56556c1 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json
@@ -1,140 +1,179 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2018-04-13 16:56:23.333041", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-04-13 16:56:23.333041",
+ "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": "exemption_sub_category", 
-   "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": "Exemption Sub Category", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Employee Tax Exemption Sub Category", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "exemption_sub_category",
+   "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": "Exemption Sub Category",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Employee Tax Exemption Sub Category",
+   "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, 
-   "fetch_from": "exemption_sub_category.exemption_category", 
-   "fieldname": "exemption_category", 
-   "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": "Exemption Category", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Employee Tax Exemption Category", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_from": "exemption_sub_category.exemption_category",
+   "fetch_if_empty": 0,
+   "fieldname": "exemption_category",
+   "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": "Exemption Category",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Employee Tax Exemption Category",
+   "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,
+   "translatable": 0,
    "unique": 0
-  }, 
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "amount", 
-   "fieldtype": "Currency", 
-   "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": "", 
-   "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, 
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_from": "exemption_sub_category.max_amount",
+   "fetch_if_empty": 0,
+   "fieldname": "max_amount",
+   "fieldtype": "Currency",
+   "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": "Maximum Exemption 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": 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,
+   "fetch_if_empty": 0,
+   "fieldname": "amount",
+   "fieldtype": "Data",
+   "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": "Declared 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": 1,
+   "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-05-29 15:58:05.779031", 
- "modified_by": "Administrator", 
- "module": "HR", 
- "name": "Employee Tax Exemption Declaration Category", 
- "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
+ ],
+ "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": "2019-04-25 15:45:11.279158",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Employee Tax Exemption Declaration Category",
+ "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/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js
index 99bec14..66118c0 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js
+++ b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js
@@ -10,6 +10,7 @@
 				}
 			}
 		});
+
 		frm.set_query('payroll_period', function() {
 			if(frm.doc.employee && frm.doc.company){
 				return {
@@ -21,6 +22,7 @@
 				frappe.msgprint(__("Please select Employee"));
 			}
 		});
+
 		frm.set_query('exemption_sub_category', 'tax_exemption_proofs', function() {
 			return {
 				filters: {
@@ -29,11 +31,28 @@
 			}
 		});
 	},
-	employee: function(frm){
-		if(frm.doc.employee){
-			frm.add_fetch('employee', 'company', 'company');
-		}else{
-			frm.set_value('company', '');
+
+	refresh: function(frm) {
+		if(frm.doc.docstatus === 0) {
+			let filters = {
+				docstatus: 1,
+				company: frm.doc.company
+			};
+			if(frm.doc.employee) filters["employee"] = frm.doc.employee;
+			if(frm.doc.payroll_period) filters["payroll_period"] = frm.doc.payroll_period;
+
+			frm.add_custom_button(__('Get Details From Declaration'), function() {
+				erpnext.utils.map_current_doc({
+					method: "erpnext.hr.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration.make_proof_submission",
+					source_doctype: "Employee Tax Exemption Declaration",
+					target: frm,
+					date_field: "creation",
+					setters: {
+						employee: frm.doc.employee || undefined
+					},
+					get_query_filters: filters
+				});
+			});
 		}
 	}
 });
diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json
index ebc0435..76c09d6 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json
@@ -1,8 +1,9 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
+ "allow_import": 1, 
+ "allow_rename": 1, 
  "autoname": "HR-TAX-PRF-.YYYY.-.#####", 
  "beta": 0, 
  "creation": "2018-04-13 17:24:11.456132", 
@@ -20,6 +21,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "employee", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -53,8 +55,10 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "company", 
-   "fieldtype": "Link", 
+   "fetch_from": "employee.employee_name", 
+   "fetch_if_empty": 0, 
+   "fieldname": "employee_name", 
+   "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -62,10 +66,9 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Company", 
+   "label": "Employee Name", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Company", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -86,71 +89,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "column_break_2", 
-   "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": "payroll_period", 
-   "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": "Payroll Period", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Payroll Period", 
-   "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, 
    "fetch_from": "employee.department", 
+   "fetch_if_empty": 0, 
    "fieldname": "department", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -184,8 +124,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "submission_date", 
-   "fieldtype": "Date", 
+   "fetch_if_empty": 0, 
+   "fieldname": "column_break_2", 
+   "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -193,7 +134,6 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Submission Date", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -216,6 +156,273 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "default": "Today", 
+   "fetch_if_empty": 0, 
+   "fieldname": "submission_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": "Submission 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": 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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "payroll_period", 
+   "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": "Payroll Period", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Payroll Period", 
+   "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, 
+   "fetch_from": "employee.company", 
+   "fetch_if_empty": 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": 1, 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "section_break_5", 
+   "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, 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "tax_exemption_proofs", 
+   "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": "Tax Exemption Proofs", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Employee Tax Exemption Proof Submission Detail", 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "section_break_10", 
+   "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, 
+   "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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "total_actual_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": "Total Actual 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, 
+   "fetch_if_empty": 0, 
+   "fieldname": "column_break_12", 
+   "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "exemption_amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -248,70 +455,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "section_break_5", 
-   "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, 
-   "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": "tax_exemption_proofs", 
-   "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": "Tax Exemption Proofs", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Employee Tax Exemption Proof Submission Detail", 
-   "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, 
+   "fetch_if_empty": 0, 
    "fieldname": "attachment_section", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -344,6 +488,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "attachments", 
    "fieldtype": "Attach", 
    "hidden": 0, 
@@ -376,6 +521,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "amended_from", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -412,7 +558,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 16:15:38.096846", 
+ "modified": "2019-04-25 17:06:36.569549", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Employee Tax Exemption Proof Submission", 
diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py
index 54e0b20..97ceb63 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py
@@ -6,20 +6,30 @@
 import frappe
 from frappe.model.document import Document
 from frappe import _
-from erpnext.hr.utils import validate_tax_declaration, calculate_hra_exemption_for_period
+from frappe.utils import flt
+from erpnext.hr.utils import validate_tax_declaration, get_total_exemption_amount, calculate_hra_exemption_for_period
 
 class EmployeeTaxExemptionProofSubmission(Document):
 	def validate(self):
 		validate_tax_declaration(self.tax_exemption_proofs)
-		self.exemption_amount = 0
+		self.set_total_actual_amount()
+		self.set_total_exemption_amount()
 		self.calculate_hra_exemption()
-		for proof in self.tax_exemption_proofs:
-			self.exemption_amount += proof.amount
+
+	def set_total_actual_amount(self):
+		self.total_actual_amount = flt(self.get("house_rent_payment_amount"))
+		for d in self.tax_exemption_proofs:
+			self.total_actual_amount += flt(d.amount)
+
+	def set_total_exemption_amount(self):
+		self.exemption_amount = get_total_exemption_amount(self.tax_exemption_proofs)
 
 	def calculate_hra_exemption(self):
-		hra_exemption = calculate_hra_exemption_for_period(self)
-		if hra_exemption:
-			self.exemption_amount += hra_exemption["total_eligible_hra_exemption"]
-			self.monthly_hra_exemption = hra_exemption["monthly_exemption"]
-			self.monthly_house_rent = hra_exemption["monthly_house_rent"]
-			self.total_eligible_hra_exemption = hra_exemption["total_eligible_hra_exemption"]
+		self.monthly_hra_exemption, self.monthly_house_rent, self.total_eligible_hra_exemption = 0, 0, 0
+		if self.get("house_rent_payment_amount"):
+			hra_exemption = calculate_hra_exemption_for_period(self)
+			if hra_exemption:
+				self.exemption_amount += hra_exemption["total_eligible_hra_exemption"]
+				self.monthly_hra_exemption = hra_exemption["monthly_exemption"]
+				self.monthly_house_rent = hra_exemption["monthly_house_rent"]
+				self.total_eligible_hra_exemption = hra_exemption["total_eligible_hra_exemption"]
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json b/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json
index c1c5896..b9254af 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
@@ -14,10 +15,12 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "exemption_sub_category", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -41,16 +44,18 @@
    "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, 
    "columns": 0, 
-   "fetch_from": "exemption_sub_category.exemption_category",
+   "fetch_from": "exemption_sub_category.exemption_category", 
+   "fetch_if_empty": 0, 
    "fieldname": "exemption_category", 
    "fieldtype": "Read Only", 
    "hidden": 0, 
@@ -74,15 +79,51 @@
    "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, 
    "columns": 0, 
+   "fetch_from": "exemption_sub_category.max_amount", 
+   "fetch_if_empty": 0, 
+   "fieldname": "max_amount", 
+   "fieldtype": "Currency", 
+   "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": "Maximum Exemption 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": 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, 
+   "fetch_if_empty": 0, 
    "fieldname": "type_of_proof", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -106,15 +147,17 @@
    "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, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -124,7 +167,7 @@
    "in_global_search": 0, 
    "in_list_view": 1, 
    "in_standard_filter": 0, 
-   "label": "Amount", 
+   "label": "Actual Amount", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -134,10 +177,10 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
-   "translatable": 0,
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -151,7 +194,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-05-16 22:42:59.750733",
+ "modified": "2019-04-25 15:45:03.154904", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Employee Tax Exemption Proof Submission Detail", 
@@ -165,5 +208,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/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json b/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json
index dc99785..b0e492e 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
  "allow_guest_to_view": 0, 
  "allow_import": 1, 
  "allow_rename": 1, 
@@ -15,10 +16,12 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fetch_if_empty": 0, 
    "fieldname": "exemption_category", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -26,8 +29,8 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 1, 
    "label": "Tax Exemption Category", 
    "length": 0, 
    "no_copy": 0, 
@@ -42,14 +45,18 @@
    "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, 
+   "fetch_from": "exemption_category.max_amount", 
+   "fetch_if_empty": 1, 
    "fieldname": "max_amount", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -59,7 +66,7 @@
    "in_global_search": 0, 
    "in_list_view": 1, 
    "in_standard_filter": 0, 
-   "label": "Max Amount", 
+   "label": "Max Exemption Amount", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -69,17 +76,21 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "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": "1", 
+   "fetch_if_empty": 0, 
    "fieldname": "is_active", 
    "fieldtype": "Check", 
    "hidden": 0, 
@@ -102,6 +113,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -115,7 +127,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-05-09 13:25:01.595240", 
+ "modified": "2019-04-25 13:24:05.164877", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Employee Tax Exemption Sub Category", 
@@ -124,7 +136,6 @@
  "permissions": [
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 1, 
    "delete": 1, 
@@ -144,7 +155,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 1, 
    "delete": 1, 
@@ -164,7 +174,6 @@
   }, 
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 1, 
    "delete": 1, 
@@ -189,6 +198,7 @@
  "show_name_in_global_search": 0, 
  "sort_field": "modified", 
  "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0
+ "track_changes": 0, 
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py b/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py
index cd58136..a8dd7e4 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py
@@ -4,7 +4,13 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe import _
+from frappe.utils import flt
 from frappe.model.document import Document
 
 class EmployeeTaxExemptionSubCategory(Document):
-	pass
+	def validate(self):
+		category_max_amount = frappe.db.get_value("Employee Tax Exemption Category", self.exemption_category, "max_amount")
+		if flt(self.max_amount) > flt(category_max_amount):
+			frappe.throw(_("Max Exemption Amount cannot be greater than maximum exemption amount {0} of Tax Exemption Category {1}")
+				.format(category_max_amount, self.exemption_category))
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_training/__init__.py b/erpnext/hr/doctype/employee_training/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/employee_training/__init__.py
diff --git a/erpnext/hr/doctype/employee_training/employee_training.json b/erpnext/hr/doctype/employee_training/employee_training.json
new file mode 100644
index 0000000..0e0dc15
--- /dev/null
+++ b/erpnext/hr/doctype/employee_training/employee_training.json
@@ -0,0 +1,108 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2019-04-16 16:15:50.931545",
+ "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,
+   "fetch_if_empty": 0,
+   "fieldname": "training",
+   "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": "Training",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Training Event",
+   "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,
+   "fetch_from": "training.end_time",
+   "fetch_if_empty": 0,
+   "fieldname": "training_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,
+   "label": "Training 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
+  }
+ ],
+ "has_web_view": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2019-04-22 12:48:56.925419",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Employee Training",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_training/employee_training.py b/erpnext/hr/doctype/employee_training/employee_training.py
new file mode 100644
index 0000000..810796d
--- /dev/null
+++ b/erpnext/hr/doctype/employee_training/employee_training.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class EmployeeTraining(Document):
+	pass
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 9e13cb6..1b487a6 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -167,7 +167,7 @@
 			if d.amount_based_on_formula:
 				formula = d.formula.strip() if d.formula else None
 				if formula:
-					amount = frappe.safe_eval(formula, self.whitelisted_globals, data)
+					amount = rounded(frappe.safe_eval(formula, self.whitelisted_globals, data))
 			if amount:
 				data[d.abbr] = amount
 
@@ -602,12 +602,11 @@
 			annual_earning = taxable_earning["taxable_earning"] * period_factor
 			exemption_amount = 0
 			if frappe.db.exists("Employee Tax Exemption Declaration", {"employee": self.employee,
-			"payroll_period": payroll_period.name, "docstatus": 1}):
+					"payroll_period": payroll_period.name, "docstatus": 1}):
 				exemption_amount = frappe.db.get_value("Employee Tax Exemption Declaration",
 					{"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1},
 					"total_exemption_amount")
 			annual_taxable_earning = annual_earning - exemption_amount
-
 		if self.deduct_tax_for_unclaimed_employee_benefits or self.deduct_tax_for_unsubmitted_tax_exemption_proof:
 			tax_detail = self.get_tax_paid_in_period(payroll_period, tax_component)
 			if tax_detail:
@@ -739,22 +738,24 @@
 		# less paid taxes
 		if args.get("pro_rata_tax_paid"):
 			tax_amount -= args.get("pro_rata_tax_paid")
+		tax_amount = rounded(tax_amount)
 		struct_row = self.get_salary_slip_row(args.get("tax_component"))
 		return [struct_row, tax_amount, benefit_tax, additional_tax]
 
-	def calculate_tax_by_tax_slab(self, payroll_period, annual_earning):
+	def calculate_tax_by_tax_slab(self, payroll_period, annual_taxable_earning):
 		payroll_period_obj = frappe.get_doc("Payroll Period", payroll_period)
 		data = self.get_data_for_eval()
+		data.update({"annual_taxable_earning": annual_taxable_earning})
 		taxable_amount = 0
 		for slab in payroll_period_obj.taxable_salary_slabs:
 			if slab.condition and not self.eval_tax_slab_condition(slab.condition, data):
 				continue
-			if not slab.to_amount and annual_earning > slab.from_amount:
-				taxable_amount += (annual_earning - slab.from_amount) * slab.percent_deduction *.01
+			if not slab.to_amount and annual_taxable_earning > slab.from_amount:
+				taxable_amount += (annual_taxable_earning - slab.from_amount) * slab.percent_deduction *.01
 				continue
-			if annual_earning > slab.from_amount and annual_earning < slab.to_amount:
-				taxable_amount += (annual_earning - slab.from_amount) * slab.percent_deduction *.01
-			elif annual_earning > slab.from_amount and annual_earning > slab.to_amount:
+			if annual_taxable_earning > slab.from_amount and annual_taxable_earning < slab.to_amount:
+				taxable_amount += (annual_taxable_earning - slab.from_amount) * slab.percent_deduction *.01
+			elif annual_taxable_earning > slab.from_amount and annual_taxable_earning > slab.to_amount:
 				taxable_amount += (slab.to_amount - slab.from_amount) * slab.percent_deduction * .01
 		return taxable_amount
 
@@ -773,13 +774,21 @@
 
 	def get_period_factor(self, period_start, period_end, start_date=None, end_date=None):
 		# TODO if both deduct checked update the factor to make tax consistent
+		joining_date, relieving_date = frappe.db.get_value("Employee", self.employee, ["date_of_joining", "relieving_date"])
+		if getdate(joining_date) > getdate(period_start):
+			period_start = joining_date
+		if relieving_date and getdate(relieving_date) < getdate(period_end):
+			period_end = relieving_date
+
 		payroll_days = date_diff(period_end, period_start) + 1
 		if start_date and end_date:
 			salary_days = date_diff(end_date, start_date) + 1
 			return flt(payroll_days)/flt(salary_days)
+
 		# if period configured for a year and monthly frequency return 12 to make tax calc consistent
 		if 360 <= payroll_days <= 370 and self.payroll_frequency == "Monthly":
 			return 12
+
 		salary_days = date_diff(self.end_date, self.start_date) + 1
 		return flt(payroll_days)/flt(salary_days)
 
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index 079bec5..746bf8c 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -13,7 +13,8 @@
 from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
 from erpnext.hr.doctype.payroll_entry.payroll_entry import get_month_details
 from erpnext.hr.doctype.employee.test_employee import make_employee
-from erpnext.hr.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration import create_payroll_period, create_exemption_category
+from erpnext.hr.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration \
+	import create_payroll_period, create_exemption_category
 
 class TestSalarySlip(unittest.TestCase):
 	def setUp(self):
@@ -36,8 +37,10 @@
 		no_of_days = self.get_no_of_days()
 		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)
 		make_employee("test_employee@salary.com")
-		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
-		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
+		frappe.db.set_value("Employee", frappe.get_value("Employee",
+			{"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
+		frappe.db.set_value("Employee", frappe.get_value("Employee",
+			{"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
 		ss = make_employee_salary_slip("test_employee@salary.com", "Monthly")
 
 		self.assertEqual(ss.total_working_days, no_of_days[0])
@@ -53,8 +56,10 @@
 		no_of_days = self.get_no_of_days()
 		frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
 		make_employee("test_employee@salary.com")
-		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
-		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
+		frappe.db.set_value("Employee", frappe.get_value("Employee",
+			{"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
+		frappe.db.set_value("Employee", frappe.get_value("Employee",
+			{"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
 		ss = make_employee_salary_slip("test_employee@salary.com", "Monthly")
 
 		self.assertEqual(ss.total_working_days, no_of_days[0] - no_of_days[1])
@@ -100,16 +105,21 @@
 		self.assertEqual(ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1))
 
 		# set relieving date in the same month
-		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", (add_days(nowdate(),-60)))
-		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", relieving_date)
-		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
+		frappe.db.set_value("Employee",frappe.get_value("Employee",
+			{"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", (add_days(nowdate(),-60)))
+		frappe.db.set_value("Employee", frappe.get_value("Employee",
+			{"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", relieving_date)
+		frappe.db.set_value("Employee", frappe.get_value("Employee",
+			{"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
 		ss.save()
 
 		self.assertEqual(ss.total_working_days, no_of_days[0])
 		self.assertEqual(ss.payment_days, getdate(relieving_date).day)
 
-		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
-		frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
+		frappe.db.set_value("Employee", frappe.get_value("Employee",
+			{"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
+		frappe.db.set_value("Employee", frappe.get_value("Employee",
+			{"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
 
 	def test_employee_salary_slip_read_permission(self):
 		make_employee("test_employee@salary.com")
@@ -168,17 +178,22 @@
 
 	def test_tax_for_payroll_period(self):
 		data = {}
-		# test the impact of tax exemption declaration, tax exemption proof submission and deduct check boxes in annual tax calculation
+		# test the impact of tax exemption declaration, tax exemption proof submission
+		# and deduct check boxes in annual tax calculation
 		# as per assigned salary structure 40500 in monthly salary so 236000*5/100/12
 		frappe.db.sql("""delete from `tabPayroll Period`""")
 		frappe.db.sql("""delete from `tabSalary Component`""")
 		payroll_period = create_payroll_period()
 		create_tax_slab(payroll_period)
 		employee = make_employee("test_tax@salary.slip")
-		delete_docs = ["Salary Slip", "Additional Salary",
-						"Employee Tax Exemption Declaration",
-						"Employee Tax Exemption Proof Submission",
-						"Employee Benefit Claim", "Salary Structure Assignment"]
+		delete_docs = [
+			"Salary Slip",
+			"Additional Salary",
+			"Employee Tax Exemption Declaration",
+			"Employee Tax Exemption Proof Submission",
+			"Employee Benefit Claim",
+			"Salary Structure Assignment"
+		]
 		for doc in delete_docs:
 			frappe.db.sql("delete from `tab%s` where employee='%s'" % (doc, employee))
 
@@ -298,12 +313,11 @@
 
 	if not salary_slip:
 		salary_slip = make_salary_slip(salary_structure_doc.name, employee = employee)
-		salary_slip.employee_name = frappe.get_value("Employee", {"name":frappe.db.get_value("Employee", {"user_id": user})}, "employee_name")
+		salary_slip.employee_name = frappe.get_value("Employee",
+			{"name":frappe.db.get_value("Employee", {"user_id": user})}, "employee_name")
 		salary_slip.payroll_frequency = payroll_frequency
 		salary_slip.posting_date = nowdate()
 		salary_slip.insert()
-		# salary_slip.submit()
-		# salary_slip = salary_slip.name
 
 	return salary_slip
 
@@ -338,99 +352,99 @@
 	salary_account = frappe.db.get_value("Account", "Salary - " + frappe.get_cached_value('Company',  company,  'abbr'))
 	if not salary_account:
 		frappe.get_doc({
-		"doctype": "Account",
-		"account_name": "Salary",
-		"parent_account": "Indirect Expenses - " + frappe.get_cached_value('Company',  company,  'abbr'),
-		"company": company
+			"doctype": "Account",
+			"account_name": "Salary",
+			"parent_account": "Indirect Expenses - " + frappe.get_cached_value('Company',  company,  'abbr'),
+			"company": company
 		}).insert()
 	return salary_account
 
 def make_earning_salary_component(setup=False, test_tax=False):
 	data = [
+		{
+			"salary_component": 'Basic Salary',
+			"abbr":'BS',
+			"condition": 'base > 10000',
+			"formula": 'base*.5',
+			"type": "Earning",
+			"amount_based_on_formula": 1
+		},
+		{
+			"salary_component": 'HRA',
+			"abbr":'H',
+			"amount": 3000,
+			"type": "Earning"
+		},
+		{
+			"salary_component": 'Special Allowance',
+			"abbr":'SA',
+			"condition": 'H < 10000',
+			"formula": 'BS*.5',
+			"type": "Earning",
+			"amount_based_on_formula": 1
+		},
+		{
+			"salary_component": "Leave Encashment",
+			"abbr": 'LE',
+			"is_additional_component": 1,
+			"type": "Earning"
+		}
+	]
+	if test_tax:
+		data.extend([
 			{
-				"salary_component": 'Basic Salary',
-				"abbr":'BS',
-				"condition": 'base > 10000',
-				"formula": 'base*.5',
+				"salary_component": "Leave Travel Allowance",
+				"abbr": 'B',
+				"is_flexible_benefit": 1,
 				"type": "Earning",
-				"amount_based_on_formula": 1
+				"pay_against_benefit_claim": 1,
+				"max_benefit_amount": 100000
 			},
 			{
-				"salary_component": 'HRA',
-				"abbr":'H',
-				"amount": 3000,
-				"type": "Earning"
-			},
-			{
-				"salary_component": 'Special Allowance',
-				"abbr":'SA',
-				"condition": 'H < 10000',
-				"formula": 'BS*.5',
+				"salary_component": "Medical Allowance",
+				"abbr": 'B',
+				"is_flexible_benefit": 1,
+				"pay_against_benefit_claim": 0,
 				"type": "Earning",
-				"amount_based_on_formula": 1
+				"max_benefit_amount": 15000
 			},
 			{
-				"salary_component": "Leave Encashment",
-				"abbr": 'LE',
+				"salary_component": "Perfomance Bonus",
+				"abbr": 'B',
 				"is_additional_component": 1,
 				"type": "Earning"
 			}
-		]
-	if test_tax:
-		data.extend([
-						{
-							"salary_component": "Leave Travel Allowance",
-							"abbr": 'B',
-							"is_flexible_benefit": 1,
-							"type": "Earning",
-							"pay_against_benefit_claim": 1,
-							"max_benefit_amount": 100000
-						},
-						{
-							"salary_component": "Medical Allowance",
-							"abbr": 'B',
-							"is_flexible_benefit": 1,
-							"pay_against_benefit_claim": 0,
-							"type": "Earning",
-							"max_benefit_amount": 15000
-						},
-						{
-							"salary_component": "Perfomance Bonus",
-							"abbr": 'B',
-							"is_additional_component": 1,
-							"type": "Earning"
-						}
-					])
+		])
 	if setup or test_tax:
 		make_salary_component(data, test_tax)
 	data.append({
-					"salary_component": 'Basic Salary',
-					"abbr":'BS',
-					"condition": 'base < 10000',
-					"formula": 'base*.2',
-					"type": "Earning",
-					"amount_based_on_formula": 1
-				})
+		"salary_component": 'Basic Salary',
+		"abbr":'BS',
+		"condition": 'base < 10000',
+		"formula": 'base*.2',
+		"type": "Earning",
+		"amount_based_on_formula": 1
+	})
 	return data
 
 def make_deduction_salary_component(setup=False, test_tax=False):
 	data =  [
-				{
-					"salary_component": 'Professional Tax',
-					"abbr":'PT',
-					"condition": 'base > 10000',
-					"formula": 'base*.1',
-					"type": "Deduction",
-					"amount_based_on_formula": 1
-				},
-				{
-					"salary_component": 'TDS',
-					"abbr":'T',
-					"formula": 'base*.1',
-					"type": "Deduction",
-					"amount_based_on_formula": 1
-				}
-			]
+		{
+			"salary_component": 'Professional Tax',
+			"abbr":'PT',
+			"condition": 'base > 10000',
+			"formula": 'base*.1',
+			"type": "Deduction",
+			"amount_based_on_formula": 1
+		},
+		{
+			"salary_component": 'TDS',
+			"abbr":'T',
+			"formula": 'base*.1',
+			"type": "Deduction",
+			"amount_based_on_formula": 1
+		}
+	]
 	if not test_tax:
 		data.append({
 			"salary_component": 'TDS',
@@ -453,48 +467,63 @@
 
 def create_exemption_declaration(employee, payroll_period):
 	create_exemption_category()
-	declaration = frappe.get_doc({"doctype": "Employee Tax Exemption Declaration",
-									"employee": employee,
-									"payroll_period": payroll_period,
-									"company": erpnext.get_default_company()})
-	declaration.append("declarations", {"exemption_sub_category": "_Test Sub Category",
-							"exemption_category": "_Test Category",
-							"amount": 100000})
+	declaration = frappe.get_doc({
+		"doctype": "Employee Tax Exemption Declaration",
+		"employee": employee,
+		"payroll_period": payroll_period,
+		"company": erpnext.get_default_company()
+	})
+	declaration.append("declarations", {
+		"exemption_sub_category": "_Test Sub Category",
+		"exemption_category": "_Test Category",
+		"amount": 100000
+	})
 	declaration.submit()
 
 def create_proof_submission(employee, payroll_period, amount):
 	submission_date = add_months(payroll_period.start_date, random.randint(0, 11))
-	proof_submission = frappe.get_doc({"doctype": "Employee Tax Exemption Proof Submission",
-									"employee": employee,
-									"payroll_period": payroll_period.name,
-									"submission_date": submission_date})
-	proof_submission.append("tax_exemption_proofs", {"exemption_sub_category": "_Test Sub Category",
-				"exemption_category": "_Test Category", "type_of_proof": "Test", "amount": amount})
+	proof_submission = frappe.get_doc({
+		"doctype": "Employee Tax Exemption Proof Submission",
+		"employee": employee,
+		"payroll_period": payroll_period.name,
+		"submission_date": submission_date
+	})
+	proof_submission.append("tax_exemption_proofs", {
+		"exemption_sub_category": "_Test Sub Category",
+		"exemption_category": "_Test Category",
+		"type_of_proof": "Test", "amount": amount
+	})
 	proof_submission.submit()
 	return submission_date
 
 def create_benefit_claim(employee, payroll_period, amount, component):
 	claim_date = add_months(payroll_period.start_date, random.randint(0, 11))
-	frappe.get_doc({"doctype": "Employee Benefit Claim", "employee": employee,
-		"claimed_amount": amount, "claim_date": claim_date, "earning_component":
-		component}).submit()
+	frappe.get_doc({
+		"doctype": "Employee Benefit Claim",
+		"employee": employee,
+		"claimed_amount": amount,
+		"claim_date": claim_date,
+		"earning_component": component
+	}).submit()
 	return claim_date
 
 def create_tax_slab(payroll_period):
-	data = [{
-				"from_amount": 250000,
-				"to_amount": 500000,
-				"percent_deduction": 5
-			},
-			{
-				"from_amount": 500000,
-				"to_amount": 1000000,
-				"percent_deduction": 20
-			},
-			{
-				"from_amount": 1000000,
-				"percent_deduction": 30
-			}]
+	data = [
+		{
+			"from_amount": 250000,
+			"to_amount": 500000,
+			"percent_deduction": 5
+		},
+		{
+			"from_amount": 500000,
+			"to_amount": 1000000,
+			"percent_deduction": 20
+		},
+		{
+			"from_amount": 1000000,
+			"percent_deduction": 30
+		}
+	]
 	payroll_period.taxable_salary_slabs = []
 	for item in data:
 		payroll_period.append("taxable_salary_slabs", item)
@@ -526,9 +555,13 @@
 
 def create_additional_salary(employee, payroll_period, amount):
 	salary_date = add_months(payroll_period.start_date, random.randint(0, 11))
-	frappe.get_doc({"doctype": "Additional Salary", "employee": employee,
-					"company": erpnext.get_default_company(),
-					"salary_component": "Perfomance Bonus",
-					"payroll_date": salary_date,
-					"amount": amount, "type": "Earning"}).submit()
+	frappe.get_doc({
+		"doctype": "Additional Salary",
+		"employee": employee,
+		"company": erpnext.get_default_company(),
+		"salary_component": "Perfomance Bonus",
+		"payroll_date": salary_date,
+		"amount": amount,
+		"type": "Earning"
+	}).submit()
 	return salary_date
diff --git a/erpnext/hr/doctype/skill/__init__.py b/erpnext/hr/doctype/skill/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/skill/__init__.py
diff --git a/erpnext/hr/doctype/skill/skill.js b/erpnext/hr/doctype/skill/skill.js
new file mode 100644
index 0000000..a939ff0
--- /dev/null
+++ b/erpnext/hr/doctype/skill/skill.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Skill', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/hr/doctype/skill/skill.json b/erpnext/hr/doctype/skill/skill.json
new file mode 100644
index 0000000..5182973
--- /dev/null
+++ b/erpnext/hr/doctype/skill/skill.json
@@ -0,0 +1,113 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:skill_name",
+ "beta": 0,
+ "creation": "2019-04-16 09:54:39.486915",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 0,
+ "engine": "InnoDB",
+ "fields": [
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "skill_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": "Skill 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
+  }
+ ],
+ "has_web_view": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2019-04-16 09:55:00.536328",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Skill",
+ "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": "System 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": "HR Manager",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/skill/skill.py b/erpnext/hr/doctype/skill/skill.py
new file mode 100644
index 0000000..8d24212
--- /dev/null
+++ b/erpnext/hr/doctype/skill/skill.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class Skill(Document):
+	pass
diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py
index 313cfc4..a600e75 100644
--- a/erpnext/hr/utils.py
+++ b/erpnext/hr/utils.py
@@ -221,16 +221,30 @@
 
 def validate_tax_declaration(declarations):
 	subcategories = []
-	for declaration in declarations:
-		if declaration.exemption_sub_category in  subcategories:
-			frappe.throw(_("More than one selection for {0} not \
-			allowed").format(declaration.exemption_sub_category), frappe.ValidationError)
-		subcategories.append(declaration.exemption_sub_category)
-		max_amount = frappe.db.get_value("Employee Tax Exemption Sub Category", \
-		declaration.exemption_sub_category, "max_amount")
-		if declaration.amount > max_amount:
-			frappe.throw(_("Max exemption amount for {0} is {1}").format(\
-			declaration.exemption_sub_category, max_amount), frappe.ValidationError)
+	for d in declarations:
+		if d.exemption_sub_category in subcategories:
+			frappe.throw(_("More than one selection for {0} not allowed").format(d.exemption_sub_category))
+		subcategories.append(d.exemption_sub_category)
+
+def get_total_exemption_amount(declarations):
+	exemptions = frappe._dict()
+	for d in declarations:
+		exemptions.setdefault(d.exemption_category, frappe._dict())
+		category_max_amount = exemptions.get(d.exemption_category).max_amount
+		if not category_max_amount:
+			category_max_amount = frappe.db.get_value("Employee Tax Exemption Category", d.exemption_category, "max_amount")
+			exemptions.get(d.exemption_category).max_amount = category_max_amount
+		sub_category_exemption_amount = d.max_amount \
+			if (d.max_amount and flt(d.amount) > flt(d.max_amount)) else d.amount
+
+		exemptions.get(d.exemption_category).setdefault("total_exemption_amount", 0.0)
+		exemptions.get(d.exemption_category).total_exemption_amount += flt(sub_category_exemption_amount)
+
+		if category_max_amount and exemptions.get(d.exemption_category).total_exemption_amount > category_max_amount:
+			exemptions.get(d.exemption_category).total_exemption_amount = category_max_amount
+
+	total_exemption_amount = sum([flt(d.total_exemption_amount) for d in exemptions.values()])
+	return total_exemption_amount
 
 def get_leave_period(from_date, to_date, company):
 	leave_period = frappe.db.sql("""
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
index 59861ce..a7d1d85 100644
--- a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
+++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
@@ -20,13 +20,12 @@
 		for bom in bom_list:
 			try:
 				bom_obj = frappe.get_doc("BOM", bom)
-				bom_obj.get_doc_before_save()
+				bom_obj.load_doc_before_save()
 				updated_bom = bom_obj.update_cost_and_exploded_items(updated_bom)
 				bom_obj.calculate_cost()
 				bom_obj.update_parent_cost()
 				bom_obj.db_update()
-				if (getattr(bom_obj.meta, 'track_changes', False)
-					and bom_obj._doc_before_save and not bom_obj.flags.ignore_version):
+				if (getattr(bom_obj.meta, 'track_changes', False) and not bom_obj.flags.ignore_version):
 					bom_obj.save_version()
 
 				frappe.db.commit()
@@ -37,7 +36,7 @@
 	def validate_bom(self):
 		if cstr(self.current_bom) == cstr(self.new_bom):
 			frappe.throw(_("Current BOM and New BOM can not be same"))
-			
+
 		if frappe.db.get_value("BOM", self.current_bom, "item") \
 			!= frappe.db.get_value("BOM", self.new_bom, "item"):
 				frappe.throw(_("The selected BOMs are not for the same item"))
diff --git a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py
index 575ebeb..02203d2 100644
--- a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py
+++ b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py
@@ -13,19 +13,19 @@
 		old_item_taxes.setdefault(d.item_code, [])
 		old_item_taxes[d.item_code].append(d)
 
-	frappe.reload_doc("accounts", "doctype", "item_tax_template_detail")
-	frappe.reload_doc("accounts", "doctype", "item_tax_template")
-	frappe.reload_doc("stock", "doctype", "item")
-	frappe.reload_doc("stock", "doctype", "item_tax")
-	frappe.reload_doc("selling", "doctype", "quotation_item")
-	frappe.reload_doc("selling", "doctype", "sales_order_item")
-	frappe.reload_doc("stock", "doctype", "delivery_note_item")
-	frappe.reload_doc("accounts", "doctype", "sales_invoice_item")
-	frappe.reload_doc("buying", "doctype", "supplier_quotation_item")
-	frappe.reload_doc("buying", "doctype", "purchase_order_item")
-	frappe.reload_doc("stock", "doctype", "purchase_receipt_item")
-	frappe.reload_doc("accounts", "doctype", "purchase_invoice_item")
-	frappe.reload_doc("accounts", "doctype", "accounts_settings")
+	frappe.reload_doc("accounts", "doctype", "item_tax_template_detail", force=1)
+	frappe.reload_doc("accounts", "doctype", "item_tax_template", force=1)
+	frappe.reload_doc("stock", "doctype", "item", force=1)
+	frappe.reload_doc("stock", "doctype", "item_tax", force=1)
+	frappe.reload_doc("selling", "doctype", "quotation_item", force=1)
+	frappe.reload_doc("selling", "doctype", "sales_order_item", force=1)
+	frappe.reload_doc("stock", "doctype", "delivery_note_item", force=1)
+	frappe.reload_doc("accounts", "doctype", "sales_invoice_item", force=1)
+	frappe.reload_doc("buying", "doctype", "supplier_quotation_item", force=1)
+	frappe.reload_doc("buying", "doctype", "purchase_order_item", force=1)
+	frappe.reload_doc("stock", "doctype", "purchase_receipt_item", force=1)
+	frappe.reload_doc("accounts", "doctype", "purchase_invoice_item", force=1)
+	frappe.reload_doc("accounts", "doctype", "accounts_settings", force=1)
 
 	# for each item that have item tax rates
 	for item_code in old_item_taxes.keys():
@@ -77,6 +77,21 @@
 	item_tax_template = frappe.new_doc("Item Tax Template")
 	item_tax_template.title = "{}--{}".format(parent, item_code) if parent else "Item-{}".format(item_code)
 	for tax_type, tax_rate in iteritems(item_tax_map):
+		if not frappe.db.exists("Account", tax_type):
+			parts = tax_type.strip().split(" - ")
+			account_name = " - ".join(parts[:-1])
+			company = frappe.db.get_value("Company", filters={"abbr": parts[-1]})
+			parent_account = frappe.db.get_value("Account",
+				filters={"account_type": "Tax", "root_type": "Liability", "is_group": 0}, fieldname="parent_account")
+
+			frappe.get_doc({
+				"doctype": "Account",
+				"account_name": account_name,
+				"company": company,
+				"account_type": "Tax",
+				"parent_account": parent_account
+			}).insert()
+
 		item_tax_template.append("taxes", {"tax_type": tax_type, "tax_rate": tax_rate})
 		item_tax_templates.setdefault(item_tax_template.title, {})
 		item_tax_templates[item_tax_template.title][tax_type] = tax_rate
diff --git a/erpnext/portal/product_configurator/utils.py b/erpnext/portal/product_configurator/utils.py
index f02212c..405a6d8 100644
--- a/erpnext/portal/product_configurator/utils.py
+++ b/erpnext/portal/product_configurator/utils.py
@@ -167,13 +167,17 @@
 		if attribute in attribute_list:
 			valid_options.setdefault(attribute, set()).add(attribute_value)
 
+	item_attribute_values = frappe.db.get_all('Item Attribute Value',
+		['parent', 'attribute_value', 'idx'], order_by='parent asc, idx asc')
+	ordered_attribute_value_map = frappe._dict()
+	for iv in item_attribute_values:
+		ordered_attribute_value_map.setdefault(iv.parent, []).append(iv.attribute_value)
+
 	# build attribute values in idx order
-	ordered_attribute_value_map = item_cache.get_ordered_attribute_values()
 	for attr in attributes:
 		valid_attribute_values = valid_options.get(attr.attribute, [])
 		ordered_values = ordered_attribute_value_map.get(attr.attribute, [])
 		attr['values'] = [v for v in ordered_values if v in valid_attribute_values]
-		attr['values'] = valid_attribute_values
 
 	return attributes
 
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 60e72da..45de6eb 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -54,5 +54,8 @@
         "stock/dashboard/item_dashboard.html",
         "stock/dashboard/item_dashboard_list.html",
         "stock/dashboard/item_dashboard.js"
+    ],
+    "js/lms.min.js": [
+        "public/js/education/lms/lms.js"
     ]
 }
diff --git a/erpnext/public/js/communication.js b/erpnext/public/js/communication.js
index 49701b8..5316eb4 100644
--- a/erpnext/public/js/communication.js
+++ b/erpnext/public/js/communication.js
@@ -33,7 +33,7 @@
 
 	make_lead_from_communication: (frm) => {
 		return frappe.call({
-			method: "frappe.email.inbox.make_lead_from_communication",
+			method: "erpnext.crm.doctype.lead.lead.make_lead_from_communication",
 			args: {
 				communication: frm.doc.name
 			},
@@ -48,7 +48,7 @@
 
 	make_issue_from_communication: (frm) => {
 		return frappe.call({
-			method: "frappe.email.inbox.make_issue_from_communication",
+			method: "erpnext.support.doctype.issue.issue.make_issue_from_communication",
 			args: {
 				communication: frm.doc.name
 			},
@@ -63,7 +63,7 @@
 
 	make_opportunity_from_communication: (frm) => {
 		return frappe.call({
-			method: "frappe.email.inbox.make_opportunity_from_communication",
+			method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
 			args: {
 				communication: frm.doc.name
 			},
diff --git a/erpnext/public/js/education/lms/call.js b/erpnext/public/js/education/lms/call.js
new file mode 100644
index 0000000..e35acbd
--- /dev/null
+++ b/erpnext/public/js/education/lms/call.js
@@ -0,0 +1,15 @@
+frappe.ready(() => {
+	frappe.provide('lms');
+
+	lms.call = (method, args) => {
+		const method_path = 'erpnext.www.lms.' + method;
+		return new Promise((resolve, reject) => {
+			return frappe.call({
+				method: method_path,
+				args,
+			})
+			.then(r => resolve(r.message))
+			.fail(reject);
+		});
+	};
+});
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/Article.vue b/erpnext/public/js/education/lms/components/Article.vue
new file mode 100644
index 0000000..eab1424
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/Article.vue
@@ -0,0 +1,44 @@
+<template>
+<div>
+    <ContentTitle :title="contentData.title" :author="contentData.author" :publishDate="contentData.publish_date">
+        <slot></slot>
+    </ContentTitle>
+    <section class="article-content-section">
+        <div>
+            <div class="content" v-html="contentData.content"></div>
+            <div class="text-right">
+            </div>
+            <div class="mt-3 text-right">
+                <a class="text-muted" href="/report"><i class="octicon octicon-issue-opened" title="Report"></i> Report a
+                    Mistake</a>
+            </div>
+        </div>
+    </section>
+</div>
+</template>
+<script>
+import ContentTitle from './ContentTitle.vue'
+export default {
+	props: ['content', 'type'],
+	name: 'Article',
+	data() {
+    	return {
+    		contentData: ''
+    	}
+    },
+    mounted() {
+    	this.getContent().then(data => this.contentData = data);
+    },
+    methods: {
+        getContent() {
+            return lms.call('get_content', {
+                content_type: this.type,
+                content: this.content
+            })
+        }
+    },
+    components: {
+        ContentTitle
+    }
+};
+</script>
diff --git a/erpnext/public/js/education/lms/components/Breadcrumb.vue b/erpnext/public/js/education/lms/components/Breadcrumb.vue
new file mode 100644
index 0000000..1b617a3
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/Breadcrumb.vue
@@ -0,0 +1,56 @@
+<template>
+	<div>
+		<nav aria-label="breadcrumb">
+			<ol class="breadcrumb">
+				<li v-for="(route, index) in routeData" class="breadcrumb-item active" aria-current="page">
+					<router-link v-if="index != routeData.length - 1" :to="route.route">
+						{{ route.label }}
+					</router-link>
+					<span v-else>{{ route.label }}</span>
+				</li>
+			</ol>
+		</nav>
+	</div>
+</template>
+<script type="text/javascript">
+	export default {
+		name: "Breadcrumb",
+		data() {
+			return {
+				routeName: this.$route.name,
+				routeParams: this.$route.params,
+				routeData: [{
+					label: "All Programs",
+					route: "/List/Program"
+				}]
+			}
+		},
+		mounted() {
+			this.buildBreadcrumb()
+		},
+		methods: {
+			buildBreadcrumb() {
+				if(this.routeName == 'program') {
+					return
+				}
+				if(this.routeName == 'course') {
+					let routeObject = {
+						label: this.routeParams.program_name,
+						route: `/Program/${this.routeParams.program_name}`
+					}
+					this.routeData.push(routeObject)
+				}
+				if(this.routeName == 'content') {
+					this.routeData.push({
+						label: this.routeParams.program_name,
+						route: `/Program/${this.routeParams.program_name}`
+					})
+					this.routeData.push({
+						label: this.routeParams.course_name,
+						route: `/Program/${this.routeParams.program_name}/${this.routeParams.course_name}`
+					})
+				}
+			}
+		}
+	};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/Button.vue b/erpnext/public/js/education/lms/components/Button.vue
new file mode 100644
index 0000000..4d8df4b
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/Button.vue
@@ -0,0 +1,25 @@
+<template>
+	<button :class="classList" v-on="$listeners" v-bind="$attrs" @click="goToRoute">
+		<slot></slot>
+	</button>
+</template>
+<script>
+export default {
+	name: 'AButton',
+	props: ['type', 'size', 'route'],
+	computed: {
+		classList() {
+			return [
+				'btn',
+				'btn-' + this.type,
+				'btn-' + this.size
+			]
+		}
+	},
+	methods: {
+		goToRoute() {
+			this.$router.push(this.route);
+		}
+	}
+}
+</script>
diff --git a/erpnext/public/js/education/lms/components/CardList.vue b/erpnext/public/js/education/lms/components/CardList.vue
new file mode 100644
index 0000000..298627f
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/CardList.vue
@@ -0,0 +1,28 @@
+<template>
+	<section class="featured-products-section" :class='sectionType'>
+	<h5 class='featured-heading' v-html="title"></h5>
+	<div class="featured-products row">
+		<!-- <p class='lead text-center' v-html="description"></p> -->
+		<slot name="card-list-slot"></slot>
+	</div>
+	<div class='mt-4 text-center'>
+		<slot name="list-bottom"></slot>
+	</div>
+</section>
+</template>
+<script>
+export default {
+    props:['title', 'description', 'sectionType'],
+    name: "CardList",
+};
+</script>
+<style scoped>
+
+.featured-heading {
+    text-transform: uppercase;
+    letter-spacing: 0.5px;
+    font-size: 12px;
+    font-weight: 500;
+}
+
+</style>
diff --git a/erpnext/public/js/education/lms/components/ContentNavigation.vue b/erpnext/public/js/education/lms/components/ContentNavigation.vue
new file mode 100644
index 0000000..a07c0f8
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/ContentNavigation.vue
@@ -0,0 +1,40 @@
+<template>
+	<div class="nav-buttons">
+		<button class='btn btn-outline-secondary' @click="$router.go(-1)">Back</button>
+		<button v-if="nextContent" class='btn btn-primary' @click="goNext()">Next</button>
+		<button v-else class='btn btn-primary' @click="finish()">Finish Topic</button>
+	</div>
+</template>
+
+<script>
+export default {
+	props: ['nextContent', 'nextContentType'],
+	name: 'ContentNavigation',
+	methods: {
+		addActivity() {
+			if(this.$route.params.type != "Quiz"){
+				console.log("Adding Activity")
+				lms.call("add_activity",
+					{
+						course: this.$route.params.course_name,
+						content_type: this.$route.params.type,
+						content: this.$route.params.content,
+					}
+				)
+			}
+		},
+		goNext() {
+			this.addActivity()
+			this.$router.push({ name: 'content', params: { course: this.$route.params.course_name, type:this.nextContentType, content:this.nextContent }})
+		},
+		finish() {
+			this.addActivity()
+			this.$router.push({ name: 'course', params: { program_name: this.$route.params.program_name, course_name: this.$route.params.course_name}})
+			lms.trigger('course-completed', course_name);
+		}
+	}
+};
+</script>
+
+<style lang="css" scoped>
+</style>
diff --git a/erpnext/public/js/education/lms/components/ContentTitle.vue b/erpnext/public/js/education/lms/components/ContentTitle.vue
new file mode 100644
index 0000000..a488ab8
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/ContentTitle.vue
@@ -0,0 +1,29 @@
+<template>
+    <section class='article-top-section video-section-bg'>
+        <div>
+            <div class="row">
+                <div class="col-md-8">
+                    <h2>{{ title }}</h2>
+                    <span v-if="typeof author !== 'undefined' || author !== null" class="text-muted">
+                        <span v-if="publishDate">Published on {{ publishDate }}</span>
+                        <span v-if="author">— {{ author }}</span>
+                    </span>
+                </div>
+                <div class="col-md-4 text-right">
+                    <slot></slot>
+                </div>
+            </div>
+            <hr>
+        </div>
+    </section>
+</template>
+
+<script>
+export default {
+    props: ['title', 'publishDate', 'author'],
+    name: 'ContentTitle',
+};
+</script>
+
+<style lang="css" scoped>
+</style>
diff --git a/erpnext/public/js/education/lms/components/CourseCard.vue b/erpnext/public/js/education/lms/components/CourseCard.vue
new file mode 100644
index 0000000..16f8873
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/CourseCard.vue
@@ -0,0 +1,92 @@
+<template>
+    <div class="py-3 col-md-4 col-sm-12">
+        <div class="card h-100">
+            <div class="card-hero-img" v-if="course.hero_image" v-bind:style="{ 'background-image': 'url(' + image + ')' }"></div>
+            <div v-else class="card-image-wrapper">
+                <div class="image-body">{{ course.course_name }}</div>
+            </div>
+            <div class='card-body'>
+                <h5 class="card-title">{{ course.course_name }}</h5>
+                <span class="course-list text-muted" id="getting-started">
+                    Topics
+                    <ul class="mb-0 mt-1" style="padding-left: 1.5em;">
+                        <li v-for="topic in course.topics" :key="topic.name">
+                            <div>{{ topic.topic_name }}</div>
+                        </li>
+                    </ul>
+                </span>
+            </div>
+            <div class='p-3' style="display: flex; justify-content: space-between;">
+                <div>
+                    <span v-if="complete"><i class="mr-2 text-success fa fa-check-circle" aria-hidden="true"></i>Course Complete</span>
+                </div>
+                <div class='text-right'>
+                    <a-button
+                        :type="'primary'"
+                        size="sm"
+                        :route="courseRoute"
+                    >
+                        {{ buttonName }}
+                    </a-button>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import AButton from './Button.vue';
+
+export default {
+    props: ['course', 'program_name'],
+    name: "CourseCard",
+    components: {
+        AButton
+    },
+    data() {
+        return {
+            courseDetails: {},
+        }
+    },
+    mounted() {
+        if(lms.store.checkLogin()) this.getCourseDetails().then(data => this.courseDetails = data)
+    },
+    computed: {
+        courseRoute() {
+            return `${this.program_name}/${this.course.name}`
+        },
+        complete() {
+            if(lms.store.checkProgramEnrollment(this.program_name)){
+                if (this.courseDetails.flag === "Completed" ) {
+                    return true
+                }
+                else {
+                    return false
+                }
+            }
+            else {
+                return false
+            }
+        },
+        isLogin() {
+            return lms.store.checkLogin()
+        },
+        buttonName() {
+            if(lms.store.checkProgramEnrollment(this.program_name)){
+                return "Start Course"
+            }
+            else {
+                return "Explore"
+            }
+        }
+    },
+    methods: {
+        getCourseDetails() {
+			return lms.call('get_student_course_details', {
+                    course_name: this.course.name,
+                    program_name: this.program_name
+				})
+        },
+    }
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/Navbar.vue b/erpnext/public/js/education/lms/components/Navbar.vue
new file mode 100644
index 0000000..f3f3ce4
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/Navbar.vue
@@ -0,0 +1,85 @@
+<template>
+<nav class="navbar navbar-light bg-white navbar-expand-lg sticky-top shadow-sm">
+    <div class="container">
+        <a class="navbar-brand" href="/lms">
+            <span>{{ portal.title }}</span>
+        </a>
+        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
+            <span class="navbar-toggler-icon"></span>
+        </button>
+
+        <div class="collapse navbar-collapse" id="navbarSupportedContent">
+            <ul class="navbar-nav mr-auto">
+
+                <li class="nav-item">
+                    <a class="nav-link" href="lms#/List/Program">
+                        All Programs
+                    </a>
+                </li>
+
+                <li class="nav-item">
+                    <a class="nav-link" href="/lms#/Profile">
+                        Profile
+                    </a>
+                </li>
+            </ul>
+            <ul class="navbar-nav ml-auto">
+                <!-- post login tools -->
+                <li v-if="isLogin" class="nav-item dropdown logged-in" id="website-post-login" data-label="website-post-login">
+                    <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
+                        <span class="user-image-wrapper">
+                            <span class="avatar avatar-small" :title="fullName">
+                                    <span class="avatar-frame" :style="avatarStyle" :title="fullName"></span>
+                            </span>
+                        </span>
+                        <span class="full-name">{{ fullName }}</span>
+                        <b class="caret"></b>
+                    </a>
+                    <ul class="dropdown-menu dropdown-menu-right" role="menu">
+                        <a class="dropdown-item" href="/me" rel="nofollow"> My Account </a>
+                        <a class="dropdown-item" href="/?cmd=web_logout" rel="nofollow"> Logout </a>
+                    </ul>
+                </li>
+
+                <li v-else class="nav-item">
+                    <a class="nav-link btn-login-area" href="/login">Login</a>
+                </li>
+            </ul>
+        </div>
+    </div>
+</nav>
+</template>
+<script>
+export default {
+    name: "Home",
+    data() {
+    	return{
+            portal: {},
+            avatar: frappe.user_image,
+            fullName: frappe.full_name,
+            isLogin: frappe.is_user_logged_in()
+    	}
+    },
+	mounted() {
+        this.getPortalDetails().then(data => this.portal = data);
+    },
+    methods: {
+        getPortalDetails() {
+            return lms.call("get_portal_details")
+        }
+    },
+    computed: {
+		avatarStyle() {
+			return `background-image: url("${this.avatar}")`
+        },
+        // isLogin() {
+        //     return frappe.is_user_logged_in()
+        // },
+	}
+};
+</script>
+<style scoped>
+a {
+	text-decoration: none;
+}
+</style>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/ProfileInfo.vue b/erpnext/public/js/education/lms/components/ProfileInfo.vue
new file mode 100644
index 0000000..6f3e8f1
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/ProfileInfo.vue
@@ -0,0 +1,85 @@
+<template>
+<section>
+		<div class="py-5">
+			<div class="row">
+				<div class="col-sm-12">
+					<div>
+						<h3>{{ fullName }}</h3>
+						<ul>
+							<li class="row">
+								<div class="col-md-3 col-sm-4 pr-0 text-muted">Email:</div>
+								<div class="col-md-9 col-sm-8">{{ email }}</div>
+							</li>
+							<li v-if="joiningDate" class="row">
+								<div class="col-md-3 col-sm-4 pr-0 text-muted">Date of Joining:</div>
+								<div class="col-md-9 col-sm-8">{{ joiningDate }}</div>
+							</li>
+							<li class="row">
+								<div class="col-md-3 col-sm-4 pr-0 text-muted">Programs Enrolled:</div>
+								<div class="col-md-9 col-sm-8">
+									<ul v-if="enrolledPrograms">
+										<li v-for="program in enrolledPrograms" :key="program">{{ program }}</li>
+									</ul>
+									<span v-else>None</span>
+								</div>
+							</li>
+						</ul>
+					</div>
+					<a href="/update-profile" class="edit-button text-muted">Edit Profile</a>
+				</div>
+			</div>
+			<div ></div>
+		</div>
+	</section>
+</template>
+<script>
+
+export default {
+	props: ['enrolledPrograms'],
+	name: "ProfileInfo",
+	data() {
+		return {
+			avatar: frappe.user_image,
+			fullName: frappe.full_name,
+			abbr: frappe.get_abbr(frappe.get_cookie("full_name")),
+			email: frappe.session.user,
+			joiningDate: ''
+		}
+	},
+	mounted(){
+		this.getJoiningDate().then(data => {
+			if(data) {
+				this.joiningDate = lms.moment(String(data)).format('D MMMM YYYY')
+			}
+		})
+	},
+	computed: {
+		avatarStyle() {
+			return `background-image: url("${this.avatar}")`
+		},
+	},
+	methods: {
+		getJoiningDate() {
+			return lms.call("get_joining_date")
+		}
+	}
+};
+</script>
+<style scoped>
+	.edit-button {
+		position: absolute;
+		top: 0;
+		right: 0;
+	}
+
+	.standard-image {
+		font-size: 72px;
+		border-radius: 6px;
+	}
+
+	ul {
+		list-style-type: none;
+		padding: 0;
+		margin: 0
+	}
+</style>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/ProgramCard.vue b/erpnext/public/js/education/lms/components/ProgramCard.vue
new file mode 100644
index 0000000..20de085
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/ProgramCard.vue
@@ -0,0 +1,82 @@
+<template>
+<div class='py-3 col-md-4 col-sm-12'>
+    <div class="card h-100">
+        <router-link :to="'/Program/' + program.name">
+            <div class="card-hero-img" v-if="program.hero_image" v-bind:style="{ 'background-image': 'url(' + image + ')' }"></div>
+            <div v-else class="card-image-wrapper text-center">
+                <div class="image-body">{{ program.program_name }}</div>
+            </div>
+            <div class='card-body'>
+                <h5 class='card-title'>{{ program.program_name }}</h5>
+                <div class="text-muted">{{ program.description.substring(0,200) }}...</div>
+            </div>
+        </router-link>
+        <div class='text-right p-3'>
+            <button v-if="program.intro_video" class='btn btn-light btn-sm' data-toggle="modal" data-target="#videoModal">Watch Intro</button>
+            <a-button v-if="enrolled" type="dark" size="sm" :route="programPageRoute">
+                {{ buttonName }}
+            </a-button>
+            <button v-else-if="isLogin" class='btn btn-dark btn-sm' @click="enroll()">{{ enrollButton }}</button>
+            <a v-else class='btn btn-secondary btn-sm' href="/login#signup">Sign Up</a>
+        </div>
+        <VideoModal v-if="program.intro_video" :title="program.program_name" :video="program.intro_video"/>
+    </div>
+</div>
+</template>
+<script>
+import AButton from './Button.vue';
+import VideoModal from './VideoModal.vue';
+export default {
+    props: ['program', 'enrolled'],
+    name: "ProgramCard",
+    data() {
+    	return {
+            isLogin: frappe.is_user_logged_in(),
+            enrollButton: 'Enroll Now',
+            programRoute: { name: 'program', params: { program_name: this.program.name }},
+            image: "'" + this.program.hero_image + "'"
+    	};
+    },
+    methods: {
+        enroll() {
+            this.enrollButton = 'Enrolling...'
+            lms.call('enroll_in_program', {
+                program_name: this.program.name,
+            }).then(data => {
+                lms.store.updateEnrolledPrograms()
+                this.$router.push(this.programRoute)
+            })
+        }
+    },
+    computed: {
+        buttonName() {
+            if(this.enrolled){
+                return "Start Program"
+            }
+            else {
+                return "Enroll"
+            }
+        },
+        programPageRoute() {
+            return this.programRoute
+        },
+        isEnrolled() {
+            return lms.store.enrolledPrograms.includes(this.program.name)
+        }
+    },
+    components: {
+        AButton,
+        VideoModal
+    }
+};
+</script>
+
+<style lang="css" scoped>
+    a {
+        text-decoration: none;
+        color: black;
+    }
+    a.btn-secondary {
+        color: white !important;
+    }
+</style>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/ProgressCard.vue b/erpnext/public/js/education/lms/components/ProgressCard.vue
new file mode 100644
index 0000000..66b61f6
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/ProgressCard.vue
@@ -0,0 +1,89 @@
+<template>
+    <div class='py-3 col-md-4 col-sm-12'>
+        <div class="card h-100">
+            <div class='card-body'>
+                <router-link :to="'/Program/' + programData.name">
+                    <h5 class='card-title'>{{ programData.program }}</h5>
+                </router-link>
+                <span class="course-list text-muted" id="getting-started">
+                    Courses
+                    <ul class="mb-0 mt-1 list-unstyled" style="padding-left: 1.5em;">
+                        <li v-for="item in programData.progress" :key="item.name">
+                            <span v-if="item.is_complete"><i class="text-success fa fa-check-circle" aria-hidden="true"></i></span>
+                            <span v-else><i class="text-secondary fa fa-circle-o" aria-hidden="true"></i></span>
+                            {{ item.course_name }}
+                        </li>
+                    </ul>
+                </span>
+            </div>
+            <div class='p-3' style="display: flex; justify-content: space-between;">
+                <div></div>
+                <div class='text-right'>
+                    <a-button
+                        :type="buttonType"
+                        size="sm btn-block"
+                        :route="programRoute"
+                    >
+                        {{ buttonName }}
+                    </a-button>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+import AButton from './Button.vue';
+export default {
+    props: ['program'],
+    name: "ProgressCard",
+    data() {
+    	return {
+            programData: {}
+    	};
+    },
+    mounted() {
+        this.getProgramProgress().then(data => this.programData = data)
+    },
+    methods: {
+       getProgramProgress() {
+			return lms.call('get_program_progress', {
+                    program_name: this.program
+				})
+        },
+    },
+    computed: {
+        programRoute() {
+            return {name: 'program', params: {program_name: this.program}}
+        },
+        buttonType() {
+            if (this.programData.percentage == 100 ){
+                return "success"
+            }
+            else if (this.programData.percentage == "0" ) {
+                return "secondary"
+            }
+            else {
+                return "info"
+            }
+        },
+        buttonName() {
+            if (this.programData.percentage == 100 ){
+                return "Program Complete"
+            }
+            else {
+                return `${this.programData.percentage}% Completed`
+            }
+        }
+    },
+    components: {
+        AButton
+    },
+};
+</script>
+<style scoped>
+
+	a {
+		text-decoration: none;
+		color: black;
+	}
+</style>
diff --git a/erpnext/public/js/education/lms/components/Quiz.vue b/erpnext/public/js/education/lms/components/Quiz.vue
new file mode 100644
index 0000000..0a6199a
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/Quiz.vue
@@ -0,0 +1,119 @@
+<template>
+	<section class="quiz-section">
+    <div>
+        <div class="row">
+            <div class="col-md-8">
+                <h2>{{ content }}</h2>
+            </div>
+        </div>
+        <div class="content">
+            <hr>
+            <div id="quiz" :name="content">
+                <div id="quiz-body">
+					<component v-for="question in quizData" :key="question.name" v-bind:is="question.type" :question="question" @updateResponse="updateResponse" :isDisabled="isDisabled"></component>
+                </div>
+                <div class="mt-3">
+                    <div>
+                        <div v-if="isDisabled || submitted" id="post-quiz-actions" class="row">
+                            <div class="col-md-8 text-left">
+                                <span v-html="message"></span>
+                            </div>
+                            <div class="col-md-4 text-right">
+                                <slot></slot>
+                            </div>
+                        </div>
+                        <div v-else id="quiz-actions" class="text-right">
+                            <button class='btn btn-outline-secondary' type="reset" :disabled="isDisabled">Reset</button>
+                            <button class='btn btn-primary' @click="submitQuiz" type="button" :disabled="isDisabled">Submit</button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="mt-3 text-right">
+            <a class="text-muted" href="/report"><i class="octicon octicon-issue-opened" title="Report"></i> Report a
+                Mistake</a>
+        </div>
+    </div>
+</section>
+</template>
+
+<script>
+import QuizSingleChoice from "./Quiz/QuizSingleChoice.vue"
+import QuizMultipleChoice from "./Quiz/QuizMultipleChoice.vue"
+
+export default {
+	props: ['content', 'type'],
+	name: 'Quiz',
+	data() {
+    	return {
+    		quizData: '',
+    		quizResponse: {},
+            score: '',
+            submitted: false,
+            isDisabled: false,
+            quizStatus: {},
+    	}
+    },
+    mounted() {
+    	this.getQuizWithoutAnswers().then(data => {
+    		this.quizData = data.quizData
+            this.quizStatus = data.status
+            this.isDisabled = data.status.is_complete
+    	});
+    },
+    components: {
+    	'SingleChoice': QuizSingleChoice,
+        'MultipleChoice': QuizMultipleChoice
+    },
+    methods: {
+        getQuizWithoutAnswers() {
+            return lms.call("get_quiz_without_answers",
+                {
+                    quiz_name: this.content,
+                    course_name: this.$route.params.course_name
+                }
+    	    )
+        },
+		updateResponse(res) {
+            this.quizResponse[res.question] = res.option
+		},
+		submitQuiz() {
+			lms.call("evaluate_quiz",
+				{
+					quiz_response: this.quizResponse,
+                    quiz_name: this.content,
+                    course: this.$route.params.course_name
+				}
+            ).then(data => {
+                this.score = data
+                this.submitted = true
+                this.quizResponse = null
+			});
+		}
+	},
+    computed: {
+      currentComponent: function() {
+        if(this.quizData.type === "MultipleChoice") {
+            return 'QuizMultipleChoice'
+        }
+        else {
+            return 'QuizSingleChoice'
+        }
+      },
+      message: function() {
+        if(this.submitted) {
+            return '<h3>Your Score: <span id="result">'+ this.score +'</span></h3>'
+        }
+        let message = '<h4>You have exhausted all attempts for this quiz.</h4>'
+        if(this.quizStatus.result == 'Pass') {
+            message = "<h4>You have successfully completed this quiz.</h4>Score: " + this.quizStatus.score
+        }
+        return message
+      }
+    },
+};
+</script>
+
+<style lang="css" scoped>
+</style>
diff --git a/erpnext/public/js/education/lms/components/Quiz/QuizMultipleChoice.vue b/erpnext/public/js/education/lms/components/Quiz/QuizMultipleChoice.vue
new file mode 100644
index 0000000..338b1ac
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/Quiz/QuizMultipleChoice.vue
@@ -0,0 +1,34 @@
+<template>
+	<div class="question mt-4">
+    <h5>{{ question.question }}</h5>
+    <div class="options ml-2">
+        <div v-for="option in question.options" :key="option.name" class="form-check pb-1">
+            <input v-model="checked" class="form-check-input" type="checkbox" :name="question.name" :id="option.name" :value="option.name" @change="emitResponse(question.name, option.name)" :disabled="isDisabled">
+            <label class="form-check-label" :for="option.name">
+                {{ option.option }}
+            </label>
+        </div>
+    </div>
+</div>
+</template>
+
+<script>
+export default {
+	props: ['question', 'isDisabled'],
+	name: 'QuizSingleChoice',
+    data() {
+        return {
+            checked: []
+        }
+    },
+	methods: {
+		emitResponse(q, o) {
+            console.log(this.checked)
+			this.$emit('updateResponse', {'question':q , 'option': this.checked, 'type': this.question.type})
+		}
+	}
+};
+</script>
+
+<style lang="css" scoped>
+</style>
diff --git a/erpnext/public/js/education/lms/components/Quiz/QuizSingleChoice.vue b/erpnext/public/js/education/lms/components/Quiz/QuizSingleChoice.vue
new file mode 100644
index 0000000..235cbce
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/Quiz/QuizSingleChoice.vue
@@ -0,0 +1,28 @@
+<template>
+	<div class="question mt-4">
+    <h5>{{ question.question }}</h5>
+    <div class="options ml-2">
+        <div v-for="option in question.options" :key="option.name" class="form-check pb-1">
+            <input class="form-check-input" type="radio" :name="question.name" :id="option.name" :value="option.name" @change="emitResponse(question.name, option.name)" :disabled="isDisabled">
+            <label class="form-check-label" :for="option.name">
+                {{ option.option }}
+            </label>
+        </div>
+    </div>
+</div>
+</template>
+
+<script>
+export default {
+	props: ['question', 'isDisabled'],
+	name: 'QuizSingleChoice',
+	methods: {
+		emitResponse(q, o) {
+			this.$emit('updateResponse', {'question':q , 'option': o, 'type': this.question.type})
+		}
+	}
+};
+</script>
+
+<style lang="css" scoped>
+</style>
diff --git a/erpnext/public/js/education/lms/components/ScoreCard.vue b/erpnext/public/js/education/lms/components/ScoreCard.vue
new file mode 100644
index 0000000..80b12cb
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/ScoreCard.vue
@@ -0,0 +1,60 @@
+<template>
+    <div v-if="quizData" class='py-3 col-md-4 col-sm-12'>
+        <div class="card h-100">
+            <div class='card-body'>
+                <h5 class='card-title'>{{ quizData.program }}</h5>
+                <div v-for="attempt in quizData.quiz_attempt" :key="attempt.content" class="course-list" id="getting-started">
+                    <div>
+                        {{ attempt.content }}
+                        <ul v-if="attempt.is_complete">
+                            <li><span class="text-muted">Score: </span>{{ attempt.score }}</li>
+                            <li><span class="text-muted">Status: </span>{{attempt.result }}</li>
+                        </ul>
+                        <span v-else>- Unattempted</span>
+                    </div>
+                </div>
+            </div>
+            <div class='p-3' style="display: flex; justify-content: space-between;">
+                <div></div>
+                <div class='text-right'>
+                    <a-button
+                            :type="'primary'"
+                            size="sm btn-block"
+                            :route="programRoute"
+                        >
+                            Go To Program
+                        </a-button>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+import AButton from './Button.vue';
+export default {
+    props: ['program'],
+    name: "ScoreCard",
+    data() {
+    	return {
+            quizData: {}
+    	};
+    },
+    mounted() {
+        this.getQuizProgress().then(data => this.quizData = data)
+    },
+    methods: {
+       getQuizProgress() {
+			return lms.call('get_quiz_progress_of_program', {
+                    program_name: this.program
+				})
+        },
+        programRoute() {
+            return {name: 'program', params: {program_name: this.program}}
+        },
+    },
+    components: {
+        AButton
+    },
+};
+</script>
+
diff --git a/erpnext/public/js/education/lms/components/TopSection.vue b/erpnext/public/js/education/lms/components/TopSection.vue
new file mode 100644
index 0000000..c27d003
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/TopSection.vue
@@ -0,0 +1,27 @@
+<template>
+<div class="hero">
+	<h1 class="text-center" v-html="title"></h1>
+	<p class='text-center' v-html="description"></p>
+	<p class="text-center padding">
+		<slot></slot>
+	</p>
+</div>
+</template>
+<script>
+
+export default {
+	props: ['title', 'description'],
+    name: "TopSection",
+};
+</script>
+<style scoped>
+	.hero {
+		padding-top: 50px;
+		padding-bottom: 100px;
+	}
+
+	.hero h1 {
+		font-size: 40px;
+		font-weight: 200;
+	}
+</style>
diff --git a/erpnext/public/js/education/lms/components/TopSectionButton.vue b/erpnext/public/js/education/lms/components/TopSectionButton.vue
new file mode 100644
index 0000000..0fa49d4
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/TopSectionButton.vue
@@ -0,0 +1,49 @@
+<template>
+    <button v-if="isLoggedIn" class='btn btn-primary btn-md' @click="primaryAction()">{{ buttonName }}</button>
+	<a v-else class='btn btn-primary btn-md' href="/login#signup">{{ buttonName }}</a>
+</template>
+<script>
+export default {
+    name: "TopSectionButton",
+    data() {
+        return {
+            buttonName: '',
+            isLoggedIn: lms.store.checkLogin(),
+            nextContent: '',
+            nextContentType: '',
+            nextCourse: '',
+            link: '',
+        }
+    },
+    mounted() {
+        this.computeButtons()
+    },
+    methods: {
+        computeButtons(){
+            if(this.isLoggedIn){
+                    this.buttonName = 'Explore Programs'
+            }
+            else{
+                this.buttonName = 'Sign Up'
+            }
+        },
+        primaryAction() {
+            if(this.$route.name == 'home'){
+                this.$router.push('List/Program');
+            }
+            else if(this.$route.name == 'program' && lms.store.enrolledPrograms.includes(this.$route.params.program_name)){
+                this.$router.push({ name: 'content', params: { program_name: this.$route.params.program_name, course: this.nextCourse, type: this.nextContentType, content: this.nextContent}})
+            }
+            else {
+                lms.call("enroll_in_program",
+                    {
+                        program_name: this.$route.params.program_name,
+                        student_email_id: frappe.session.user
+                    }
+                )
+                lms.store.updateEnrolledPrograms()
+            }
+        },
+    }
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/TopicCard.vue b/erpnext/public/js/education/lms/components/TopicCard.vue
new file mode 100644
index 0000000..4cb8e85
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/TopicCard.vue
@@ -0,0 +1,112 @@
+
+<template>
+    <div class="py-3 col-md-4 col-sm-12">
+        <div class="card h-100">
+            <div class="card-hero-img" v-if="topic.hero_image" v-bind:style="{ 'background-image': 'url(' + image + ')' }"></div>
+            <div v-else class="card-image-wrapper">
+                <div class="image-body">{{ topic.topic_name }}</div>
+            </div>
+            <div class='card-body'>
+                <h5 class="card-title">{{ topic.topic_name }}</h5>
+                <span class="course-list text-muted" id="getting-started">
+                    Content
+                    <ul class="mb-0 mt-1" style="padding-left: 1.5em;">
+                        <li v-for="content in topic.topic_content" :key="content.name">
+                            <router-link v-if="isLogin" tag="a" :class="'text-muted'" :to="{name: 'content', params:{program_name: program_name, topic:topic.name, course_name: course_name, type:content.content_type, content: content.content} }">
+                                {{ content.content }}
+                            </router-link>
+                            <div v-else><span style="padding-right: 0.4em"></span>{{ content.content }}</div>
+                        </li>
+                    </ul>
+                </span>
+            </div>
+            <div v-if="isLogin" class='p-3' style="display: flex; justify-content: space-between;">
+                <div>
+                    <span v-if="complete"><i class="mr-2 text-success fa fa-check-circle" aria-hidden="true"></i>Course Complete</span>
+                </div>
+                <div class='text-right'>
+                    <a-button
+                    :type="'primary'"
+                    size="sm"
+                    :route="firstContentRoute"
+                >
+                    {{ buttonName }}
+                </a-button>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import AButton from './Button.vue';
+
+export default {
+    props: ['topic', 'course_name', 'program_name'],
+    name: "TopicCard",
+    data() {
+        return {
+            topicDetails: {}
+        }
+    },
+    mounted() {
+        if(lms.store.checkLogin()) this.gettopicDetails().then(data => this.topicDetails = data)
+    },
+    components: {
+        AButton
+    },
+    computed: {
+        firstContentRoute() {
+            if(lms.store.checkLogin()){
+                return `/Program/${this.program_name}/${this.course_name}/${this.topic.name}/${this.topicDetails.content_type}/${this.topicDetails.content}`
+            }
+            else {
+                return {}
+            }
+        },
+        complete() {
+            if(lms.store.checkProgramEnrollment(this.program_name)){
+                if (this.topicDetails.flag === "Completed" ) {
+                    return true
+                }
+                else {
+                    return false
+                }
+            }
+            else {
+                return false
+            }
+        },
+        isLogin() {
+            // return lms.store.checkProgramEnrollment(this.program_name)
+            return lms.store.checkLogin()
+        },
+        buttonName() {
+            if(lms.store.checkProgramEnrollment(this.program_name)){
+                if (this.topicDetails.flag == 'Continue'){
+                    return 'Continue'
+                }
+                else {
+                    return 'Start Topic'
+                }
+            }
+            else {
+                return "Explore"
+            }
+        }
+    },
+    methods: {
+        iconClass(content_type) {
+            if(content_type == 'Video') return 'fa fa-play'
+            if(content_type == 'Article') return 'fa fa-file-text-o'
+            if(content_type == 'Quiz') return 'fa fa-question-circle-o'
+        },
+        gettopicDetails() {
+			return lms.call('get_student_topic_details', {
+                    topic_name: this.topic.name,
+                    course_name: this.course_name,
+				})
+        },
+    }
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/Video.vue b/erpnext/public/js/education/lms/components/Video.vue
new file mode 100644
index 0000000..27f922f
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/Video.vue
@@ -0,0 +1,64 @@
+<template>
+<div>
+    <section class='mt-2'>
+    <div>
+        <div class="mt-3 row">
+            <div class="col-md-8">
+                <h2>{{ contentData.name }}</h2>
+                <span class="text-muted">
+                    <i class="octicon octicon-clock" title="Duration"></i> {{ contentData.duration }} Mins
+                    &mdash; Published on {{ contentData.publish_date }}.
+                </span>
+            </div>
+            <div class="col-md-4 text-right">
+                <slot></slot>
+            </div>
+        </div>
+        <youtube-player :url="contentData.url" class="mt-3"/>
+        <hr>
+    </div>
+</section>
+<section class="video-description-section">
+    <div>
+        <div class="content" v-html="contentData.description">
+        </div>
+        <div class="text-right hidden">
+            <a class='btn btn-outline-secondary' href="/classrooms/module">Previous</a>
+            <a class='btn btn-primary' href="/classrooms/module">Next</a>
+        </div>
+        <div class="mt-3 text-right">
+            <a class="text-muted" href="/report"><i class="octicon octicon-issue-opened" title="Report"></i> Report a
+                Mistake</a>
+        </div>
+    </div>
+</section>
+</div>
+</template>
+<script>
+import YoutubePlayer from './YoutubePlayer.vue'
+
+export default {
+	props: ['content', 'type'],
+	name: 'Video',
+	data() {
+    	return {
+            contentData: '',
+    	}
+    },
+    components: {
+        YoutubePlayer
+    },
+    mounted() {
+        this.getContent()
+            .then(data => this.contentData = data)
+    },
+    methods: {
+        getContent() {
+            return lms.call('get_content', {
+                content_type: this.type,
+                content: this.content
+            })
+        }
+    }
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/VideoModal.vue b/erpnext/public/js/education/lms/components/VideoModal.vue
new file mode 100644
index 0000000..71227ad
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/VideoModal.vue
@@ -0,0 +1,35 @@
+<template>
+	<div class="modal" id="videoModal" tabindex="-1" role="dialog">
+		<div class="modal-dialog" role="document">
+			<div class="modal-content">
+			<div class="modal-header">
+				<h5 class="modal-title">{{ title }}</h5>
+				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
+				<span id="close_modal" aria-hidden="true" @click="stopVideo()">&times;</span>
+				</button>
+			</div>
+			<div class="modal-body">
+				<youtube-player :url="video"/>
+			</div>
+			</div>
+		</div>
+	</div>
+</template>
+<script type="text/javascript">
+import YoutubePlayer from './YoutubePlayer.vue'
+
+export default {
+	name: 'VideoModal',
+	props: ['title', 'video'],
+	components: {
+		YoutubePlayer
+	},
+	methods: {
+		stopVideo() {
+			$('.yvideo').each(function() {
+  				this.contentWindow.postMessage('{"event":"command","func":"stopVideo","args":""}', '*')
+			});
+		}
+	}
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/YoutubePlayer.vue b/erpnext/public/js/education/lms/components/YoutubePlayer.vue
new file mode 100644
index 0000000..9377b57
--- /dev/null
+++ b/erpnext/public/js/education/lms/components/YoutubePlayer.vue
@@ -0,0 +1,36 @@
+<template>
+	<div class="embed-responsive embed-responsive-16by9">
+        <iframe class="embed-responsive-item yvideo" :src="'https://www.youtube.com/embed/' + videoID + '?version=3&enablejsapi=1'" allowfullscreen></iframe>
+    </div>
+</template>
+<script type="text/javascript">
+	export default {
+		name: 'YoutubePlayer',
+		props: ['url'],
+		data() {
+			return {
+				videoID: ''
+			}
+		},
+		watch: {
+			url() {
+				this.videoID = this.getVideoID(this.url)
+			}
+		},
+		methods: {
+			getVideoID(link) {
+				if (!Array.prototype.last){
+					Array.prototype.last = function(){
+						return this[this.length - 1];
+					};
+				};
+				if (link.includes('v=')){
+					return link.split('v=')[1].split('&')[0]
+				}
+				else if (link.includes('youtu.be')) {
+					return link.split('/').last().split('?')[0]
+				}
+		    }
+		}
+	};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/lms.js b/erpnext/public/js/education/lms/lms.js
new file mode 100644
index 0000000..4665b14
--- /dev/null
+++ b/erpnext/public/js/education/lms/lms.js
@@ -0,0 +1,81 @@
+import Vue from 'vue/dist/vue.js';
+import VueRouter from 'vue-router/dist/vue-router.js';
+import moment from 'moment/min/moment.min.js';
+
+import lmsRoot from "./lmsRoot.vue";
+import routes from './routes';
+import './call';
+
+Vue.use(VueRouter);
+
+var store = {
+	enrolledPrograms: [],
+	enrolledCourses: []
+};
+
+// let profile_page = `<a class="dropdown-item" href="/lms#/Profile" rel="nofollow"> LMS Profile </a>`
+// document.querySelector('#website-post-login > ul').innerHTML += profile_page
+
+frappe.ready(() => {
+	frappe.provide('lms');
+
+	lms.moment = moment;
+
+	lms.store = new Vue({
+		data: store,
+		methods: {
+			updateEnrolledPrograms() {
+				if(this.checkLogin()) {
+					lms.call("get_program_enrollments").then(data => {
+						this.enrolledPrograms = data;
+					});
+				}
+			},
+			updateEnrolledCourses() {
+				if(this.checkLogin()) {
+					lms.call("get_all_course_enrollments").then(data => {
+						this.enrolledCourses = data;
+					});
+				}
+			},
+			checkLogin() {
+				return frappe.is_user_logged_in();
+			},
+			updateState() {
+				this.checkLogin();
+				this.updateEnrolledPrograms();
+				this.updateEnrolledCourses();
+			},
+			checkProgramEnrollment(programName) {
+				if(this.checkLogin()){
+					if(this.enrolledPrograms) {
+						if(this.enrolledPrograms.includes(programName)) {
+							return true;
+						}
+						else {
+							return false;
+						}
+					}
+					else {
+						return false;
+					}
+				}
+				else {
+					return false;
+				}
+			}
+		}
+	});
+	lms.view = new Vue({
+		el: "#lms-app",
+		router: new VueRouter({ routes }),
+		template: "<lms-root/>",
+		components: { lmsRoot },
+		mounted() {
+			lms.store.updateState();
+		}
+	});
+	lms.view.$router.afterEach((to, from) => {
+		window.scrollTo(0,0);
+	});
+});
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/lmsRoot.vue b/erpnext/public/js/education/lms/lmsRoot.vue
new file mode 100644
index 0000000..d359265
--- /dev/null
+++ b/erpnext/public/js/education/lms/lmsRoot.vue
@@ -0,0 +1,45 @@
+<template>
+	<div id="lms-root">
+		<navbar></navbar>
+		<main class="container my-5">
+			<div class="page_content">
+				<router-view :key="$route.fullPath"></router-view>
+			</div>
+		</main>
+	</div>
+</template>
+<script>
+import Navbar from "./components/Navbar.vue"
+export default {
+	name: "lmsRoot",
+	components: {
+		Navbar
+	}
+};
+</script>
+<style>
+	div.card-hero-img {
+        height: 220px;
+        background-size: cover;
+        background-repeat: no-repeat;
+        background-position: center;
+        background-color: rgb(250, 251, 252);
+    }
+
+    .card-image-wrapper {
+        display: flex;
+        overflow: hidden;
+        height: 220px;
+        background-color: rgb(250, 251, 252);
+        justify-content: center;
+    }
+
+    .image-body {
+        align-self: center;
+        color: #d1d8dd;
+        font-size: 24px;
+        font-weight: 600;
+        line-height: 1;
+        padding: 20px;
+    }
+</style>
diff --git a/erpnext/public/js/education/lms/pages/ContentPage.vue b/erpnext/public/js/education/lms/pages/ContentPage.vue
new file mode 100644
index 0000000..542e937
--- /dev/null
+++ b/erpnext/public/js/education/lms/pages/ContentPage.vue
@@ -0,0 +1,87 @@
+<template>
+	<div>
+		<breadcrumb/>
+		<component v-bind:is="currentComponent" :content="content" :type="type">
+			<ContentNavigation :nextContent="nextContent" :nextContentType="nextContentType"/>
+		</component>
+	</div>
+</template>
+<script>
+import Article from "../components/Article.vue"
+import Quiz from "../components/Quiz.vue"
+import Video from "../components/Video.vue"
+import ContentNavigation from "../components/ContentNavigation.vue"
+import Breadcrumb from "../components/Breadcrumb.vue"
+
+export default {
+	props:['program_name', 'course_name', 'topic', 'type', 'content'],
+	name: "ContentPage",
+	data() {
+		return{
+			nextContent: '',
+			nextContentType: '',
+		}
+	},
+	computed: {
+	  currentComponent: function() {
+	  	if(this.type === "Article") {
+	  		return 'Article'
+	  	}
+	  	else if(this.type === "Quiz") {
+	  		return 'Quiz'
+	  	}
+	  	else if(this.type === "Video") {
+	  		return 'Video'
+	  	}
+	  },
+	},
+	mounted() {
+	  	this.getNextContent().then(data => {
+	  		this.nextContent = data.content,
+	  		this.nextContentType = data.content_type
+	  	});
+	},
+	methods: {
+		getNextContent(){
+			return lms.call("get_next_content",
+				{
+					current_content: this.content,
+					current_content_type: this.type,
+					topic: this.topic,
+			  	}
+			);
+		}
+	},
+	components: {
+		Article,
+		Video,
+		Quiz,
+		ContentNavigation,
+		Breadcrumb
+	}
+};
+</script>
+
+<style>
+.footer-message {
+	display: none;
+}
+
+.video-description-section {
+	padding-top: 0em !important;
+}
+
+.article-top-section {
+	padding-top: 0.5em !important;
+	padding-bottom: 0rem !important;
+}
+
+.article-content-section {
+	padding-top: 0em !important;
+}
+
+.quiz-section {
+	padding-top: 0.5em !important;
+	padding-bottom: 0rem !important;
+}
+</style>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/pages/CoursePage.vue b/erpnext/public/js/education/lms/pages/CoursePage.vue
new file mode 100644
index 0000000..9aaf8a9
--- /dev/null
+++ b/erpnext/public/js/education/lms/pages/CoursePage.vue
@@ -0,0 +1,49 @@
+<template>
+<div>
+	<breadcrumb></breadcrumb>
+	<TopSection v-bind:title="course.course_name" v-bind:description="course.description">
+    </TopSection>
+	<CardList :title="'Topics'" :description="''" :sectionType="'section-padding section-bg'">
+        <TopicCard slot="card-list-slot" v-for="topic in topicData" :topic="topic" :course_name="course_name" :program_name="program_name" :key="topic.name"/>
+    </CardList>
+</div>
+</template>
+<script>
+import TopSection from "../components/TopSection.vue"
+import CardList from "../components/CardList.vue"
+import TopicCard from "../components/TopicCard.vue"
+import Breadcrumb from "../components/Breadcrumb.vue"
+
+export default {
+	props: ['program_name','course_name'],
+    name: "CoursePage",
+    components: {
+		TopSection,
+		CardList,
+		TopicCard,
+		Breadcrumb
+	},
+	data() {
+		return {
+			course: {},
+			topicData: [],
+		}
+	},
+	mounted() {
+		this.getCourseDetails().then(data => this.course = data);
+		this.getTopics().then(data => this.topicData = data);
+	},
+	methods: {
+		getCourseDetails() {
+			return lms.call('get_course_details', {
+				course_name: this.course_name
+			});
+		},
+		getTopics() {
+			return lms.call('get_topics', {
+				course_name: this.course_name
+			})
+		}
+	}
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/pages/Home.vue b/erpnext/public/js/education/lms/pages/Home.vue
new file mode 100644
index 0000000..5690086
--- /dev/null
+++ b/erpnext/public/js/education/lms/pages/Home.vue
@@ -0,0 +1,48 @@
+<template>
+<div>
+	<TopSection :title="portal.title" :description="portal.description">
+        <TopSectionButton/>
+    </TopSection>
+	<CardList :title="'Featured Programs'" :description="'Master ERPNext'" :sectionType="'section-padding section-bg'">
+        <ProgramCard slot="card-list-slot" v-for="item in featuredPrograms" :key="item.program.name" :program="item.program" :enrolled="item.is_enrolled"/>
+        <AButton slot="list-bottom" :type="'primary'" :size="'md'" :route="'List/Program'">View All</AButton>
+    </CardList>
+</div>
+</template>
+<script>
+import Button from '../components/Button.vue';
+import TopSection from "../components/TopSection.vue"
+import CardList from "../components/CardList.vue"
+import ProgramCard from "../components/ProgramCard.vue"
+import TopSectionButton from "../components/TopSectionButton.vue"
+
+export default {
+    name: "Home",
+    data() {
+    	return{
+    		portal: {},
+            featuredPrograms: {},
+            // enrolledPrograms: new Set()
+    	}
+    },
+    components: {
+        AButton: Button,
+		TopSection,
+        CardList,
+        ProgramCard,
+        TopSectionButton
+    },
+	mounted() {
+        this.getPortalDetails().then(data => this.portal = data);
+        this.getFeaturedPrograms().then(data => this.featuredPrograms = data);
+    },
+    methods: {
+        getPortalDetails() {
+            return lms.call("get_portal_details")
+        },
+        getFeaturedPrograms() {
+            return lms.call("get_featured_programs")
+        }
+    }
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/pages/ListPage.vue b/erpnext/public/js/education/lms/pages/ListPage.vue
new file mode 100644
index 0000000..0768191
--- /dev/null
+++ b/erpnext/public/js/education/lms/pages/ListPage.vue
@@ -0,0 +1,53 @@
+<template>
+	<div>
+		<TopSection :title="'Programs at ' + portal.title" :description="portal.description">
+        	<AButton v-if="isLogin" :type="'primary'" :size="'lg'" :route="{ name: 'signup'}">Sign Up</AButton>
+    	</TopSection>
+		<CardList :title="'All Programs'" :description="''" :sectionType="'section-padding section-bg'">
+			<ProgramCard slot="card-list-slot" v-for="item in masterData" :key="item.program.name" :program="item.program" :enrolled="item.is_enrolled"/>
+		</CardList>
+	</div>
+</template>
+<script>
+import ProgramCard from '../components/ProgramCard.vue';
+import CourseCard from "../components/CourseCard.vue"
+import Button from '../components/Button.vue';
+import TopSection from "../components/TopSection.vue"
+import CardList from "../components/CardList.vue"
+
+
+export default {
+	props: ['master'],
+    name: "ListPage",
+    components: {
+        AButton: Button,
+		CourseCard,
+		ProgramCard,
+		CardList,
+		TopSection		
+	},
+	data() {
+		return {
+			portal: {},
+			masterData: {}
+		}
+	},
+	mounted() {
+        this.getPortalDetails().then(data => this.portal = data);
+        this.getMaster().then(data => this.masterData = data);
+    },
+    methods: {
+        getPortalDetails() {
+            return lms.call("get_portal_details")
+        },
+        getMaster() {
+            return lms.call("get_all_programs")
+        }
+	},
+	computed: {
+		isLogin() {
+			return !lms.store.checkLogin()
+		}
+	}
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/pages/ProfilePage.vue b/erpnext/public/js/education/lms/pages/ProfilePage.vue
new file mode 100644
index 0000000..c926463
--- /dev/null
+++ b/erpnext/public/js/education/lms/pages/ProfilePage.vue
@@ -0,0 +1,50 @@
+<template>
+<div>
+	<ProfileInfo :enrolledPrograms="enrolledPrograms"></ProfileInfo>
+	<div v-if="enrolledPrograms">
+		<CardList :title="'Your Progress'" :description="''" :sectionType="'section-padding section-bg'">
+	        <ProgressCard slot="card-list-slot" v-for="program in enrolledPrograms" :program="program" :key="program"/>
+	    </CardList>
+		<CardList :title="'Quiz Attempts'" :description="''" :sectionType="'section-padding section'">
+	        <ScoreCard slot="card-list-slot" v-for="program in enrolledPrograms" :program="program" :key="program"/>
+	    </CardList>
+	</div>
+	<div v-else>
+		You haven't enrolled in any programs yet.
+	</div>
+
+</div>
+</template>
+<script>
+import Button from '../components/Button.vue';
+import TopSection from "../components/TopSection.vue"
+import CardList from "../components/CardList.vue"
+import ProgressCard from "../components/ProgressCard.vue"
+import ProfileInfo from "../components/ProfileInfo.vue"
+import ScoreCard from "../components/ScoreCard.vue"
+
+export default {
+    name: "ProfilePage",
+    components: {
+        AButton: Button,
+		TopSection,
+		CardList,
+		ProfileInfo,
+		ProgressCard,
+		ScoreCard
+	},
+	data() {
+		return {
+			enrolledPrograms: {},
+		}
+	},
+	mounted() {
+        this.getEnrolledPrograms().then(data => this.enrolledPrograms = data);
+    },
+    methods: {
+        getEnrolledPrograms() {
+            return lms.call("get_program_enrollments")
+        }
+    }
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/pages/ProgramPage.vue b/erpnext/public/js/education/lms/pages/ProgramPage.vue
new file mode 100644
index 0000000..2a13661
--- /dev/null
+++ b/erpnext/public/js/education/lms/pages/ProgramPage.vue
@@ -0,0 +1,49 @@
+<template>
+<div>
+	<breadcrumb></breadcrumb>
+	<TopSection v-bind:title="program.program_name" v-bind:description="program.description">
+    </TopSection>
+	<CardList :title="'Courses'" :description="''" :sectionType="'section-padding'">
+        <CourseCard slot="card-list-slot" v-for="course in courseData" :course="course" :program_name="program_name" :key="course.name"/>
+    </CardList>
+</div>
+</template>
+<script>
+import TopSection from "../components/TopSection.vue"
+import CardList from "../components/CardList.vue"
+import CourseCard from "../components/CourseCard.vue"
+import Breadcrumb from "../components/Breadcrumb.vue"
+
+export default {
+	props: ['program_name'],
+    name: "ProgramPage",
+    components: {
+		TopSection,
+		CardList,
+		CourseCard,
+		Breadcrumb
+	},
+	data() {
+		return {
+			program: {},
+			courseData: [],
+		}
+	},
+	mounted() {
+		this.getProgramDetails().then(data => this.program = data);
+		this.getCourses().then(data => this.courseData = data);
+	},
+	methods: {
+		getProgramDetails() {
+			return lms.call('get_program', {
+				program_name: this.program_name
+			});
+		},
+		getCourses() {
+			return lms.call('get_courses', {
+				program_name: this.program_name
+			})
+		}
+	}
+};
+</script>
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/routes.js b/erpnext/public/js/education/lms/routes.js
new file mode 100644
index 0000000..483f222
--- /dev/null
+++ b/erpnext/public/js/education/lms/routes.js
@@ -0,0 +1,92 @@
+import Home from "./pages/Home.vue";
+import ProgramPage from "./pages/ProgramPage.vue";
+import CoursePage from "./pages/CoursePage.vue";
+import ContentPage from "./pages/ContentPage.vue";
+import ListPage from "./pages/ListPage.vue";
+import ProfilePage from "./pages/ProfilePage.vue";
+
+const routes = [{
+	name: 'home',
+	path: '',
+	component: Home
+},
+{
+	name: 'program',
+	path: '/Program/:program_name',
+	component: ProgramPage,
+	props: true
+},
+{
+	name: 'course',
+	path: '/Program/:program_name/:course_name/',
+	component: CoursePage,
+	props: true,
+},
+{
+	name: 'content',
+	path: '/Program/:program_name/:course_name/:topic/:type/:content',
+	component: ContentPage,
+	props: true,
+	beforeRouteUpdate (to, from, next) {
+		if (lms.store.checkProgramEnrollment(to.params.program_name)) {
+			next();
+		} else {
+			next({
+				name: 'program',
+				params: {
+					program_name: to.params.program_name
+				}
+			});
+		}
+	}
+},
+{
+	name: 'list',
+	path: '/List/:master',
+	component: ListPage,
+	props: true
+},
+{
+	name: 'signup',
+	path: '/Signup',
+	beforeEnter(to, from, next) {
+		window.location = window.location.origin.toString() + '/login#signup';
+	},
+	component: Home,
+	props: true
+},
+{
+	name: 'login',
+	path: '/Login',
+	beforeEnter(to, from, next) {
+		window.location = window.location.origin.toString() + '/login#login';
+	},
+	component: Home,
+	props: true
+},
+{
+	name: 'logout',
+	path: '/Logout',
+	beforeEnter(to, from, next) {
+		window.location = window.location.origin.toString() + '/?cmd=web_logout';
+	},
+	component: Home,
+	props: true
+},
+{
+	name: 'profile',
+	path: '/Profile',
+	component: ProfilePage,
+	props: true,
+	beforeEnter: (to, from, next) => {
+		if (!lms.store.checkLogin()) {
+			next({
+				name: 'home'
+			});
+		} else {
+			next();
+		}
+	}
+}];
+
+export default routes;
\ No newline at end of file
diff --git a/erpnext/public/js/templates/address_list.html b/erpnext/public/js/templates/address_list.html
index 0bc86ed..2379ef6 100644
--- a/erpnext/public/js/templates/address_list.html
+++ b/erpnext/public/js/templates/address_list.html
@@ -9,7 +9,7 @@
             <span class="text-muted">({%= __("Shipping") %})</span>{% } %}
 
         <a href="#Form/Address/{%= encodeURIComponent(addr_list[i].name) %}"
-            class="btn btn-light btn-xs pull-right"
+            class="btn btn-default btn-xs pull-right"
 				style="margin-top:-3px; margin-right: -5px;">
             {%= __("Edit") %}</a>
     </p>
@@ -19,5 +19,5 @@
 {% if(!addr_list.length) { %}
 <p class="text-muted small">{%= __("No address added yet.") %}</p>
 {% } %}
-<p><button class="btn btn-xs btn-light btn-address">{{ __("New Address") }}</button></p>
+<p><button class="btn btn-xs btn-default btn-address">{{ __("New Address") }}</button></p>
 
diff --git a/erpnext/public/js/templates/contact_list.html b/erpnext/public/js/templates/contact_list.html
index 2144893..893b4e0 100644
--- a/erpnext/public/js/templates/contact_list.html
+++ b/erpnext/public/js/templates/contact_list.html
@@ -10,7 +10,7 @@
 			 <span class="text-muted">&ndash; {%= contact_list[i].designation %}</span>
 			{% } %}
 			<a href="#Form/Contact/{%= encodeURIComponent(contact_list[i].name) %}"
-				class="btn btn-xs btn-light pull-right"
+				class="btn btn-xs btn-default pull-right"
 				style="margin-top:-3px; margin-right: -5px;">
 				{%= __("Edit") %}</a>
 		</p>
@@ -33,6 +33,6 @@
 {% if(!contact_list.length) { %}
 <p class="text-muted small">{%= __("No contacts added yet.") %}</p>
 {% } %}
-<p><button class="btn btn-xs btn-light btn-contact">
+<p><button class="btn btn-xs btn-default btn-contact">
 	{{ __("New Contact") }}</button>
 </p>
\ No newline at end of file
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 6b583af..f3a4f7c 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -284,18 +284,18 @@
 		'Employee Tax Exemption Declaration':[
 			dict(fieldname='hra_section', label='HRA Exemption',
 				fieldtype='Section Break', insert_after='declarations'),
-			dict(fieldname='salary_structure_hra', label='HRA as per Salary Structure',
-				fieldtype='Currency', insert_after='hra_section', read_only=1),
 			dict(fieldname='monthly_house_rent', label='Monthly House Rent',
-				fieldtype='Currency', insert_after='salary_structure_hra'),
+				fieldtype='Currency', insert_after='hra_section'),
 			dict(fieldname='rented_in_metro_city', label='Rented in Metro City',
-				fieldtype='Check', insert_after='monthly_house_rent'),
+				fieldtype='Check', insert_after='monthly_house_rent', depends_on='monthly_house_rent'),
+			dict(fieldname='salary_structure_hra', label='HRA as per Salary Structure',
+				fieldtype='Currency', insert_after='rented_in_metro_city', read_only=1, depends_on='monthly_house_rent'),
 			dict(fieldname='hra_column_break', fieldtype='Column Break',
-				insert_after='rented_in_metro_city'),
+				insert_after='salary_structure_hra', depends_on='monthly_house_rent'),
 			dict(fieldname='annual_hra_exemption', label='Annual HRA Exemption',
-				fieldtype='Currency', insert_after='hra_column_break', read_only=1),
+				fieldtype='Currency', insert_after='hra_column_break', read_only=1, depends_on='monthly_house_rent'),
 			dict(fieldname='monthly_hra_exemption', label='Monthly HRA Exemption',
-				fieldtype='Currency', insert_after='annual_hra_exemption', read_only=1)
+				fieldtype='Currency', insert_after='annual_hra_exemption', read_only=1, depends_on='monthly_house_rent')
 		],
 		'Employee Tax Exemption Proof Submission': [
 			dict(fieldname='hra_section', label='HRA Exemption',
@@ -303,19 +303,19 @@
 			dict(fieldname='house_rent_payment_amount', label='House Rent Payment Amount',
 				fieldtype='Currency', insert_after='hra_section'),
 			dict(fieldname='rented_in_metro_city', label='Rented in Metro City',
-				fieldtype='Check', insert_after='house_rent_payment_amount'),
+				fieldtype='Check', insert_after='house_rent_payment_amount', depends_on='house_rent_payment_amount'),
 			dict(fieldname='rented_from_date', label='Rented From Date',
-				fieldtype='Date', insert_after='rented_in_metro_city'),
+				fieldtype='Date', insert_after='rented_in_metro_city', depends_on='house_rent_payment_amount'),
 			dict(fieldname='rented_to_date', label='Rented To Date',
-				fieldtype='Date', insert_after='rented_from_date'),
+				fieldtype='Date', insert_after='rented_from_date', depends_on='house_rent_payment_amount'),
 			dict(fieldname='hra_column_break', fieldtype='Column Break',
-				insert_after='rented_to_date'),
+				insert_after='rented_to_date', depends_on='house_rent_payment_amount'),
 			dict(fieldname='monthly_house_rent', label='Monthly House Rent',
-				fieldtype='Currency', insert_after='hra_column_break', read_only=1),
+				fieldtype='Currency', insert_after='hra_column_break', read_only=1, depends_on='house_rent_payment_amount'),
 			dict(fieldname='monthly_hra_exemption', label='Monthly Eligible Amount',
-				fieldtype='Currency', insert_after='monthly_house_rent', read_only=1),
+				fieldtype='Currency', insert_after='monthly_house_rent', read_only=1, depends_on='house_rent_payment_amount'),
 			dict(fieldname='total_eligible_hra_exemption', label='Total Eligible HRA Exemption',
-				fieldtype='Currency', insert_after='monthly_hra_exemption', read_only=1)
+				fieldtype='Currency', insert_after='monthly_hra_exemption', read_only=1, depends_on='house_rent_payment_amount')
 		],
 		'Supplier': [
 			{
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index e379ed8..f413a8e 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -1,7 +1,7 @@
 from __future__ import unicode_literals
 import frappe, re
 from frappe import _
-from frappe.utils import cstr, flt, date_diff, getdate
+from frappe.utils import cstr, flt, date_diff, nowdate
 from erpnext.regional.india import states, state_numbers
 from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount
 from erpnext.controllers.accounts_controller import get_taxes_and_charges
@@ -144,24 +144,40 @@
 def calculate_annual_eligible_hra_exemption(doc):
 	basic_component = frappe.get_cached_value('Company',  doc.company,  "basic_component")
 	hra_component = frappe.get_cached_value('Company',  doc.company,  "hra_component")
+	if not (basic_component and hra_component):
+		frappe.throw(_("Please mention Basic and HRA component in Company"))
+
 	annual_exemption, monthly_exemption, hra_amount = 0, 0, 0
 	if hra_component and basic_component:
-		assignment = get_salary_assignment(doc.employee, getdate())
-		if assignment and frappe.db.exists("Salary Detail", {
-			"parent": assignment.salary_structure,
-			"salary_component": hra_component, "parentfield": "earnings"}):
-			basic_amount, hra_amount = get_component_amt_from_salary_slip(doc.employee,
-				assignment.salary_structure, basic_component, hra_component)
-			if hra_amount:
-				if doc.monthly_house_rent:
-					annual_exemption = calculate_hra_exemption(assignment.salary_structure,
-									basic_amount, hra_amount, doc.monthly_house_rent,
-									doc.rented_in_metro_city)
-					if annual_exemption > 0:
-						monthly_exemption = annual_exemption / 12
-					else:
-						annual_exemption = 0
-	return {"hra_amount": hra_amount, "annual_exemption": annual_exemption, "monthly_exemption": monthly_exemption}
+		assignment = get_salary_assignment(doc.employee, nowdate())
+
+		if assignment:
+			hra_component_exists = frappe.db.exists("Salary Detail", {
+				"parent": assignment.salary_structure,
+				"salary_component": hra_component,
+				"parentfield": "earnings",
+				"parenttype": "Salary Structure"
+			})
+			if hra_component_exists:
+				basic_amount, hra_amount = get_component_amt_from_salary_slip(doc.employee,
+					assignment.salary_structure, basic_component, hra_component)
+				if hra_amount:
+					if doc.monthly_house_rent:
+						annual_exemption = calculate_hra_exemption(assignment.salary_structure,
+							basic_amount, hra_amount, doc.monthly_house_rent,
+							doc.rented_in_metro_city)
+						if annual_exemption > 0:
+							monthly_exemption = annual_exemption / 12
+						else:
+							annual_exemption = 0
+		elif doc.docstatus == 1:
+			frappe.throw(_("Salary Structure must be submitted before submission of Tax Ememption Declaration"))
+
+	return frappe._dict({
+		"hra_amount": hra_amount,
+		"annual_exemption": annual_exemption,
+		"monthly_exemption": monthly_exemption
+	})
 
 def get_component_amt_from_salary_slip(employee, salary_structure, basic_component, hra_component):
 	salary_slip = make_salary_slip(salary_structure, employee=employee)
@@ -181,8 +197,10 @@
 	frequency = frappe.get_value("Salary Structure", salary_structure, "payroll_frequency")
 	# case 1: The actual amount allotted by the employer as the HRA.
 	exemptions.append(get_annual_component_pay(frequency, monthly_hra))
+
 	actual_annual_rent = monthly_house_rent * 12
 	annual_basic = get_annual_component_pay(frequency, basic)
+
 	# case 2: Actual rent paid less 10% of the basic salary.
 	exemptions.append(flt(actual_annual_rent) - flt(annual_basic * 0.1))
 	# case 3: 50% of the basic salary, if the employee is staying in a metro city (40% for a non-metro city).
@@ -205,15 +223,25 @@
 def validate_house_rent_dates(doc):
 	if not doc.rented_to_date or not doc.rented_from_date:
 		frappe.throw(_("House rented dates required for exemption calculation"))
+
 	if date_diff(doc.rented_to_date, doc.rented_from_date) < 14:
 		frappe.throw(_("House rented dates should be atleast 15 days apart"))
-	proofs = frappe.db.sql("""select name from `tabEmployee Tax Exemption Proof Submission`
-		where docstatus=1 and employee='{0}' and payroll_period='{1}' and
-		(rented_from_date between '{2}' and '{3}' or rented_to_date between
-		'{2}' and '{3}')""".format(doc.employee, doc.payroll_period,
-		doc.rented_from_date, doc.rented_to_date))
+
+	proofs = frappe.db.sql("""
+		select name
+		from `tabEmployee Tax Exemption Proof Submission`
+		where
+			docstatus=1 and employee=%(employee)s and payroll_period=%(payroll_period)s
+			and (rented_from_date between %(from_date)s and %(to_date)s or rented_to_date between %(from_date)s and %(to_date)s)
+	""", {
+		"employee": doc.employee,
+		"payroll_period": doc.payroll_period,
+		"from_date": doc.rented_from_date,
+		"to_date": doc.rented_to_date
+	})
+
 	if proofs:
-		frappe.throw(_("House rent paid days overlap with {0}").format(proofs[0][0]))
+		frappe.throw(_("House rent paid days overlapping with {0}").format(proofs[0][0]))
 
 def calculate_hra_exemption_for_period(doc):
 	monthly_rent, eligible_hra = 0, 0
diff --git a/erpnext/regional/report/irs_1099/irs_1099.py b/erpnext/regional/report/irs_1099/irs_1099.py
index 0cb4a3a..67834d1 100644
--- a/erpnext/regional/report/irs_1099/irs_1099.py
+++ b/erpnext/regional/report/irs_1099/irs_1099.py
@@ -97,9 +97,7 @@
 		row["recipient_street_address"], row["recipient_city_state"] = get_street_address_html("Supplier", row.supplier)
 		row["payments"] = fmt_money(row["payments"], precision=0, currency="USD")
 		frappe._dict(row)
-		print(row)
 		pdf = get_pdf(render_template(template, row), output=output if output else None)
-		print(pdf)
 	frappe.local.response.filename = filters.fiscal_year + " " + filters.company + " IRS 1099 Forms"
 	frappe.local.response.filecontent = read_multi_pdf(output)
 	frappe.local.response.type = "download"
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index adb58a1..dc22b5b 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -204,6 +204,20 @@
 							erpnext.utils.make_subscription(doc.doctype, doc.name)
 						}, __('Create'))
 					}
+
+					if (doc.docstatus === 1 && !doc.inter_company_order_reference) {
+						let me = this;
+						frappe.model.with_doc("Customer", me.frm.doc.customer, () => {
+							let customer = frappe.model.get_doc("Customer", me.frm.doc.customer);
+							let internal = customer.is_internal_customer;
+							let disabled = customer.disabled;
+							if (internal === 1 && disabled === 0) {
+								me.frm.add_custom_button("Inter Company Order", function() {
+									me.make_inter_company_order();
+								}, __('Create'));
+							}
+						});
+					}
 				}
 				// payment request
 				if(flt(doc.per_billed)==0) {
@@ -500,6 +514,13 @@
 		})
 	},
 
+	make_inter_company_order: function() {
+		frappe.model.open_mapped_doc({
+			method: "erpnext.selling.doctype.sales_order.sales_order.make_inter_company_purchase_order",
+			frm: this.frm
+		});
+	},
+
 	make_maintenance_visit: function() {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.selling.doctype.sales_order.sales_order.make_maintenance_visit",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index 30123db..95c803d 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -1449,6 +1449,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "pricing_rule_details",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1481,6 +1482,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "pricing_rules",
    "fieldtype": "Table",
    "hidden": 0,
@@ -1514,6 +1516,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
    "fieldname": "section_break_31",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -3237,6 +3240,40 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fetch_if_empty": 0,
+   "fieldname": "inter_company_order_reference",
+   "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": "Inter Company Order Reference",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Purchase Order",
+   "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": "Track this Sales Order against any Project",
    "fetch_if_empty": 0,
    "fieldname": "project",
@@ -4292,17 +4329,15 @@
   }
  ],
  "has_web_view": 0,
- "hide_heading": 0,
  "hide_toolbar": 0,
  "icon": "fa fa-file-text",
  "idx": 105,
- "image_view": 0,
  "in_create": 0,
  "is_submittable": 1,
  "issingle": 0,
  "istable": 0,
  "max_attachments": 0,
- "modified": "2019-02-13 01:02:45.882179",
+ "modified": "2019-04-18 12:05:23.464968",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Sales Order",
@@ -4425,7 +4460,6 @@
  ],
  "quick_entry": 0,
  "read_only": 0,
- "read_only_onload": 1,
  "search_fields": "status,transaction_date,customer,customer_name, territory,order_type,company",
  "show_name_in_global_search": 1,
  "sort_field": "modified",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index d09e281..fc11e11 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -19,6 +19,8 @@
 from erpnext.stock.doctype.item.item import get_item_defaults
 from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
 from erpnext.manufacturing.doctype.production_plan.production_plan import get_items_for_material_requests
+from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
+	unlink_inter_company_doc
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -42,6 +44,7 @@
 		self.validate_warehouse()
 		self.validate_drop_ship()
 		self.validate_serial_no_based_delivery()
+		validate_inter_company_party(self.doctype, self.customer, self.company, self.inter_company_order_reference)
 
 		from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
 		make_packing_list(self)
@@ -182,6 +185,8 @@
 
 		self.update_blanket_order()
 
+		update_linked_doc(self.doctype, self.name, self.inter_company_order_reference)
+
 	def on_cancel(self):
 		super(SalesOrder, self).on_cancel()
 
@@ -198,6 +203,8 @@
 
 		self.update_blanket_order()
 
+		unlink_inter_company_doc(self.doctype, self.name, self.inter_company_order_reference)
+
 	def update_project(self):
 		if frappe.db.get_single_value('Selling Settings', 'sales_update_frequency') != "Each Transaction":
 			return
@@ -764,6 +771,7 @@
 		target.apply_discount_on = ""
 		target.additional_discount_percentage = 0.0
 		target.discount_amount = 0.0
+		target.inter_company_order_reference = ""
 
 		default_price_list = frappe.get_value("Supplier", supplier, "default_price_list")
 		if default_price_list:
@@ -970,4 +978,9 @@
 	material_request.flags.ignore_permissions = 1
 	material_request.run_method("set_missing_values")
 	material_request.submit()
-	return material_request
\ No newline at end of file
+	return material_request
+
+@frappe.whitelist()
+def make_inter_company_purchase_order(source_name, target_doc=None):
+	from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
+	return make_inter_company_transaction("Sales Order", source_name, target_doc)
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index cd69dd4..b8c4604 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -412,7 +412,6 @@
 @frappe.whitelist()
 def make_sales_invoice(source_name, target_doc=None):
 	doc = frappe.get_doc('Delivery Note', source_name)
-	sales_orders = [d.against_sales_order for d in doc.items]
 	returned_qty_map = get_returned_qty_map(source_name)
 	invoiced_qty_map = get_invoiced_qty_map(source_name)
 
@@ -452,7 +451,7 @@
 				returned_qty = 0
 		return pending_qty, returned_qty
 
-	doc = get_mapped_doc("Delivery Note", source_name, 	{
+	doc = get_mapped_doc("Delivery Note", source_name, {
 		"Delivery Note": {
 			"doctype": "Sales Invoice",
 			"validation": {
@@ -470,7 +469,7 @@
 				"cost_center": "cost_center"
 			},
 			"postprocess": update_item,
-			"filter": lambda d: get_pending_qty(d)[0]<=0
+			"filter": lambda d: get_pending_qty(d)[0] <= 0 if not doc.get("is_return") else get_pending_qty(d)[0] > 0
 		},
 		"Sales Taxes and Charges": {
 			"doctype": "Sales Taxes and Charges",
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index aeab9ed..ed02cee 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -90,8 +90,6 @@
 			self.set_opening_stock()
 
 	def validate(self):
-		self.get_doc_before_save()
-
 		super(Item, self).validate()
 
 		if not self.item_name:
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 361137e..1bd55f8 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -468,7 +468,7 @@
 				"asset": "asset",
 			},
 			"postprocess": update_item,
-			"filter": lambda d: get_pending_qty(d)[0]<=0
+			"filter": lambda d: get_pending_qty(d)[0] <= 0 if not doc.get("is_return") else get_pending_qty(d)[0] > 0
 		},
 		"Purchase Taxes and Charges": {
 			"doctype": "Purchase Taxes and Charges",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index da2d09f..a6af4bd 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -35,7 +35,7 @@
 
 class StockEntry(StockController):
 	def get_feed(self):
-		return _("From {0} to {1}").format(self.from_warehouse, self.to_warehouse)
+		return self.stock_entry_type
 
 	def onload(self):
 		for item in self.get("items"):
diff --git a/erpnext/stock/report/inactive_items/__init__.py b/erpnext/stock/report/inactive_items/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/report/inactive_items/__init__.py
diff --git a/erpnext/stock/report/inactive_items/inactive_items.js b/erpnext/stock/report/inactive_items/inactive_items.js
new file mode 100644
index 0000000..39dfd5c
--- /dev/null
+++ b/erpnext/stock/report/inactive_items/inactive_items.js
@@ -0,0 +1,34 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Inactive Items"] = {
+	"filters": [
+		{
+			fieldname: "item",
+			label: __("Item"),
+			fieldtype: "Link",
+			options: "Item"
+		},
+		{
+			fieldname: "item_group",
+			label: __("Item Group"),
+			fieldtype: "Link",
+			options: "Item Group"
+		},
+		{
+			fieldname: "based_on",
+			label: __("Based On"),
+			fieldtype: "Select",
+			options: "Sales Order\nSales Invoice",
+			default: "Sales Order"
+		},
+		{
+			fieldname: "days",
+			label: __("Days Since Last order"),
+			fieldtype: "Select",
+			options: [30, 60, 90],
+			default: 30
+		},
+	]
+}
diff --git a/erpnext/stock/report/inactive_items/inactive_items.json b/erpnext/stock/report/inactive_items/inactive_items.json
new file mode 100644
index 0000000..b9eb05e
--- /dev/null
+++ b/erpnext/stock/report/inactive_items/inactive_items.json
@@ -0,0 +1,31 @@
+{
+ "add_total_row": 0, 
+ "creation": "2019-04-16 16:05:00.647308", 
+ "disable_prepared_report": 0, 
+ "disabled": 0, 
+ "docstatus": 0, 
+ "doctype": "Report", 
+ "idx": 0, 
+ "is_standard": "Yes", 
+ "letter_head": "Test Letter Head 1", 
+ "modified": "2019-04-16 16:06:33.630043", 
+ "modified_by": "Administrator", 
+ "module": "Stock", 
+ "name": "Inactive Items", 
+ "owner": "Administrator", 
+ "prepared_report": 0, 
+ "ref_doctype": "Sales Invoice", 
+ "report_name": "Inactive Items", 
+ "report_type": "Script Report", 
+ "roles": [
+  {
+   "role": "Accounts User"
+  }, 
+  {
+   "role": "Accounts Manager"
+  }, 
+  {
+   "role": "Auditor"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/stock/report/inactive_items/inactive_items.py b/erpnext/stock/report/inactive_items/inactive_items.py
new file mode 100644
index 0000000..8d87912
--- /dev/null
+++ b/erpnext/stock/report/inactive_items/inactive_items.py
@@ -0,0 +1,148 @@
+# 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.utils import getdate, add_days, today, cint
+from frappe import _
+
+def execute(filters=None):
+
+	columns = get_columns()
+	data = get_data(filters)
+	return columns, data
+
+def get_columns():
+
+	columns = [
+		{
+			"fieldname": "territory",
+			"fieldtype": "Link",
+			"label": _("Territory"),
+			"options": "Territory",
+			"width": 100
+		},
+		{
+			"fieldname": "item_group",
+			"fieldtype": "Link",
+			"label": _("Item Group"),
+			"options": "Item Group",
+			"width": 150
+		},
+		{
+			"fieldname": "item_name",
+			"fieldtype": "Link",
+			"options": "Item",
+			"label": "Item",
+			"width": 150
+		},
+		{
+			"fieldname": "item_name",
+			"fieldtype": "Data",
+			"label": _("Item Name"),
+			"width": 150
+		},
+
+		{
+			"fieldname": "customer",
+			"fieldtype": "Link",
+			"label": _("Customer"),
+			"options": "Customer",
+			"width": 100
+		},
+		{
+			"fieldname": "last_order_date",
+			"fieldtype": "Date",
+			"label": _("Last Order Date"),
+			"width": 100
+		},
+		{
+			"fieldname": "qty",
+			"fieldtype": "Float",
+			"label": _("Quantity"),
+			"width": 100
+		},
+		{
+			"fieldname": "days_since_last_order",
+			"fieldtype": "Int",
+			"label": _("Days Since Last Order"),
+			"width": 100
+		},
+	]
+
+	return columns
+
+
+def get_data(filters):
+
+	data = []
+	items = get_items(filters)
+	sales_invoice_data = get_sales_details(filters)
+
+	for item in items:
+		if sales_invoice_data.get(item.name):
+			item_obj = sales_invoice_data[item.name]
+			if item_obj.days_since_last_order > cint(filters['days']):
+				row = {
+					"territory": item_obj.territory,
+					"item_group": item_obj.item_group,
+					"item": item_obj.name,
+					"item_name": item_obj.item_name,
+					"customer": item_obj.customer,
+					"last_order_date": item_obj.last_order_date,
+					"qty": item_obj.qty,
+					"days_since_last_order": item_obj.days_since_last_order
+				}
+				data.append(row)
+		else:
+			row = {
+				"item_group": item.item_group,
+				"item": item.name,
+				"item_name": item.item_name
+			}
+			data.append(row)
+
+	return data
+
+
+def get_sales_details(filters):
+
+	data = []
+	item_details_map = {}
+
+	date_field = "s.transaction_date" if filters["based_on"] == "Sales Order" else "s.posting_date"
+
+	sales_data = frappe.db.sql("""
+		select s.territory, s.customer, si.item_group, si.item_name, si.qty, {date_field} as last_order_date,
+		DATEDIFF(CURDATE(), {date_field}) as days_since_last_order
+		from `tab{doctype}` s, `tab{doctype} Item` si
+		where s.name = si.parent and s.docstatus = 1
+		group by si.name order by days_since_last_order """ #nosec
+		.format(date_field = date_field, doctype = filters['based_on']), as_dict=1)
+
+	for d in sales_data:
+		item_details_map.setdefault(d.item_name, d)
+
+	return item_details_map
+
+def get_items(filters):
+
+	filters_dict = {
+		"disabled": 0,
+		"is_stock_item": 1
+	}
+
+	if filters.get("item_group"):
+		filters_dict.update({
+			"item_group": filters["item_group"]
+		})
+
+	if filters.get("item"):
+		filters_dict.update({
+			"name": filters["item"]
+		})
+
+	items = frappe.get_all("Item", fields=["name", "item_group", "item_name"], filters=filters_dict, order_by="name")
+
+	return items
+
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index 20b5e45..70da5b5 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -154,10 +154,10 @@
 		"posting_date": filters.from_date,
 		"posting_time": "00:00:00"
 	})
-	row = [""]*len(columns)
-	row[1] = _("'Opening'")
-	for i, v in ((9, 'qty_after_transaction'), (11, 'valuation_rate'), (12, 'stock_value')):
-			row[i] = last_entry.get(v, 0)
+	row = {}
+	row["item_code"] = _("'Opening'")
+	for dummy, v in ((9, 'qty_after_transaction'), (11, 'valuation_rate'), (12, 'stock_value')):
+			row[v] = last_entry.get(v, 0)
 
 	return row
 
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index 3a1c5ef..91b718e 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -1,1309 +1,1309 @@
 {
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "naming_series:",
- "beta": 0,
- "creation": "2013-02-01 10:36:25",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
- "engine": "InnoDB",
+ "allow_copy": 0, 
+ "allow_events_in_timeline": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 1, 
+ "allow_rename": 1, 
+ "autoname": "naming_series:", 
+ "beta": 0, 
+ "creation": "2013-02-01 10:36:25", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "Setup", 
+ "editable_grid": 0, 
+ "engine": "InnoDB", 
  "fields": [
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "subject_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": "Subject",
-   "length": 0,
-   "no_copy": 0,
-   "options": "fa fa-flag",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "subject_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": "Subject", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "fa fa-flag", 
+   "permlevel": 0, 
+   "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": "",
-   "fetch_if_empty": 0,
-   "fieldname": "naming_series",
-   "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": "Series",
-   "length": 0,
-   "no_copy": 1,
-   "options": "ISS-.YYYY.-",
-   "permlevel": 0,
-   "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": 1,
-   "translatable": 0,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "", 
+   "fetch_if_empty": 0, 
+   "fieldname": "naming_series", 
+   "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": "Series", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "ISS-.YYYY.-", 
+   "permlevel": 0, 
+   "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": 1, 
+   "translatable": 0, 
    "unique": 0
-  },
+  }, 
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 1,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "subject",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 1,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "label": "Subject",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "subject", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 1, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Subject", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "issue_type",
-   "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": "Issue Type",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Issue Type",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "customer", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 1, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Customer", 
+   "length": 0, 
+   "no_copy": 0, 
+   "oldfieldname": "customer", 
+   "oldfieldtype": "Link", 
+   "options": "Customer", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "customer",
-   "fieldtype": "Link",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 1,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "label": "Customer",
-   "length": 0,
-   "no_copy": 0,
-   "oldfieldname": "customer",
-   "oldfieldtype": "Link",
-   "options": "Customer",
-   "permlevel": 0,
-   "print_hide": 1,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:doc.__islocal", 
+   "fetch_if_empty": 0, 
+   "fieldname": "raised_by", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 1, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Raised By (Email)", 
+   "length": 0, 
+   "no_copy": 0, 
+   "oldfieldname": "raised_by", 
+   "oldfieldtype": "Data", 
+   "options": "Email", 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "cb00",
-   "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,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "cb00", 
+   "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, 
+   "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",
-   "fetch_if_empty": 0,
-   "fieldname": "status",
-   "fieldtype": "Select",
-   "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": "Status",
-   "length": 0,
-   "no_copy": 1,
-   "oldfieldname": "status",
-   "oldfieldtype": "Select",
-   "options": "Open\nReplied\nHold\nClosed",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "Open", 
+   "fetch_if_empty": 0, 
+   "fieldname": "status", 
+   "fieldtype": "Select", 
+   "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": "Status", 
+   "length": 0, 
+   "no_copy": 1, 
+   "oldfieldname": "status", 
+   "oldfieldtype": "Select", 
+   "options": "Open\nReplied\nHold\nClosed", 
+   "permlevel": 0, 
+   "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": "Medium",
-   "depends_on": "",
-   "fetch_if_empty": 0,
-   "fieldname": "priority",
-   "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": 1,
-   "label": "Priority",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Low\nMedium\nHigh",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "Medium", 
+   "depends_on": "", 
+   "fetch_if_empty": 0, 
+   "fieldname": "priority", 
+   "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": 1, 
+   "label": "Priority", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Low\nMedium\nHigh", 
+   "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": 1,
-   "collapsible": 0,
-   "columns": 0,
-   "depends_on": "eval:doc.__islocal",
-   "fetch_if_empty": 0,
-   "fieldname": "raised_by",
-   "fieldtype": "Data",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 1,
-   "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Raised By (Email)",
-   "length": 0,
-   "no_copy": 0,
-   "oldfieldname": "raised_by",
-   "oldfieldtype": "Data",
-   "options": "Email",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "issue_type", 
+   "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": "Issue Type", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Issue Type", 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "email_account",
-   "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": "Email Account",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Email Account",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "collapsible_depends_on": "eval:doc.status!=\"Closed\"", 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "sb_details", 
+   "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": "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": 1,
-   "collapsible_depends_on": "eval:doc.status!=\"Closed\"",
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "sb_details",
-   "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": "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "", 
+   "fetch_if_empty": 0, 
+   "fieldname": "description", 
+   "fieldtype": "Text Editor", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 1, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Description", 
+   "length": 0, 
+   "no_copy": 0, 
+   "oldfieldname": "problem_description", 
+   "oldfieldtype": "Text", 
+   "permlevel": 0, 
+   "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,
-   "depends_on": "",
-   "fetch_if_empty": 0,
-   "fieldname": "description",
-   "fieldtype": "Text Editor",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 1,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "label": "Description",
-   "length": 0,
-   "no_copy": 0,
-   "oldfieldname": "problem_description",
-   "oldfieldtype": "Text",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "columns": 0, 
+   "depends_on": "eval: doc.service_level_agreement", 
+   "fetch_if_empty": 0, 
+   "fieldname": "service_level_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": "Service Level", 
+   "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": 1,
-   "columns": 0,
-   "depends_on": "eval: doc.service_level_agreement",
-   "fetch_if_empty": 0,
-   "fieldname": "service_level_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": "Service Level",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "service_level_agreement", 
+   "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": "Service Level Agreement", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Service Level Agreement", 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "service_level_agreement",
-   "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": "Service Level Agreement",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Service Level Agreement",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "response_by", 
+   "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": "Response By", 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "response_by",
-   "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": "Response By",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "columns": 0, 
+   "fetch_if_empty": 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, 
+   "label": "", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "fa fa-pushpin", 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 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,
-   "label": "",
-   "length": 0,
-   "no_copy": 0,
-   "options": "fa fa-pushpin",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "Ongoing", 
+   "fetch_if_empty": 0, 
+   "fieldname": "agreement_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": "Agreement Status", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Ongoing\nFulfilled\nFailed", 
+   "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": "Ongoing",
-   "fetch_if_empty": 0,
-   "fieldname": "agreement_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": "Agreement Status",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Ongoing\nFulfilled\nFailed",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "resolution_by", 
+   "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": "Resolution By", 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "resolution_by",
-   "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": "Resolution By",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "response", 
+   "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": "Response", 
+   "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": 1,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "response",
-   "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": "Response",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "mins_to_first_response", 
+   "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": "Mins to First Response", 
+   "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": 1,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "mins_to_first_response",
-   "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": "Mins to First Response",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "first_responded_on", 
+   "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": "First Responded On", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "first_responded_on",
-   "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": "First Responded On",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "additional_info", 
+   "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": "Reference", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "fa fa-pushpin", 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "additional_info",
-   "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": "Reference",
-   "length": 0,
-   "no_copy": 0,
-   "options": "fa fa-pushpin",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "lead", 
+   "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": "Lead", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Lead", 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "lead",
-   "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": "Lead",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Lead",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "contact", 
+   "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": "Contact", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Contact", 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "contact",
-   "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": "Contact",
-   "length": 0,
-   "no_copy": 0,
-   "options": "Contact",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "email_account", 
+   "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": "Email Account", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Email Account", 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "column_break_16",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "column_break_16", 
+   "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": 1,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "customer_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": "Customer Name",
-   "length": 0,
-   "no_copy": 0,
-   "oldfieldname": "customer_name",
-   "oldfieldtype": "Data",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 1, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "customer_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": "Customer Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "oldfieldname": "customer_name", 
+   "oldfieldtype": "Data", 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 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,
-   "fetch_if_empty": 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,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 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, 
+   "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": 1,
-   "columns": 0,
-   "fetch_if_empty": 0,
-   "fieldname": "section_break_19",
-   "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": "Resolution",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "section_break_19", 
+   "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": "Resolution", 
+   "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": "eval:!doc.__islocal",
-   "fetch_if_empty": 0,
-   "fieldname": "resolution_details",
-   "fieldtype": "Text Editor",
-   "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": "Resolution Details",
-   "length": 0,
-   "no_copy": 1,
-   "oldfieldname": "resolution_details",
-   "oldfieldtype": "Text",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:!doc.__islocal", 
+   "fetch_if_empty": 0, 
+   "fieldname": "resolution_details", 
+   "fieldtype": "Text Editor", 
+   "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": "Resolution Details", 
+   "length": 0, 
+   "no_copy": 1, 
+   "oldfieldname": "resolution_details", 
+   "oldfieldtype": "Text", 
+   "permlevel": 0, 
+   "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": "eval:!doc.__islocal",
-   "fetch_if_empty": 0,
-   "fieldname": "column_break1",
-   "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,
-   "oldfieldtype": "Column Break",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:!doc.__islocal", 
+   "fetch_if_empty": 0, 
+   "fieldname": "column_break1", 
+   "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, 
+   "oldfieldtype": "Column Break", 
+   "permlevel": 0, 
+   "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": "Today",
-   "fetch_if_empty": 0,
-   "fieldname": "opening_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": "Opening Date",
-   "length": 0,
-   "no_copy": 1,
-   "oldfieldname": "opening_date",
-   "oldfieldtype": "Date",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "Today", 
+   "fetch_if_empty": 0, 
+   "fieldname": "opening_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": "Opening Date", 
+   "length": 0, 
+   "no_copy": 1, 
+   "oldfieldname": "opening_date", 
+   "oldfieldtype": "Date", 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "opening_time",
-   "fieldtype": "Time",
-   "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": "Opening Time",
-   "length": 0,
-   "no_copy": 1,
-   "oldfieldname": "opening_time",
-   "oldfieldtype": "Time",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "opening_time", 
+   "fieldtype": "Time", 
+   "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": "Opening Time", 
+   "length": 0, 
+   "no_copy": 1, 
+   "oldfieldname": "opening_time", 
+   "oldfieldtype": "Time", 
+   "permlevel": 0, 
+   "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": "eval:!doc.__islocal",
-   "fetch_if_empty": 0,
-   "fieldname": "resolution_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": "Resolution Date",
-   "length": 0,
-   "no_copy": 1,
-   "oldfieldname": "resolution_date",
-   "oldfieldtype": "Date",
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:!doc.__islocal", 
+   "fetch_if_empty": 0, 
+   "fieldname": "resolution_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": "Resolution Date", 
+   "length": 0, 
+   "no_copy": 1, 
+   "oldfieldname": "resolution_date", 
+   "oldfieldtype": "Date", 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "content_type",
-   "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": "Content Type",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "content_type", 
+   "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": "Content Type", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "attachment",
-   "fieldtype": "Attach",
-   "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": "Attachment",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "attachment", 
+   "fieldtype": "Attach", 
+   "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": "Attachment", 
+   "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,
-   "fetch_if_empty": 0,
-   "fieldname": "via_customer_portal",
-   "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": "Via Customer Portal",
-   "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,
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fetch_if_empty": 0, 
+   "fieldname": "via_customer_portal", 
+   "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": "Via Customer Portal", 
+   "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_toolbar": 0,
- "icon": "fa fa-ticket",
- "idx": 7,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2019-04-04 10:55:40.222692",
+ ], 
+ "has_web_view": 0, 
+ "hide_toolbar": 0, 
+ "icon": "fa fa-ticket", 
+ "idx": 7, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2019-04-23 18:04:42.039620", 
  "modified_by": "Administrator",
- "module": "Support",
- "name": "Issue",
- "owner": "Administrator",
+ "module": "Support", 
+ "name": "Issue", 
+ "owner": "Administrator", 
  "permissions": [
   {
-   "amend": 0,
-   "cancel": 0,
-   "create": 1,
-   "delete": 1,
-   "email": 1,
-   "export": 0,
-   "if_owner": 0,
-   "import": 0,
-   "permlevel": 0,
-   "print": 1,
-   "read": 1,
-   "report": 1,
-   "role": "Support Team",
-   "set_user_permissions": 0,
-   "share": 1,
-   "submit": 0,
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 0, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Support Team", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
    "write": 1
   }
- ],
- "quick_entry": 1,
- "read_only": 0,
- "search_fields": "status,customer,subject,raised_by",
- "show_name_in_global_search": 0,
- "sort_order": "ASC",
- "timeline_field": "customer",
- "title_field": "subject",
- "track_changes": 0,
- "track_seen": 1,
+ ], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "search_fields": "status,customer,subject,raised_by", 
+ "show_name_in_global_search": 0, 
+ "sort_order": "ASC", 
+ "timeline_field": "customer", 
+ "title_field": "subject", 
+ "track_changes": 0, 
+ "track_seen": 1, 
  "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 01677ae..d626def 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -13,6 +13,7 @@
 from frappe.utils.user import is_website_user
 from ..service_level_agreement.service_level_agreement import get_active_service_level_agreement_for
 from erpnext.crm.doctype.opportunity.opportunity import assign_to_user
+from frappe.email.inbox import link_communication_to_document
 
 sender_field = "raised_by"
 
@@ -294,3 +295,19 @@
 			"doctype": "Task"
 		}
 	}, target_doc)
+@frappe.whitelist()
+def make_issue_from_communication(communication, ignore_communication_links=False):
+	""" raise a issue from email """
+
+	doc = frappe.get_doc("Communication", communication)
+	issue = frappe.get_doc({
+		"doctype": "Issue",
+		"subject": doc.subject,
+		"communication_medium": doc.communication_medium,
+		"raised_by": doc.sender or "",
+		"raised_by_phone": doc.phone_no or ""
+	}).insert(ignore_permissions=True)
+
+	link_communication_to_document(doc, "Issue", issue.name, ignore_communication_links)
+
+	return issue.name
diff --git a/erpnext/www/lms.html b/erpnext/www/lms.html
new file mode 100644
index 0000000..1796194
--- /dev/null
+++ b/erpnext/www/lms.html
@@ -0,0 +1,10 @@
+{% extends "templates/web.html" %}
+
+{% block title %}{{ heading or "LMS"}}{% endblock %}
+
+{% block navbar %}{% endblock %}
+
+{% block content %}
+<div id="lms-app"></div>
+<script type="text/javascript" src="/assets/js/lms.min.js"></script>
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/www/lms.py b/erpnext/www/lms.py
new file mode 100644
index 0000000..7561d73
--- /dev/null
+++ b/erpnext/www/lms.py
@@ -0,0 +1,242 @@
+from __future__ import unicode_literals
+import erpnext.education.utils as utils
+import frappe
+from frappe import _
+
+# LMS Utils to Update State for Vue Store
+@frappe.whitelist()
+def get_program_enrollments():
+	student = utils.get_current_student()
+	if student == None:
+		return None
+	return student.get_program_enrollments()
+
+@frappe.whitelist()
+def get_all_course_enrollments():
+	student = utils.get_current_student()
+	if student == None:
+		return None
+	return student.get_all_course_enrollments()
+
+# Vue Client Functions
+@frappe.whitelist(allow_guest=True)
+def get_portal_details():
+	"""
+	Returns portal details from Education Settings Doctype. This contains the Title and Description for LMS amoung other things.
+	"""
+	from erpnext import get_default_company
+
+	settings = frappe.get_doc("Education Settings")
+	title = settings.portal_title or get_default_company()
+	description = settings.description
+	return dict(title=title, description=description)
+
+@frappe.whitelist(allow_guest=True)
+def get_featured_programs():
+	featured_program_names = frappe.get_all("Program", filters={"is_published": True, "is_featured": True})
+	if featured_program_names:
+		featured_list = [utils.get_program_and_enrollment_status(program['name']) for program in featured_program_names]
+		return featured_list
+	else:
+		return get_all_programs()[:2]
+
+@frappe.whitelist(allow_guest=True)
+def get_all_programs():
+	program_names = frappe.get_all("Program", filters={"is_published": True})
+	if program_names:
+		program_list = [utils.get_program_and_enrollment_status(program['name']) for program in program_names]
+		return program_list
+
+@frappe.whitelist(allow_guest=True)
+def get_program(program_name):
+	try:
+		return frappe.get_doc('Program', program_name)
+	except frappe.DoesNotExistError:
+		frappe.throw(_("Program {0} does not exist.".format(program_name)))
+
+# Functions to get program & course details
+@frappe.whitelist(allow_guest=True)
+def get_courses(program_name):
+	program = frappe.get_doc('Program', program_name)
+	courses = program.get_course_list()
+	return courses
+
+@frappe.whitelist()
+def get_next_content(current_content, current_content_type, topic):
+	if frappe.session.user == "Guest":
+		return None
+	topic = frappe.get_doc("Topic", topic)
+	content_list = [{'content_type':item.doctype, 'content':item.name} for item in topic.get_contents()]
+	current_index = content_list.index({'content': current_content, 'content_type': current_content_type})
+	try:
+		return content_list[current_index + 1]
+	except IndexError:
+		return None
+
+def get_quiz_with_answers(quiz_name):
+	try:
+		quiz = frappe.get_doc("Quiz", quiz_name).get_questions()
+		quiz_output = [{'name':question.name, 'question':question.question, 'options':[{'name': option.name, 'option':option.option, 'is_correct':option.is_correct} for option in question.options]} for question in quiz]
+		return quiz_output
+	except:
+		frappe.throw("Quiz {0} does not exist".format(quiz_name))
+		return None
+
+@frappe.whitelist()
+def get_quiz_without_answers(quiz_name, course_name):
+	try:
+		quiz = frappe.get_doc("Quiz", quiz_name)
+		questions = quiz.get_questions()
+	except:
+		frappe.throw("Quiz {0} does not exist".format(quiz_name))
+		return None
+
+	if utils.check_super_access():
+		quiz_output = [{'name':question.name, 'question':question.question, 'type': question.type, 'options':[{'name': option.name, 'option':option.option} for option in question.options]} for question in questions]
+		return { 'quizData': quiz_output, 'status': None}
+
+	enrollment = utils.get_course_enrollment(course_name).name
+	quiz_progress = {}
+	quiz_progress['is_complete'], quiz_progress['score'], quiz_progress['result']  = utils.check_quiz_completion(quiz, enrollment)
+	quiz_output = [{'name':question.name, 'question':question.question, 'type': question.type, 'options':[{'name': option.name, 'option':option.option} for option in question.options]} for question in questions]
+	return { 'quizData': quiz_output, 'status': quiz_progress}
+
+@frappe.whitelist()
+def evaluate_quiz(course, quiz_response, quiz_name):
+	"""LMS Function: Evaluates a simple multiple choice quiz.
+	:param course: name of the course
+	:param quiz_response: contains user selected choices for a quiz in the form of a string formatted as a dictionary. The function uses `json.loads()` to convert it to a python dictionary.
+	:param quiz_name: Name of the quiz attempted
+	"""
+	import json
+	quiz_response = json.loads(quiz_response)
+	quiz = frappe.get_doc("Quiz", quiz_name)
+	answers, score, status = quiz.evaluate(quiz_response, quiz_name)
+	print(answers)
+
+	course_enrollment = utils.get_course_enrollment(course)
+	if course_enrollment:
+		course_enrollment.add_quiz_activity(quiz_name, quiz_response, answers, score, status)
+
+	return score
+
+@frappe.whitelist()
+def enroll_in_program(program_name):
+	student = utils.get_current_student()
+	if not student:
+		student = utils.create_student_from_current_user()
+	program_enrollment = student.enroll_in_program(program_name)
+	return program_name
+
+# Academdy Activity
+@frappe.whitelist()
+def add_activity(course, content_type, content):
+	if not utils.get_current_student():
+		return
+	enrollment = utils.get_course_enrollment(course)
+	enrollment.add_activity(content_type, content)
+
+@frappe.whitelist()
+def get_student_course_details(course_name, program_name):
+	"""
+	Return the porgress of a course in a program as well as the content to continue from.
+		:param course_name:
+		:param program_name:
+	"""
+	student = utils.get_current_student()
+	if not student:
+		return {'flag':'Start Course' }
+
+	course_enrollment = utils.get_course_enrollment(course_name)
+	program_enrollment = utils.get_program_enrollment(program_name)
+
+	if not program_enrollment:
+		return None
+
+	if not course_enrollment:
+		course_enrollment = utils.enroll_in_course(course_name, program_name)
+
+	progress = course_enrollment.get_progress(student)
+	count = sum([activity['is_complete'] for activity in progress])
+	if count == 0:
+		return {'flag':'Start Course'}
+	elif count == len(progress):
+		return {'flag':'Completed'}
+	elif count < len(progress):
+		next_item = next(item for item in progress if item['is_complete']==False)
+		return {'flag':'Continue'}
+
+@frappe.whitelist()
+def get_student_topic_details(topic_name, course_name):
+	"""
+	Return the porgress of a course in a program as well as the content to continue from.
+		:param topic_name:
+		:param course_name:
+	"""
+	topic = frappe.get_doc("Topic", topic_name)
+	student = utils.get_current_student()
+	if not student:
+		topic_content = topic.get_all_children()
+		if topic_content:
+			return {'flag':'Start Course', 'content_type': topic_content[0].content_type, 'content': topic_content[0].content}
+		else:
+			return None
+	course_enrollment = utils.get_course_enrollment(course_name)
+	progress = student.get_topic_progress(course_enrollment.name, topic)
+	if not progress:
+		return { 'flag':'Start Topic', 'content_type': None, 'content': None }
+	count = sum([activity['is_complete'] for activity in progress])
+	if count == 0:
+		return {'flag':'Start Topic', 'content_type': progress[0]['content_type'], 'content': progress[0]['content']}
+	elif count == len(progress):
+		return {'flag':'Completed', 'content_type': progress[0]['content_type'], 'content': progress[0]['content']}
+	elif count < len(progress):
+		next_item = next(item for item in progress if item['is_complete']==False)
+		return {'flag':'Continue', 'content_type': next_item['content_type'], 'content': next_item['content']}
+
+@frappe.whitelist()
+def get_program_progress(program_name):
+	program_enrollment = frappe.get_doc("Program Enrollment", utils.get_program_enrollment(program_name))
+	if not program_enrollment:
+		return None
+	else:
+		return program_enrollment.get_program_progress()
+
+@frappe.whitelist()
+def get_joining_date():
+	student = utils.get_current_student()
+	if student:
+		return student.joining_date
+
+@frappe.whitelist()
+def get_quiz_progress_of_program(program_name):
+	program_enrollment = frappe.get_doc("Program Enrollment", utils.get_program_enrollment(program_name))
+	if not program_enrollment:
+		return None
+	else:
+		return program_enrollment.get_quiz_progress()
+
+
+@frappe.whitelist(allow_guest=True)
+def get_course_details(course_name):
+	try:
+		course = frappe.get_doc('Course', course_name)
+		return course
+	except:
+		return None
+
+# Functions to get program & course details
+@frappe.whitelist(allow_guest=True)
+def get_topics(course_name):
+	try:
+		course = frappe.get_doc('Course', course_name)
+		return course.get_topics()
+	except frappe.DoesNotExistError:
+		frappe.throw(_("Course {0} does not exist.".format(course_name)))
+
+@frappe.whitelist()
+def get_content(content_type, content):
+	try:
+		return frappe.get_doc(content_type, content)
+	except frappe.DoesNotExistError:
+		frappe.throw(_("{0} {1} does not exist.".format(content_type, content)))
\ No newline at end of file
diff --git a/erpnext/www/test_lms.py b/erpnext/www/test_lms.py
new file mode 100644
index 0000000..e63f4c9
--- /dev/null
+++ b/erpnext/www/test_lms.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies and Contributors
+# See license.txt
+from __future__ import unicode_literals
+from erpnext.education.doctype.program.test_program import make_program_and_linked_courses
+
+import frappe
+import unittest
+
+class TestLms(unittest.TestCase):
+    pass
\ No newline at end of file