[cleanup] job opening and job applicant
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index f47185e..0e50149 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -42,7 +42,7 @@
 
 fixtures = ["Web Form"]
 
-website_generators = ["Item Group", "Item", "Sales Partner"]
+website_generators = ["Item Group", "Item", "Sales Partner", "Job Opening"]
 
 website_context = {
 	"favicon": 	"/assets/erpnext/images/favicon.png",
@@ -72,12 +72,6 @@
 		}
 	},
 	{"from_route": "/jobs", "to_route": "Job Opening"},
-	{"from_route": "/jobs/<path:name>", "to_route": "job_opening",
-		"defaults": {
-			"doctype": "Job Opening",
-			"parents": [{"title": _("Job Opening"), "name": "jobs"}]
-		}
-	}
 ]
 
 has_website_permission = {
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.json b/erpnext/hr/doctype/job_applicant/job_applicant.json
index fc579cb..6bb9ea7 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant.json
+++ b/erpnext/hr/doctype/job_applicant/job_applicant.json
@@ -18,6 +18,7 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Applicant Name", 
@@ -41,6 +42,7 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "label": "Email Id", 
@@ -65,6 +67,7 @@
    "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Status", 
@@ -89,6 +92,7 @@
    "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "length": 0, 
@@ -112,6 +116,7 @@
    "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Job Opening", 
@@ -132,15 +137,17 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "section_break_5", 
+   "fieldname": "section_break_6", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -154,16 +161,43 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "thread_html", 
-   "fieldtype": "HTML", 
+   "fieldname": "cover_letter", 
+   "fieldtype": "Text", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "Thread HTML", 
+   "label": "Cover Letter", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "fieldname": "resume_attachment", 
+   "fieldtype": "Attach", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Resume Attachment", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -184,7 +218,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-02-19 16:43:24.705867", 
+ "modified": "2016-03-02 02:22:31.941850", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Job Applicant", 
@@ -204,33 +238,11 @@
    "print": 1, 
    "read": 1, 
    "report": 1, 
-   "restrict": 0, 
-   "restricted": 0, 
    "role": "HR User", 
    "set_user_permissions": 0, 
    "share": 1, 
    "submit": 0, 
    "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 0, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 0, 
-   "read": 1, 
-   "report": 0, 
-   "role": "Guest", 
-   "set_user_permissions": 0, 
-   "share": 0, 
-   "submit": 0, 
-   "write": 0
   }
  ], 
  "read_only": 0, 
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.py b/erpnext/hr/doctype/job_applicant/job_applicant.py
index f1c0362..56c31cd 100644
--- a/erpnext/hr/doctype/job_applicant/job_applicant.py
+++ b/erpnext/hr/doctype/job_applicant/job_applicant.py
@@ -28,13 +28,6 @@
 	def validate(self):
 		self.check_email_id_is_unique()
 		validate_email_add(self.email_id, True)
-		if frappe.db.sql("""select applicant_name from `tabJob Applicant` where email_id= %s and job_title= %s""",
-				(self.email_id, self.job_title)):
-					frappe.throw(_("Application already exist for {0} against Job Opening - {1}")
-						.format(self.applicant_name, self.job_title), DuplicationError)
-		
-		if not self.get("__islocal") and not self.upload_cv:
-			frappe.throw(_("CV Required"))
 
 	def check_email_id_is_unique(self):
 		if self.email_id:
@@ -44,4 +37,3 @@
 			if names:
 				frappe.throw(_("Email id must be unique, already exists for {0}").format(comma_and(names)), frappe.DuplicateEntryError)
 
-		
\ No newline at end of file
diff --git a/erpnext/hr/doctype/job_opening/job_opening.json b/erpnext/hr/doctype/job_opening/job_opening.json
index d05fe48..3cf1431 100644
--- a/erpnext/hr/doctype/job_opening/job_opening.json
+++ b/erpnext/hr/doctype/job_opening/job_opening.json
@@ -18,6 +18,7 @@
    "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Job Title", 
@@ -37,10 +38,36 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "publish", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Publish on website", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "status", 
    "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Status", 
@@ -66,6 +93,7 @@
    "fieldtype": "Text Editor", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Description", 
