[Enhance] Job Card (#15244)

* [Enhance] Added job card against the work order

* removed work order from timesheet

* Fixed codacy

* Added patch to make job card from the timesheet

* Timer in job card

* Dates validation in job card

* Added button to make job card from work order

* Added sub-assembly operation in the work order
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index c706be9..a01011a 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -127,6 +127,23 @@
 				if(!r.exc) frm.refresh_fields();
 			}
 		});
+	},
+
+	routing: function(frm) {
+		if (frm.doc.routing) {
+			frappe.call({
+				doc: frm.doc,
+				method: "get_routing",
+				freeze: true,
+				callback: function(r) {
+					if (!r.exc) {
+						frm.refresh_fields();
+						erpnext.bom.calculate_op_cost(frm.doc);
+						erpnext.bom.calculate_total(frm.doc);
+					}
+				}
+			});
+		}
 	}
 });
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.json b/erpnext/manufacturing/doctype/bom/bom.json
index 69a75c4..77fc498 100644
--- a/erpnext/manufacturing/doctype/bom/bom.json
+++ b/erpnext/manufacturing/doctype/bom/bom.json
@@ -479,6 +479,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "depends_on": "with_operations", 
+   "fieldname": "transfer_material_against_job_card", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Transfer Material Against Job Card", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "currency_detail", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -674,6 +707,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "routing", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Routing", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Routing", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "operations", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -1877,7 +1943,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-06-01 03:45:06.731308", 
+ "modified": "2018-07-15 11:09:19.425998", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "BOM", 
@@ -1930,5 +1996,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 98aee05..5e9f46c 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -89,6 +89,13 @@
 
 		return item
 
+	def get_routing(self):
+		if self.routing:
+			for d in frappe.get_all("BOM Operation", fields = ["*"],
+				filters = {'parenttype': 'Routing', 'parent': self.routing}):
+				child = self.append('operations', d)
+				child.hour_rate = flt(d.hour_rate / self.conversion_rate, 2)
+
 	def validate_rm_item(self, item):
 		if (item[0]['name'] in [it.item_code for it in self.items]) and item[0]['name'] == self.item:
 			frappe.throw(_("BOM #{0}: Raw material cannot be same as main Item").format(self.name))
@@ -458,6 +465,7 @@
 				self.add_to_cur_exploded_items(frappe._dict({
 					'item_code'		: d.item_code,
 					'item_name'		: d.item_name,
+					'operation'		: d.operation,
 					'source_warehouse': d.source_warehouse,
 					'description'	: d.description,
 					'image'			: d.image,
@@ -480,7 +488,7 @@
 		""" Add all items from Flat BOM of child BOM"""
 		# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
 		child_fb_items = frappe.db.sql("""select bom_item.item_code, bom_item.item_name,
-			bom_item.description, bom_item.source_warehouse,
+			bom_item.description, bom_item.source_warehouse, bom_item.operation,
 			bom_item.stock_uom, bom_item.stock_qty, bom_item.rate, bom_item.allow_transfer_for_manufacture,
 			bom_item.stock_qty / ifnull(bom.quantity, 1) as qty_consumed_per_unit
 			from `tabBOM Explosion Item` bom_item, tabBOM bom
@@ -491,6 +499,7 @@
 				'item_code'				: d['item_code'],
 				'item_name'				: d['item_name'],
 				'source_warehouse'		: d['source_warehouse'],
+				'operation'				: d['operation'],
 				'description'			: d['description'],
 				'stock_uom'				: d['stock_uom'],
 				'stock_qty'				: d['qty_consumed_per_unit'] * stock_qty,
@@ -571,7 +580,7 @@
 		query = query.format(table="BOM Explosion Item",
 			where_conditions="",
 			is_stock_item=is_stock_item,
-			select_columns = """, bom_item.source_warehouse, bom_item.allow_transfer_for_manufacture,
+			select_columns = """, bom_item.source_warehouse, bom_item.operation, bom_item.allow_transfer_for_manufacture,
 				(Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s ) as idx""")
 
 		items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
@@ -580,7 +589,7 @@
 		items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
 	else:
 		query = query.format(table="BOM Item", where_conditions="", is_stock_item=is_stock_item,
-			select_columns = ", bom_item.source_warehouse, bom_item.idx, bom_item.allow_transfer_for_manufacture")
+			select_columns = ", bom_item.source_warehouse, bom_item.idx, bom_item.operation, bom_item.allow_transfer_for_manufacture")
 		items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
 
 	for item in items:
diff --git a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
index 8c7db8f..ab3c5a1 100644
--- a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
+++ b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
@@ -54,37 +54,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "cb", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fieldname": "item_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -117,6 +86,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "cb", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "source_warehouse", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -150,6 +150,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "operation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Operation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "section_break_3", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -576,7 +609,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-07-12 16:29:55.464426", 
+ "modified": "2018-08-27 16:32:35.152139", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "BOM Explosion Item", 
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index ceee2c1..b31f692 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -17,6 +17,39 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "operation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Operation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "columns": 3, 
    "fieldname": "item_code", 
    "fieldtype": "Link", 
@@ -1000,7 +1033,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-07-12 16:16:16.815165", 
+ "modified": "2018-08-22 16:16:16.815165", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "BOM Item", 
diff --git a/erpnext/manufacturing/doctype/job_card/__init__.py b/erpnext/manufacturing/doctype/job_card/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/__init__.py
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js
new file mode 100644
index 0000000..6f5290e
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card.js
@@ -0,0 +1,113 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Job Card', {
+	refresh: function(frm) {
+		if (frm.doc.items && frm.doc.docstatus==1) {
+			if (frm.doc.for_quantity != frm.doc.transferred_qty) {
+				frm.add_custom_button(__("Material Request"), () => {
+					frm.trigger("make_material_request");
+				});
+			}
+
+			if (frm.doc.for_quantity != frm.doc.transferred_qty) {
+				frm.add_custom_button(__("Material Transfer"), () => {
+					frm.trigger("make_stock_entry");
+				});
+			}
+		}
+
+		if (frm.doc.docstatus == 0) {
+			if (!frm.doc.actual_start_date || !frm.doc.actual_end_date) {
+				frm.trigger("make_dashboard");
+			}
+
+			if (!frm.doc.actual_start_date) {
+				frm.add_custom_button(__("Start Job"), () => {
+					frm.set_value('actual_start_date', frappe.datetime.now_datetime());
+					frm.save();
+				});
+			} else if (!frm.doc.actual_end_date) {
+				frm.add_custom_button(__("Complete Job"), () => {
+					frm.set_value('actual_end_date', frappe.datetime.now_datetime());
+					frm.save();
+				});
+			}
+		}
+	},
+
+	make_dashboard: function(frm) {
+		if(frm.doc.__islocal)
+			return;
+
+		frm.dashboard.refresh();
+		const timer = `
+			<div class="stopwatch" style="font-weight:bold">
+				<span class="hours">00</span>
+				<span class="colon">:</span>
+				<span class="minutes">00</span>
+				<span class="colon">:</span>
+				<span class="seconds">00</span>
+			</div>`;
+
+		var section = frm.dashboard.add_section(timer);
+
+		if (frm.doc.actual_start_date) {
+			let currentIncrement = moment(frappe.datetime.now_datetime()).diff(moment(frm.doc.actual_start_date),"seconds");
+			initialiseTimer();
+
+			function initialiseTimer() {
+				const interval = setInterval(function() {
+					var current = setCurrentIncrement();
+					updateStopwatch(current);
+				}, 1000);
+			}
+
+			function updateStopwatch(increment) {
+				var hours = Math.floor(increment / 3600);
+				var minutes = Math.floor((increment - (hours * 3600)) / 60);
+				var seconds = increment - (hours * 3600) - (minutes * 60);
+
+				$(section).find(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
+				$(section).find(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
+				$(section).find(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());
+			}
+
+			function setCurrentIncrement() {
+				currentIncrement += 1;
+				return currentIncrement;
+			}
+		}
+	},
+
+	for_quantity: function(frm) {
+		frm.doc.items = [];
+		frm.call({
+			method: "get_required_items",
+			doc: frm.doc,
+			callback: function() {
+				refresh_field("items");
+			}
+		})
+	},
+
+	make_material_request: function(frm) {
+		frappe.model.open_mapped_doc({
+			method: "erpnext.manufacturing.doctype.job_card.job_card.make_material_request",
+			frm: frm,
+			run_link_triggers: true
+		});
+	},
+
+	make_stock_entry: function(frm) {
+		frappe.model.open_mapped_doc({
+			method: "erpnext.manufacturing.doctype.job_card.job_card.make_stock_entry",
+			frm: frm,
+			run_link_triggers: true
+		});
+	},
+
+	timer: function(frm) {
+		return `<button> Start </button>`
+	}
+});
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.json b/erpnext/manufacturing/doctype/job_card/job_card.json
new file mode 100644
index 0000000..443cad8
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card.json
@@ -0,0 +1,912 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "autoname": "PO-JOB.#####", 
+ "beta": 0, 
+ "creation": "2018-07-09 17:23:29.518745", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "work_order", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Work Order", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Work Order", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 1, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "workstation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Workstation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Workstation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "operation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Operation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "wip_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "WIP Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_4", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "Today", 
+   "fieldname": "posting_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Posting Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "company", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Company", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Company", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "for_quantity", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "For Quantity", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "0", 
+   "fieldname": "transferred_qty", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Transferred Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "timing_detail", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Timing Detail", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "employee", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Employee", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Employee", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "time_in_mins", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Time In Mins", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_13", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "actual_start_date", 
+   "fieldtype": "Datetime", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Actual Start Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "actual_end_date", 
+   "fieldtype": "Datetime", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Actual End Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "section_break_8", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Raw Materials", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "items", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Items", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Job Card Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 1, 
+   "columns": 0, 
+   "fieldname": "more_information", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "More Information", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "operation_id", 
+   "fieldtype": "Data", 
+   "hidden": 1, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Operation ID", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "bom_no", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "BOM No", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "BOM", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "project", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Project", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Project", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_20", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "remarks", 
+   "fieldtype": "Small Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Remarks", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "Open", 
+   "fieldname": "status", 
+   "fieldtype": "Select", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Status", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Open\nWork In Progress\nCancelled\nCompleted", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "amended_from", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Amended From", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "Job Card", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 1, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2018-08-28 16:50:43.576151", 
+ "modified_by": "Administrator", 
+ "module": "Manufacturing", 
+ "name": "Job Card", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 1, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "System Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }, 
+  {
+   "amend": 1, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Manufacturing User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }, 
+  {
+   "amend": 1, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Manufacturing Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "title_field": "operation", 
+ "track_changes": 1, 
+ "track_seen": 0, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
new file mode 100644
index 0000000..bce5b90
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -0,0 +1,211 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import flt, time_diff_in_hours, get_datetime
+from frappe.model.mapper import get_mapped_doc
+from frappe.model.document import Document
+
+class JobCard(Document):
+	def validate(self):
+		self.status = 'Open'
+		self.validate_actual_dates()
+		self.set_time_in_mins()
+
+	def validate_actual_dates(self):
+		if get_datetime(self.actual_start_date) > get_datetime(self.actual_end_date):
+			frappe.throw(_("Actual start date must be less than actual end date"))
+
+		if not (self.employee and self.actual_start_date and self.actual_end_date):
+			return
+
+		data = frappe.db.sql(""" select name from `tabJob Card`
+			where
+				((%(actual_start_date)s > actual_start_date and %(actual_start_date)s < actual_end_date) or
+				(%(actual_end_date)s > actual_start_date and %(actual_end_date)s < actual_end_date) or
+				(%(actual_start_date)s <= actual_start_date and %(actual_end_date)s >= actual_end_date)) and
+				name != %(name)s and employee = %(employee)s and docstatus =1
+		""", {
+			'actual_start_date': self.actual_start_date,
+			'actual_end_date': self.actual_end_date,
+			'employee': self.employee,
+			'name': self.name
+		}, as_dict=1)
+
+		if data:
+			frappe.throw(_("Start date and end date is overlapping with the job card <a href='#Form/Job Card/{0}'>{1}</a>")
+				.format(data[0].name, data[0].name))
+
+	def set_time_in_mins(self):
+		if self.actual_start_date and self.actual_end_date:
+			self.time_in_mins = time_diff_in_hours(self.actual_end_date, self.actual_start_date) * 60
+
+	def get_required_items(self):
+		if not self.get('work_order'):
+			return
+
+		doc = frappe.get_doc('Work Order', self.get('work_order'))
+		if not doc.transfer_material_against_job_card and doc.skip_transfer:
+			return
+
+		for d in doc.required_items:
+			if not d.operation:
+				frappe.throw(_("Row {0} : Operation is required against the raw material item {1}")
+					.format(d.idx, d.item_code))
+
+			if self.get('operation') == d.operation:
+				child = self.append('items', {
+					'item_code': d.item_code,
+					'source_warehouse': d.source_warehouse,
+					'uom': frappe.db.get_value("Item", d.item_code, 'stock_uom'),
+					'item_name': d.item_name,
+					'description': d.description,
+					'required_qty': (d.required_qty * flt(self.for_quantity)) / doc.qty
+				})
+
+	def on_submit(self):
+		self.validate_dates()
+		self.update_work_order()
+		self.set_transferred_qty()
+
+	def validate_dates(self):
+		if not self.actual_start_date and not self.actual_end_date:
+			frappe.throw(_("Actual start date and actual end date is mandatory"))
+
+	def on_cancel(self):
+		self.update_work_order()
+		self.set_transferred_qty()
+
+	def update_work_order(self):
+		if not self.work_order:
+			return
+
+		data = frappe.db.get_value("Job Card", {'docstatus': 1, 'operation_id': self.operation_id},
+			['sum(time_in_mins)', 'min(actual_start_date)', 'max(actual_end_date)', 'sum(for_quantity)'])
+
+		if data:
+			time_in_mins, actual_start_date, actual_end_date, for_quantity = data
+
+			wo = frappe.get_doc('Work Order', self.work_order)
+
+			for data in wo.operations:
+				if data.name == self.operation_id:
+					data.completed_qty = for_quantity
+					data.actual_operation_time = time_in_mins
+					data.actual_start_time = actual_start_date
+					data.actual_end_time = actual_end_date
+
+			wo.flags.ignore_validate_update_after_submit = True
+			wo.update_operation_status()
+			wo.calculate_operating_cost()
+			wo.set_actual_dates()
+			wo.save()
+
+	def set_transferred_qty(self):
+		if not self.items:
+			self.transferred_qty = self.for_quantity if self.docstatus == 1 else 0
+
+		if self.items:
+			self.transferred_qty = frappe.db.get_value('Stock Entry', {'job_card': self.name,
+				'work_order': self.work_order, 'docstatus': 1}, 'sum(fg_completed_qty)')
+
+		self.db_set("transferred_qty", self.transferred_qty)
+
+		qty = 0
+		if self.work_order:
+			doc = frappe.get_doc('Work Order', self.work_order)
+			if doc.transfer_material_against_job_card and not doc.skip_transfer:
+				completed = True
+				for d in doc.operations:
+					if d.status != 'Completed':
+						completed = False
+						break
+
+				if completed:
+					job_cards = frappe.get_all('Job Card', filters = {'work_order': self.work_order, 
+						'docstatus': ('!=', 2)}, fields = 'sum(transferred_qty) as qty', group_by='operation_id')
+					qty = min([d.qty for d in job_cards])
+
+			doc.db_set('material_transferred_for_manufacturing', qty)
+
+		self.set_status()
+
+	def set_status(self):
+		status = 'Cancelled' if self.docstatus == 2 else 'Work In Progress'
+
+		if self.for_quantity == self.transferred_qty:
+			status = 'Completed'
+
+		self.db_set('status', status)
+
+def update_job_card_reference(name, fieldname, value):
+	frappe.db.set_value('Job Card', name, fieldname, value)
+
+@frappe.whitelist()
+def make_material_request(source_name, target_doc=None):
+	def update_item(obj, target, source_parent):
+		target.warehouse = source_parent.wip_warehouse
+
+	def set_missing_values(source, target):
+		target.material_request_type = "Material Transfer"
+
+	doclist = get_mapped_doc("Job Card", source_name, {
+		"Job Card": {
+			"doctype": "Material Request",
+			"validation": {
+				"docstatus": ["=", 1]
+			},
+			"field_map": {
+				"name": "job_card",
+			},
+		},
+		"Job Card Item": {
+			"doctype": "Material Request Item",
+			"field_map": {
+				"required_qty": "qty",
+				"uom": "stock_uom"
+			},
+			"postprocess": update_item,
+		}
+	}, target_doc, set_missing_values)
+
+	return doclist
+
+@frappe.whitelist()
+def make_stock_entry(source_name, target_doc=None):
+	def update_item(obj, target, source_parent):
+		target.t_warehouse = source_parent.wip_warehouse
+
+	def set_missing_values(source, target):
+		target.purpose = "Material Transfer for Manufacture"
+		target.from_bom = 1
+		target.fg_completed_qty = source.get('for_quantity', 0) - source.get('transferred_qty', 0)
+		target.calculate_rate_and_amount()
+		target.set_missing_values()
+
+	doclist = get_mapped_doc("Job Card", source_name, {
+		"Job Card": {
+			"doctype": "Stock Entry",
+			"validation": {
+				"docstatus": ["=", 1]
+			},
+			"field_map": {
+				"name": "job_card",
+				"for_quantity": "fg_completed_qty"
+			},
+		},
+		"Job Card Item": {
+			"doctype": "Stock Entry Detail",
+			"field_map": {
+				"source_warehouse": "s_warehouse",
+				"required_qty": "qty",
+				"uom": "stock_uom"
+			},
+			"postprocess": update_item,
+		}
+	}, target_doc, set_missing_values)
+
+	return doclist
diff --git a/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py b/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py
new file mode 100644
index 0000000..a9811fc
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card_dashboard.py
@@ -0,0 +1,12 @@
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'job_card',
+		'transactions': [
+			{
+				'label': _('Transactions'),
+				'items': ['Material Request', 'Stock Entry']
+			}
+		]
+	}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/job_card_list.js b/erpnext/manufacturing/doctype/job_card/job_card_list.js
new file mode 100644
index 0000000..d40a9fa
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/job_card_list.js
@@ -0,0 +1,13 @@
+frappe.listview_settings['Job Card'] = {
+	get_indicator: function(doc) {
+		if (doc.status === "Work In Progress") {
+			return [__("Work In Progress"), "orange", "status,=,Work In Progress"];
+		} else if (doc.status === "Completed") {
+			return [__("Completed"), "green", "status,=,Completed"];
+		} else if (doc.docstatus == 2) {
+			return [__("Cancelled"), "red", "status,=,Cancelled"];
+		} else {
+			return [__("Open"), "red", "status,=,Open"];
+		}
+	}
+};
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.js b/erpnext/manufacturing/doctype/job_card/test_job_card.js
new file mode 100644
index 0000000..5dc7805
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/test_job_card.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Job Card", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Job Card
+		() => frappe.tests.make('Job Card', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.py b/erpnext/manufacturing/doctype/job_card/test_job_card.py
new file mode 100644
index 0000000..ca05fea
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card/test_job_card.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestJobCard(unittest.TestCase):
+	pass
diff --git a/erpnext/manufacturing/doctype/job_card_item/__init__.py b/erpnext/manufacturing/doctype/job_card_item/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_item/__init__.py
diff --git a/erpnext/manufacturing/doctype/job_card_item/job_card_item.json b/erpnext/manufacturing/doctype/job_card_item/job_card_item.json
new file mode 100644
index 0000000..bc9fe10
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_item/job_card_item.json
@@ -0,0 +1,363 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-07-09 17:20:44.737289", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "item_code", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Item Code", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "source_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 1, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Source Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "uom", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "UOM", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "UOM", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_3", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "item_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Item Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "description", 
+   "fieldtype": "Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Description", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "qty_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "required_qty", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Required Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_9", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "allow_alternative_item", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Allow Alternative Item", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 1, 
+ "max_attachments": 0, 
+ "modified": "2018-08-28 15:23:48.099459", 
+ "modified_by": "Administrator", 
+ "module": "Manufacturing", 
+ "name": "Job Card Item", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card_item/job_card_item.py b/erpnext/manufacturing/doctype/job_card_item/job_card_item.py
new file mode 100644
index 0000000..373cba2
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_item/job_card_item.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class JobCardItem(Document):
+	pass
diff --git a/erpnext/manufacturing/doctype/routing/__init__.py b/erpnext/manufacturing/doctype/routing/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/__init__.py
diff --git a/erpnext/manufacturing/doctype/routing/routing.js b/erpnext/manufacturing/doctype/routing/routing.js
new file mode 100644
index 0000000..6cfd0ba
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/routing.js
@@ -0,0 +1,58 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Routing', {
+	calculate_operating_cost: function(frm, child) {
+		const operating_cost = flt(flt(child.hour_rate) * flt(child.time_in_mins) / 60, 2);
+		frappe.model.set_value(child.doctype, child.name, "operating_cost", operating_cost);
+	}
+});
+
+frappe.ui.form.on('BOM Operation', {
+	operation: function(frm, cdt, cdn) {
+		const d = locals[cdt][cdn];
+
+		if(!d.operation) return;
+
+		frappe.call({
+			"method": "frappe.client.get",
+			args: {
+				doctype: "Operation",
+				name: d.operation
+			},
+			callback: function (data) {
+				if (data.message.description) {
+					frappe.model.set_value(d.doctype, d.name, "description", data.message.description);
+				}
+
+				if (data.message.workstation) {
+					frappe.model.set_value(d.doctype, d.name, "workstation", data.message.workstation);
+				}
+
+				frm.events.calculate_operating_cost(frm, d);
+			}
+		});
+	},
+
+	workstation: function(frm, cdt, cdn) {
+		const d = locals[cdt][cdn];
+
+		frappe.call({
+			"method": "frappe.client.get",
+			args: {
+				doctype: "Workstation",
+				name: d.workstation
+			},
+			callback: function (data) {
+				frappe.model.set_value(d.doctype, d.name, "base_hour_rate", data.message.hour_rate);
+				frappe.model.set_value(d.doctype, d.name, "hour_rate", data.message.hour_rate);
+				frm.events.calculate_operating_cost(frm, d);
+			}
+		});
+	},
+
+	time_in_mins: function(frm, cdt, cdn) {
+		const d = locals[cdt][cdn];
+		frm.events.calculate_operating_cost(frm, d);
+	}
+});
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/routing/routing.json b/erpnext/manufacturing/doctype/routing/routing.json
new file mode 100644
index 0000000..e864c0c
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/routing.json
@@ -0,0 +1,180 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "autoname": "field:routing_name", 
+ "beta": 0, 
+ "creation": "2018-07-15 11:03:24.191613", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "routing_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Routing Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 1
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "eval:!doc.__islocal", 
+   "fieldname": "disabled", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Disabled", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "operations", 
+   "fieldtype": "Table", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "BOM Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "BOM Operation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 0, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2018-07-15 11:42:41.424793", 
+ "modified_by": "Administrator", 
+ "module": "Manufacturing", 
+ "name": "Routing", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Manufacturing Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 1
+  }, 
+  {
+   "amend": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Manufacturing User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0, 
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/routing/routing.py b/erpnext/manufacturing/doctype/routing/routing.py
new file mode 100644
index 0000000..ecd0ba8
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/routing.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class Routing(Document):
+	pass
diff --git a/erpnext/manufacturing/doctype/routing/test_routing.js b/erpnext/manufacturing/doctype/routing/test_routing.js
new file mode 100644
index 0000000..6cb6549
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/test_routing.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Routing", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Routing
+		() => frappe.tests.make('Routing', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/manufacturing/doctype/routing/test_routing.py b/erpnext/manufacturing/doctype/routing/test_routing.py
new file mode 100644
index 0000000..53ad152
--- /dev/null
+++ b/erpnext/manufacturing/doctype/routing/test_routing.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestRouting(unittest.TestCase):
+	pass
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index b32db3b..fb8fd26 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -73,53 +73,6 @@
 
 		self.assertRaises(StockOverProductionError, s.submit)
 
-	def test_make_time_sheet(self):
-		from erpnext.manufacturing.doctype.work_order.work_order import make_timesheet
-		wo_order = make_wo_order_test_record(item="_Test FG Item 2",
-			planned_start_date=now(), qty=1, do_not_save=True)
-
-		wo_order.set_work_order_operations()
-		wo_order.insert()
-		wo_order.submit()
-
-		d = wo_order.operations[0]
-		d.completed_qty = flt(d.completed_qty)
-
-		name = frappe.db.get_value('Timesheet', {'work_order': wo_order.name}, 'name')
-		time_sheet_doc = frappe.get_doc('Timesheet', name)
-		self.assertEqual(wo_order.company, time_sheet_doc.company)
-		time_sheet_doc.submit()
-
-		self.assertEqual(wo_order.name, time_sheet_doc.work_order)
-		self.assertEqual((wo_order.qty - d.completed_qty),
-			sum([d.completed_qty for d in time_sheet_doc.time_logs]))
-
-		manufacturing_settings = frappe.get_doc({
-			"doctype": "Manufacturing Settings",
-			"allow_production_on_holidays": 0
-		})
-
-		manufacturing_settings.save()
-
-		wo_order.load_from_db()
-		self.assertEqual(wo_order.operations[0].status, "Completed")
-		self.assertEqual(wo_order.operations[0].completed_qty, wo_order.qty)
-
-		self.assertEqual(wo_order.operations[0].actual_operation_time, 60)
-		self.assertEqual(wo_order.operations[0].actual_operating_cost, 6000)
-
-		time_sheet_doc1 = make_timesheet(wo_order.name, wo_order.company)
-		self.assertEqual(len(time_sheet_doc1.get('time_logs')), 0)
-
-		time_sheet_doc.cancel()
-
-		wo_order.load_from_db()
-		self.assertEqual(wo_order.operations[0].status, "Pending")
-		self.assertEqual(flt(wo_order.operations[0].completed_qty), 0)
-
-		self.assertEqual(flt(wo_order.operations[0].actual_operation_time), 0)
-		self.assertEqual(flt(wo_order.operations[0].actual_operating_cost), 0)
-
 	def test_planned_operating_cost(self):
 		wo_order = make_wo_order_test_record(item="_Test FG Item 2",
 			planned_start_date=now(), qty=1, do_not_save=True)
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js
index 013183e..e85b0a5 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order.js
@@ -4,7 +4,6 @@
 frappe.ui.form.on("Work Order", {
 	setup: function(frm) {
 		frm.custom_make_buttons = {
-			'Timesheet': 'Make Timesheet',
 			'Stock Entry': 'Make Stock Entry',
 		}
 
@@ -113,13 +112,11 @@
 			frm.trigger('show_progress');
 		}
 
-		if(frm.doc.docstatus == 1 && frm.doc.status != 'Stopped'){
-			frm.add_custom_button(__('Make Timesheet'), function(){
-				frappe.model.open_mapped_doc({
-					method: "erpnext.manufacturing.doctype.work_order.work_order.make_new_timesheet",
-					frm: cur_frm
-				})
-			})
+		if (frm.doc.docstatus === 1 && frm.doc.operations
+			&& frm.doc.qty != frm.doc.material_transferred_for_manufacturing) {
+			frm.add_custom_button(__('Make Job Card'), () => {
+				frm.trigger("make_job_card")
+			}).addClass('btn-primary');
 		}
 
 		if(frm.doc.required_items && frm.doc.allow_alternative_item) {
@@ -139,6 +136,113 @@
 				});
 			}
 		}
+
+		if (frm.doc.status == "Completed" &&
+			frm.doc.__onload.backflush_raw_materials_based_on == "Material Transferred for Manufacture") {
+			frm.add_custom_button(__("Make BOM"), () => {
+				frm.trigger("make_bom");
+			});
+		}
+	},
+
+	make_job_card: function(frm) {
+		let qty = 0;
+		const fields = [{
+			fieldtype: "Link",
+			fieldname: "operation",
+			options: "Operation",
+			label: __("Operation"),
+			get_query: () => {
+				const filter_workstation = frm.doc.operations.filter(d => {
+					if (d.status != "Completed") {
+						return d;
+					}
+				});
+
+				return {
+					filters: {
+						name: ["in", (filter_workstation || []).map(d => d.operation)]
+					}
+				};
+			},
+			reqd: true
+		}, {
+			fieldtype: "Link",
+			fieldname: "workstation",
+			options: "Workstation",
+			label: __("Workstation"),
+			get_query: () => {
+				const operation = dialog.get_value("operation");
+				const filter_workstation = frm.doc.operations.filter(d => {
+					if (d.operation == operation) {
+						return d;
+					}
+				});
+
+				return {
+					filters: {
+						name: ["in", (filter_workstation || []).map(d => d.workstation)]
+					}
+				};
+			},
+			onchange: () => {
+				const operation = dialog.get_value("operation");
+				const workstation = dialog.get_value("workstation");
+				if (operation && workstation) {
+					const row = frm.doc.operations.filter(d => d.operation == operation && d.workstation == workstation)[0];
+					qty = frm.doc.qty - row.completed_qty;
+
+					if (qty > 0) {
+						dialog.set_value("qty", qty);
+					}
+				}
+			},
+			reqd: true
+		}, {
+			fieldtype: "Float",
+			fieldname: "qty",
+			label: __("For Quantity"),
+			reqd: true
+		}];
+
+		const dialog = frappe.prompt(fields, function(data) {
+			if (data.qty > qty) {
+				frappe.throw(__("For Quantity must be less than quantity {0}", [qty]));
+			}
+
+			if (data.qty <= 0) {
+				frappe.throw(__("For Quantity must be greater than zero"));
+			}
+
+			frappe.call({
+				method: "erpnext.manufacturing.doctype.work_order.work_order.make_job_card",
+				args: {
+					work_order: frm.doc.name,
+					operation: data.operation,
+					workstation: data.workstation,
+					qty: data.qty
+				},
+				callback: function(r){
+					if (r.message) {
+						var doc = frappe.model.sync(r.message)[0];
+						frappe.set_route("Form", doc.doctype, doc.name);
+					}
+				}
+			});
+		}, __("For Job Card"));
+	},
+
+	make_bom: function(frm) {
+		frappe.call({
+			method: "make_bom",
+			doc: frm.doc,
+			callback: function(r){
+				if (r.message) {
+					var doc = frappe.model.sync(r.message)[0];
+					frappe.set_route("Form", doc.doctype, doc.name);
+				}
+			}
+		});
 	},
 
 	show_progress: function(frm) {
@@ -189,7 +293,8 @@
 						frm.set_value('sales_order', "");
 						frm.trigger('set_sales_order');
 						erpnext.in_production_item_onchange = true;
-						$.each(["description", "stock_uom", "project", "bom_no", "allow_alternative_item"], function(i, field) {
+						$.each(["description", "stock_uom", "project", "bom_no",
+							"allow_alternative_item", "transfer_material_against_job_card"], function(i, field) {
 							frm.set_value(field, r.message[field]);
 						});
 
@@ -235,6 +340,9 @@
 	before_submit: function(frm) {
 		frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true);
 		frm.fields_dict.required_items.grid.toggle_reqd("source_warehouse", true);
+		if (frm.doc.operations) {
+			frm.fields_dict.operations.grid.toggle_reqd("workstation", true);
+		}
 	},
 
 	set_sales_order: function(frm) {
@@ -316,7 +424,10 @@
 				}, __("Status"));
 			}
 
-			if(!frm.doc.skip_transfer){
+			const show_start_btn = (frm.doc.skip_transfer
+				|| frm.doc.transfer_material_against_job_card) ? 0 : 1;
+
+			if (show_start_btn){
 				if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty))
 					&& frm.doc.status != 'Stopped') {
 					frm.has_start_btn = true;
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index aef2ac4..df9dd83 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -559,6 +559,39 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "depends_on": "operations",
+   "fieldname": "transfer_material_against_job_card",
+   "fieldtype": "Check",
+   "hidden": 0,
+   "ignore_user_permissions": 0,
+   "ignore_xss_filter": 0,
+   "in_filter": 0,
+   "in_global_search": 0,
+   "in_list_view": 0,
+   "in_standard_filter": 0,
+   "label": "Transfer Material Against Job Card",
+   "length": 0,
+   "no_copy": 0,
+   "permlevel": 0,
+   "precision": "",
+   "print_hide": 0,
+   "print_hide_if_no_value": 0,
+   "read_only": 0,
+   "remember_last_selected_value": 0,
+   "report_hide": 0,
+   "reqd": 0,
+   "search_index": 0,
+   "set_only_once": 0,
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
    "fieldname": "warehouses",
    "fieldtype": "Section Break",
    "hidden": 0,
@@ -1639,7 +1672,7 @@
  "issingle": 0,
  "istable": 0,
  "max_attachments": 0,
- "modified": "2018-08-29 06:28:22.983369",
+ "modified": "2018-09-05 06:28:22.983369",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Work Order",
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 6995829..1d465d5 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -190,6 +190,9 @@
 
 		for purpose, fieldname in (("Manufacture", "produced_qty"),
 			("Material Transfer for Manufacture", "material_transferred_for_manufacturing")):
+			if (purpose == 'Material Transfer for Manufacture' and
+				self.operations and self.transfer_material_against_job_card):
+				continue
 
 			qty = flt(frappe.db.sql("""select sum(fg_completed_qty)
 				from `tabStock Entry` where work_order=%s and docstatus=1
@@ -209,9 +212,6 @@
 		production_plan = frappe.get_doc('Production Plan', self.production_plan)
 		production_plan.run_method("update_produced_qty", self.produced_qty, self.production_plan_item)
 
-	def before_submit(self):
-		self.make_time_logs()
-
 	def on_submit(self):
 		if not self.wip_warehouse:
 			frappe.throw(_("Work-in-Progress Warehouse is required before Submit"))
@@ -223,18 +223,27 @@
 		self.update_completed_qty_in_material_request()
 		self.update_planned_qty()
 		self.update_ordered_qty()
+		self.create_job_card()
 
 	def on_cancel(self):
 		self.validate_cancel()
 
 		frappe.db.set(self,'status', 'Cancelled')
 		self.update_work_order_qty_in_so()
-		self.delete_timesheet()
+		self.delete_job_card()
 		self.update_completed_qty_in_material_request()
 		self.update_planned_qty()
 		self.update_ordered_qty()
 		self.update_reserved_qty_for_production()
 
+	def create_job_card(self):
+		for row in self.operations:
+			if not row.workstation:
+				frappe.throw(_("Row {0}: select the workstation against the operation {1}")
+					.format(row.idx, row.operation))
+
+			create_job_card(self, row, auto_create=True)
+
 	def validate_cancel(self):
 		if self.status == "Stopped":
 			frappe.throw(_("Stopped Work Order cannot be cancelled, Unstop it first to cancel"))
@@ -312,6 +321,17 @@
 		"""	% ", ".join(["%s"]*len(bom_list)), tuple(bom_list), as_dict=1)
 
 		self.set('operations', operations)
+
+		if self.use_multi_level_bom and self.get('operations') and self.get('items'):
+			raw_material_operations = [d.operation for d in self.get('items')]
+			operations = [d.operation for d in self.get('operations')]
+
+			for operation in raw_material_operations:
+				if operation not in operations:
+					self.append('operations', {
+						'operation': operation
+					})
+
 		self.calculate_time()
 
 	def calculate_time(self):
@@ -335,99 +355,6 @@
 
 		return holidays[holiday_list]
 
-	def make_time_logs(self, open_new=False):
-		"""Capacity Planning. Plan time logs based on earliest availablity of workstation after
-			Planned Start Date. Time logs will be created and remain in Draft mode and must be submitted
-			before manufacturing entry can be made."""
-
-		if not self.operations:
-			return
-
-		timesheets = []
-		plan_days = frappe.db.get_single_value("Manufacturing Settings", "capacity_planning_for_days") or 30
-
-		timesheet = make_timesheet(self.name, self.company)
-		timesheet.set('time_logs', [])
-
-		for i, d in enumerate(self.operations):
-
-			if d.status != 'Completed':
-				self.set_start_end_time_for_workstation(d, i)
-
-				args = self.get_operations_data(d)
-
-				add_timesheet_detail(timesheet, args)
-				original_start_time = d.planned_start_time
-
-				# validate operating hours if workstation [not mandatory] is specified
-				try:
-					timesheet.validate_time_logs()
-				except OverlapError:
-					if frappe.message_log: frappe.message_log.pop()
-					timesheet.schedule_for_work_order(d.idx)
-				except WorkstationHolidayError:
-					if frappe.message_log: frappe.message_log.pop()
-					timesheet.schedule_for_work_order(d.idx)
-
-				from_time, to_time = self.get_start_end_time(timesheet, d.name)
-
-				if date_diff(from_time, original_start_time) > plan_days:
-					frappe.throw(_("Unable to find Time Slot in the next {0} days for Operation {1}").format(plan_days, d.operation))
-					break
-
-				d.planned_start_time = from_time
-				d.planned_end_time = to_time
-				d.db_update()
-
-		if timesheet and open_new:
-			return timesheet
-
-		if timesheet and timesheet.get("time_logs"):
-			timesheet.save()
-			timesheets.append(getlink("Timesheet", timesheet.name))
-
-		self.planned_end_date = self.operations[-1].planned_end_time
-		if timesheets:
-			frappe.local.message_log = []
-			frappe.msgprint(_("Timesheet created:") + "\n" + "\n".join(timesheets))
-
-	def get_operations_data(self, data):
-		return {
-			'from_time': get_datetime(data.planned_start_time),
-			'hours': data.time_in_mins / 60.0,
-			'to_time': get_datetime(data.planned_end_time),
-			'project': self.project,
-			'operation': data.operation,
-			'operation_id': data.name,
-			'workstation': data.workstation,
-			'completed_qty': flt(self.qty) - flt(data.completed_qty)
-		}
-
-	def set_start_end_time_for_workstation(self, data, index):
-		"""Set start and end time for given operation. If first operation, set start as
-		`planned_start_date`, else add time diff to end time of earlier operation."""
-
-		if index == 0:
-			data.planned_start_time = self.planned_start_date
-		else:
-			data.planned_start_time = get_datetime(self.operations[index-1].planned_end_time)\
-								+ get_mins_between_operations()
-
-		data.planned_end_time = get_datetime(data.planned_start_time) + relativedelta(minutes = data.time_in_mins)
-
-		if data.planned_start_time == data.planned_end_time:
-			frappe.throw(_("Capacity Planning Error"))
-
-	def get_start_end_time(self, timesheet, operation_id):
-		for data in timesheet.time_logs:
-			if data.operation_id == operation_id:
-				return data.from_time, data.to_time
-
-	def check_operation_fits_in_working_hours(self, d):
-		"""Raises expection if operation is longer than working hours in the given workstation."""
-		from erpnext.manufacturing.doctype.workstation.workstation import check_if_within_operating_hours
-		check_if_within_operating_hours(d.workstation, d.operation, d.planned_start_time, d.planned_end_time)
-
 	def update_operation_status(self):
 		for d in self.get("operations"):
 			if not d.completed_qty:
@@ -451,9 +378,9 @@
 			if actual_end_dates:
 				self.actual_end_date = max(actual_end_dates)
 
-	def delete_timesheet(self):
-		for timesheet in frappe.get_all("Timesheet", ["name"], {"work_order": self.name}):
-			frappe.delete_doc("Timesheet", timesheet.name)
+	def delete_job_card(self):
+		for d in frappe.get_all("Job Card", ["name"], {"work_order": self.name}):
+			frappe.delete_doc("Job Card", d.name)
 
 	def validate_production_item(self):
 		if frappe.db.get_value("Item", self.production_item, "has_variants"):
@@ -523,6 +450,7 @@
 			else:
 				for item in sorted(item_dict.values(), key=lambda d: d['idx']):
 					self.append('required_items', {
+						'operation': item.operation,
 						'item_code': item.item_code,
 						'item_name': item.item_name,
 						'description': item.description,
@@ -573,6 +501,30 @@
 
 			d.db_set('consumed_qty', flt(consumed_qty), update_modified = False)
 
+	def make_bom(self):
+		data = frappe.db.sql(""" select sed.item_code, sed.qty, sed.s_warehouse
+			from `tabStock Entry Detail` sed, `tabStock Entry` se
+			where se.name = sed.parent and se.purpose = 'Manufacture'
+			and (sed.t_warehouse is null or sed.t_warehouse = '') and se.docstatus = 1
+			and se.work_order = %s""", (self.name), as_dict=1)
+
+		bom = frappe.new_doc("BOM")
+		bom.item = self.production_item
+		bom.conversion_rate = 1
+
+		for d in data:
+			bom.append('items', {
+				'item_code': d.item_code,
+				'qty': d.qty,
+				'source_warehouse': d.s_warehouse
+			})
+
+		if self.operations:
+			bom.set('operations', self.operations)
+			bom.with_operations = 1
+
+		bom.set_bom_material_details()
+		return bom
 
 @frappe.whitelist()
 def get_item_details(item, project = None):
@@ -609,8 +561,12 @@
 		else:
 			frappe.throw(_("Default BOM for {0} not found").format(item))
 
-	res['project'] = project or frappe.db.get_value('BOM', res['bom_no'], 'project')
-	res['allow_alternative_item'] = frappe.db.get_value('BOM', res['bom_no'], 'allow_alternative_item')
+	bom_data = frappe.db.get_value('BOM', res['bom_no'],
+		['project', 'allow_alternative_item', 'transfer_material_against_job_card'], as_dict=1)
+
+	res['project'] = project or bom_data.project
+	res['allow_alternative_item'] = bom_data.allow_alternative_item
+	res['transfer_material_against_job_card'] = bom_data.transfer_material_against_job_card
 	res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
 
 	return res
@@ -668,25 +624,6 @@
 	return stock_entry.as_dict()
 
 @frappe.whitelist()
-def make_timesheet(work_order, company):
-	timesheet = frappe.new_doc("Timesheet")
-	timesheet.employee = ""
-	timesheet.work_order = work_order
-	timesheet.company = company
-	return timesheet
-
-@frappe.whitelist()
-def add_timesheet_detail(timesheet, args):
-	if isinstance(timesheet, string_types):
-		timesheet = frappe.get_doc('Timesheet', timesheet)
-
-	if isinstance(args, string_types):
-		args = json.loads(args)
-
-	timesheet.append('time_logs', args)
-	return timesheet
-
-@frappe.whitelist()
 def get_default_warehouse():
 	wip_warehouse = frappe.db.get_single_value("Manufacturing Settings",
 		"default_wip_warehouse")
@@ -695,16 +632,6 @@
 	return {"wip_warehouse": wip_warehouse, "fg_warehouse": fg_warehouse}
 
 @frappe.whitelist()
-def make_new_timesheet(source_name, target_doc=None):
-	po = frappe.get_doc('Work Order', source_name)
-	ts = po.make_time_logs(open_new=True)
-
-	if not ts or not ts.get('time_logs'):
-		frappe.throw(_("Already completed"))
-
-	return ts
-
-@frappe.whitelist()
 def stop_unstop(work_order, status):
 	""" Called from client side on Stop/Unstop event"""
 
@@ -730,3 +657,40 @@
 	""", (production_item, production_item))
 
 	return out
+
+@frappe.whitelist()
+def make_job_card(work_order, operation, workstation, qty=0):
+	work_order = frappe.get_doc('Work Order', work_order)
+	row = get_work_order_operation_data(work_order, operation, workstation)
+	if row:
+		return create_job_card(work_order, row, qty)
+
+def create_job_card(work_order, row, qty=0, auto_create=False):
+	doc = frappe.new_doc("Job Card")
+	doc.update({
+		'work_order': work_order.name,
+		'operation': row.operation,
+		'workstation': row.workstation,
+		'posting_date': nowdate(),
+		'for_quantity': qty or work_order.get('qty', 0),
+		'operation_id': row.name,
+		'bom_no': work_order.bom_no,
+		'project': work_order.project,
+		'company': work_order.company,
+		'wip_warehouse': work_order.wip_warehouse
+	})
+
+	if work_order.transfer_material_against_job_card and not work_order.skip_transfer:
+		doc.get_required_items()
+
+	if auto_create:
+		doc.flags.ignore_mandatory = True
+		doc.insert()
+		frappe.msgprint(_("Job card {0} created").format(doc.name))
+
+	return doc
+
+def get_work_order_operation_data(work_order, operation, workstation):
+	for d in work_order.operations:
+		if d.operation == operation and d.workstation == workstation:
+			return d
diff --git a/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py b/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py
index 9b7c9a3..02fbfcd 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py
@@ -5,7 +5,7 @@
 		'fieldname': 'work_order',
 		'transactions': [
 			{
-				'items': ['Stock Entry', 'Timesheet']
+				'items': ['Stock Entry', 'Job Card']
 			}
 		]
 	}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
index badeb91..6dbb494 100644
--- a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
+++ b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
@@ -19,6 +19,39 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "operation", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Operation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Operation", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "item_code", 
    "fieldtype": "Link", 
    "hidden": 0, 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 0fe66e3..a83dfd6 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -563,4 +563,5 @@
 erpnext.patches.v11_0.update_hub_url # 2018-08-31  # 2018-09-03
 erpnext.patches.v10_0.set_discount_amount
 erpnext.patches.v10_0.recalculate_gross_margin_for_project
+erpnext.patches.v11_0.make_job_card
 erpnext.patches.v11_0.redesign_healthcare_billing_work_flow
diff --git a/erpnext/patches/v11_0/make_job_card.py b/erpnext/patches/v11_0/make_job_card.py
new file mode 100644
index 0000000..ab9c7c4
--- /dev/null
+++ b/erpnext/patches/v11_0/make_job_card.py
@@ -0,0 +1,18 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	frappe.reload_doc('manufacturing', 'doctype', 'work_order')
+	frappe.reload_doc('manufacturing', 'doctype', 'work_order_item')
+	frappe.reload_doc('manufacturing', 'doctype', 'job_card')
+	frappe.reload_doc('manufacturing', 'doctype', 'job_card_item')
+
+	for d in frappe.db.sql("""select work_order, name from tabTimesheet
+		where (work_order is not null and work_order != '') and docstatus = 0""", as_dict=1):
+		if d.work_order:
+			doc = frappe.get_doc('Work Order', d.work_order)
+			doc.make_job_card()
+			frappe.delete_doc('Timesheet', d.name)
\ No newline at end of file
diff --git a/erpnext/projects/doctype/timesheet/timesheet.json b/erpnext/projects/doctype/timesheet/timesheet.json
index d1ec38c..e5198de 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.json
+++ b/erpnext/projects/doctype/timesheet/timesheet.json
@@ -457,6 +457,39 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 1, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "User", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "User", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "start_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
    "in_global_search": 0, 
    "in_list_view": 1, 
    "in_standard_filter": 0, 
@@ -514,73 +547,6 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "collapsible_depends_on": "", 
-   "columns": 0, 
-   "depends_on": "work_order", 
-   "fieldname": "work_detail", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Work Detail", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "work_order", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Work Order", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Work Order", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
    "columns": 0, 
    "fieldname": "section_break_5", 
    "fieldtype": "Section Break", 
@@ -1066,7 +1032,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 14:44:32.912004", 
+ "modified": "2018-08-28 14:44:32.912004", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Timesheet", 
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 7dc121c..f48c0c6 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -97,19 +97,13 @@
 		self.set_status()
 
 	def on_cancel(self):
-		self.update_work_order(None)
 		self.update_task_and_project()
 
 	def on_submit(self):
 		self.validate_mandatory_fields()
-		self.update_work_order(self.name)
 		self.update_task_and_project()
 
 	def validate_mandatory_fields(self):
-		if self.work_order:
-			work_order = frappe.get_doc("Work Order", self.work_order)
-			pending_qty = flt(work_order.qty) - flt(work_order.produced_qty)
-
 		for data in self.time_logs:
 			if not data.from_time and not data.to_time:
 				frappe.throw(_("Row {0}: From Time and To Time is mandatory.").format(data.idx))
@@ -120,41 +114,6 @@
 			if flt(data.hours) == 0.0:
 				frappe.throw(_("Row {0}: Hours value must be greater than zero.").format(data.idx))
 
-			if self.work_order and flt(data.completed_qty) == 0:
-				frappe.throw(_("Row {0}: Completed Qty must be greater than zero.").format(data.idx))
-
-			if self.work_order and flt(pending_qty) < flt(data.completed_qty) and flt(pending_qty) > 0:
-				frappe.throw(_("Row {0}: Completed Qty cannot be more than {1} for operation {2}").format(data.idx, pending_qty, data.operation),
-					OverWorkLoggedError)
-
-	def update_work_order(self, time_sheet):
-		if self.work_order:
-			pro = frappe.get_doc('Work Order', self.work_order)
-
-			for timesheet in self.time_logs:
-				for data in pro.operations:
-					if data.name == timesheet.operation_id:
-						summary = self.get_actual_timesheet_summary(timesheet.operation_id)
-						data.time_sheet = time_sheet
-						data.completed_qty = summary.completed_qty
-						data.actual_operation_time = summary.mins
-						data.actual_start_time = summary.from_time
-						data.actual_end_time = summary.to_time
-
-			pro.flags.ignore_validate_update_after_submit = True
-			pro.update_operation_status()
-			pro.calculate_operating_cost()
-			pro.set_actual_dates()
-			pro.save()
-
-	def get_actual_timesheet_summary(self, operation_id):
-		"""Returns 'Actual Operating Time'. """
-		return frappe.db.sql("""select
-			sum(tsd.hours*60) as mins, sum(tsd.completed_qty) as completed_qty, min(tsd.from_time) as from_time,
-			max(tsd.to_time) as to_time from `tabTimesheet Detail` as tsd, `tabTimesheet` as ts where
-			ts.work_order = %s and tsd.operation_id = %s and ts.docstatus=1 and ts.name = tsd.parent""",
-			(self.work_order, operation_id), as_dict=1)[0]
-
 	def update_task_and_project(self):
 		tasks, projects = [], []
 
@@ -176,16 +135,12 @@
 
 	def validate_time_logs(self):
 		for data in self.get('time_logs'):
-			self.check_workstation_timings(data)
 			self.validate_overlap(data)
 
 	def validate_overlap(self, data):
 		settings = frappe.get_single('Projects Settings')
-		if self.work_order:
-			self.validate_overlap_for("workstation", data, data.workstation, settings.ignore_workstation_time_overlap)
-		else:
-			self.validate_overlap_for("user", data, self.user, settings.ignore_user_time_overlap)
-			self.validate_overlap_for("employee", data, self.employee, settings.ignore_employee_time_overlap)
+		self.validate_overlap_for("user", data, self.user, settings.ignore_user_time_overlap)
+		self.validate_overlap_for("employee", data, self.employee, settings.ignore_employee_time_overlap)
 
 	def validate_overlap_for(self, fieldname, args, value, ignore_validation=False):
 		if not value or ignore_validation:
@@ -227,48 +182,6 @@
 
 		return existing[0] if existing else None
 
-	def check_workstation_timings(self, args):
-		"""Checks if **Time Log** is between operating hours of the **Workstation**."""
-		if args.workstation and args.from_time and args.to_time:
-			check_if_within_operating_hours(args.workstation, args.operation, args.from_time, args.to_time)
-
-	def schedule_for_work_order(self, index):
-		for data in self.time_logs:
-			if data.idx == index:
-				self.move_to_next_day(data) #check for workstation holiday
-				self.move_to_next_non_overlapping_slot(data) #check for overlap
-				break
-
-	def move_to_next_non_overlapping_slot(self, data):
-		overlapping = self.get_overlap_for("workstation", data, data.workstation)
-		if overlapping:
-			time_sheet = self.get_last_working_slot(overlapping.name, data.workstation)
-			data.from_time = get_datetime(time_sheet.to_time) + get_mins_between_operations()
-			data.to_time = self.get_to_time(data)
-			self.check_workstation_working_day(data)
-
-	def get_last_working_slot(self, time_sheet, workstation):
-		return frappe.db.sql(""" select max(from_time) as from_time, max(to_time) as to_time
-			from `tabTimesheet Detail` where workstation = %(workstation)s""",
-			{'workstation': workstation}, as_dict=True)[0]
-
-	def move_to_next_day(self, data):
-		"""Move start and end time one day forward"""
-		self.check_workstation_working_day(data)
-
-	def check_workstation_working_day(self, data):
-		while True:
-			try:
-				self.check_workstation_timings(data)
-				break
-			except WorkstationHolidayError:
-				if frappe.message_log: frappe.message_log.pop()
-				data.from_time = get_datetime(data.from_time) + timedelta(hours=24)
-				data.to_time = self.get_to_time(data)
-
-	def get_to_time(self, data):
-		return get_datetime(data.from_time) + timedelta(hours=data.hours)
-
 	def update_cost(self):
 		for data in self.time_logs:
 			if data.activity_type or data.billable:
diff --git a/erpnext/stock/doctype/material_request/material_request.json b/erpnext/stock/doctype/material_request/material_request.json
index 9927265..c0285cb 100644
--- a/erpnext/stock/doctype/material_request/material_request.json
+++ b/erpnext/stock/doctype/material_request/material_request.json
@@ -779,6 +779,39 @@
    "set_only_once": 0,
    "translatable": 0,
    "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "job_card", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Job Card", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Job Card", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
   }
  ],
  "has_web_view": 0,
@@ -793,7 +826,7 @@
  "istable": 0,
  "max_attachments": 0,
  "menu_index": 0,
- "modified": "2018-08-30 07:28:01.070112",
+ "modified": "2018-09-05 07:28:01.070112",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 730ec3e..42c8370 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -15,6 +15,7 @@
 from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
 from erpnext.buying.utils import check_for_closed_status, validate_for_items
 from erpnext.stock.doctype.item.item import get_item_defaults
+from erpnext.manufacturing.doctype.job_card.job_card import update_job_card_reference
 
 from six import string_types
 
@@ -92,6 +93,9 @@
 		if self.material_request_type == 'Purchase':
 			self.validate_budget()
 
+		if self.job_card:
+			update_job_card_reference(self.job_card, 'material_request', self.name)
+
 	def before_save(self):
 		self.set_status(update=True)
 
@@ -144,6 +148,8 @@
 	def on_cancel(self):
 		self.update_requested_qty()
 		self.update_requested_qty_in_production_plan()
+		if self.job_card:
+			update_job_card_reference(self.job_card, 'material_request', None)
 
 	def update_completed_qty(self, mr_items=None, update_modified=True):
 		if self.material_request_type == "Purchase":
@@ -407,7 +413,11 @@
 
 	def set_missing_values(source, target):
 		target.purpose = source.material_request_type
+		if source.job_card:
+			target.purpose = 'Material Transfer for Manufacture'
+
 		target.run_method("calculate_rate_and_amount")
+		target.set_job_card_data()
 
 	doclist = get_mapped_doc("Material Request", source_name, {
 		"Material Request": {
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index fa3501a..0356b0e 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -654,7 +654,7 @@
 	work_order: function() {
 		var me = this;
 		this.toggle_enable_bom();
-		if(!me.frm.doc.work_order) {
+		if(!me.frm.doc.work_order || me.frm.doc.job_card) {
 			return;
 		}
 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json
index 0e3fbec..35f8c27 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.json
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -1943,6 +1943,39 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
+   "fieldname": "job_card",
+   "fieldtype": "Link",
+   "hidden": 0,
+   "ignore_user_permissions": 0,
+   "ignore_xss_filter": 0,
+   "in_filter": 0,
+   "in_global_search": 0,
+   "in_list_view": 0,
+   "in_standard_filter": 0,
+   "label": "Job Card",
+   "length": 0,
+   "no_copy": 0,
+   "options": "Job Card",
+   "permlevel": 0,
+   "precision": "",
+   "print_hide": 1,
+   "print_hide_if_no_value": 0,
+   "read_only": 1,
+   "remember_last_selected_value": 0,
+   "report_hide": 0,
+   "reqd": 0,
+   "search_index": 0,
+   "set_only_once": 0, 
+   "translatable": 0,
+   "unique": 0
+  },
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
    "fieldname": "amended_from",
    "fieldtype": "Link",
    "hidden": 0,
@@ -2015,7 +2048,7 @@
  "issingle": 0,
  "istable": 0,
  "max_attachments": 0,
- "modified": "2018-08-29 06:27:59.630826",
+ "modified": "2018-09-05 06:27:59.630826",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Entry",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index f723fcf..b7dbda2 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -17,6 +17,7 @@
 from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit, get_serial_nos
 
 import json
+from erpnext.manufacturing.doctype.job_card.job_card import update_job_card_reference
 
 from six import string_types, itervalues, iteritems
 
@@ -59,6 +60,7 @@
 		self.validate_batch()
 		self.validate_inspection()
 		self.validate_fg_completed_qty()
+		self.set_job_card_data()
 
 		if not self.from_bom:
 			self.fg_completed_qty = 0.0
@@ -88,6 +90,9 @@
 			self.update_so_in_serial_number()
 
 
+		if self.job_card:
+			update_job_card_reference(self.job_card, 'stock_entry', self.name)
+
 	def on_cancel(self):
 
 		if self.purchase_order and self.purpose == "Subcontract":
@@ -102,6 +107,18 @@
 		self.make_gl_entries_on_cancel()
 		self.update_cost_in_project()
 
+		if self.job_card:
+			update_job_card_reference(self.job_card, 'stock_entry', None)
+
+	def set_job_card_data(self):
+		if self.job_card and not self.work_order:
+			data = frappe.db.get_value('Job Card',
+				self.job_card, ['for_quantity', 'work_order', 'bom_no'], as_dict=1)
+			self.fg_completed_qty = data.for_quantity
+			self.work_order = data.work_order
+			self.from_bom = 1
+			self.bom_no = data.bom_no
+
 	def validate_work_order_status(self):
 		pro_doc = frappe.get_doc("Work Order", self.work_order)
 		if pro_doc.status == 'Completed':
@@ -584,6 +601,10 @@
 			if pro_doc.status == 'Stopped':
 				frappe.throw(_("Transaction not allowed against stopped Work Order {0}").format(self.work_order))
 
+		if self.job_card:
+			job_doc = frappe.get_doc('Job Card', self.job_card)
+			job_doc.set_transferred_qty()
+
 		if self.work_order:
 			pro_doc = frappe.get_doc("Work Order", self.work_order)
 			_validate_work_order(pro_doc)