@@ -80,6 +108,58 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "depends_on": "publish", 
+   "fieldname": "page_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Page Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "default": "jobs", 
+   "fieldname": "parent_website_route", 
+   "fieldtype": "Data", 
+   "hidden": 1, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Parent Website Route", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
   }
  ], 
  "hide_heading": 0, 
@@ -92,7 +172,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-02-17 17:29:04.401527", 
+ "modified": "2016-03-02 01:44:28.280777", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Job Opening", 
@@ -117,26 +197,6 @@
    "share": 1, 
    "submit": 0, 
    "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 0, 
-   "delete": 0, 
-   "email": 0, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 0, 
-   "read": 1, 
-   "report": 0, 
-   "role": "Guest", 
-   "set_user_permissions": 0, 
-   "share": 0, 
-   "submit": 0, 
-   "write": 0
   }
  ], 
  "read_only": 0, 
diff --git a/erpnext/hr/doctype/job_opening/job_opening.py b/erpnext/hr/doctype/job_opening/job_opening.py
index b9f9ffe..7c42a76 100644
--- a/erpnext/hr/doctype/job_opening/job_opening.py
+++ b/erpnext/hr/doctype/job_opening/job_opening.py
@@ -6,7 +6,19 @@
 from __future__ import unicode_literals
 import frappe
 
-from frappe.model.document import Document
+from frappe.website.website_generator import WebsiteGenerator
+from frappe import _
 
-class JobOpening(Document):
-	pass
\ No newline at end of file
+class JobOpening(WebsiteGenerator):
+	website = frappe._dict(
+		template = "templates/generators/job_opening.html",
+		condition_field = "publish",
+		page_title_field = "job_title",
+	)
+
+	def get_context(self, context):
+		context.parents = [{'name': 'jobs', 'title': _('All Jobs') }]
+
+def get_list_context(context):
+	context.title = _("Jobs")
+	context.introduction = _('Current Job Openings')
diff --git a/erpnext/templates/generators/job_opening.html b/erpnext/templates/generators/job_opening.html
new file mode 100644
index 0000000..9cfa888
--- /dev/null
+++ b/erpnext/templates/generators/job_opening.html
@@ -0,0 +1,19 @@
+{% extends "templates/web.html" %}
+
+{% block breadcrumbs %}
+	{% include "templates/includes/breadcrumbs.html" %}
+{% endblock %}
+
+{% block header %}
+<h1>{{ job_title }}</h1>
+{% endblock %}
+
+{% block page_content %}
+
+<div>{{ description }}</div>
+
+<a class='btn btn-primary'
+	href='/job_application?job_title={{ doc.job_title }}'>
+	{{ _("Apply Now") }}</a>
+
+{% endblock %}
diff --git a/erpnext/templates/pages/job_opening.html b/erpnext/templates/pages/job_opening.html
deleted file mode 100644
index 6a7ceb1..0000000
--- a/erpnext/templates/pages/job_opening.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-<head>
-<title>{{doc.job_title}}</title>
-</head>
-{% extends "templates/web.html" %}
-{% block header %}
-<h1>{{ doc.job_title }}</h1>
-{% endblock %}
-
-{% block breadcrumbs %}
-	{% include "templates/includes/breadcrumbs.html" %}
-{% endblock %}
-
-{% block page_content %}
-
-<p>{{ doc.description }}</p>
-
-<input class="btn btn-large btn-primary" type="button" onclick="location.href='/job_application?job_title={{ doc.job_title }}';" value="Apply Now" />
-
-{% endblock %}
\ No newline at end of file
diff --git a/erpnext/templates/pages/job_opening.py b/erpnext/templates/pages/job_opening.py
deleted file mode 100644
index 1bcfce2..0000000
--- a/erpnext/templates/pages/job_opening.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-
-from frappe import _
-
-def get_context(context):
-	context.no_cache = 1
-	context.doc = frappe.get_doc(frappe.form_dict.doctype, frappe.form_dict.name)
-	context.parents = frappe.form_dict.parents
-
-	if not context.doc.has_website_permission("read"):
-		frappe.throw(_("Not Permitted"), frappe.PermissionError)
-