is corrective job card
diff --git a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
index 1330636..4458e6d 100644
--- a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
+++ b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
@@ -11,7 +11,6 @@
   "workstation",
   "description",
   "col_break1",
-  "skip_job_card",
   "hour_rate",
   "time_in_mins",
   "operating_cost",
@@ -118,20 +117,13 @@
    "fieldname": "sequence_id",
    "fieldtype": "Int",
    "label": "Sequence ID"
-  },
-  {
-   "allow_on_submit": 1,
-   "default": "0",
-   "fieldname": "skip_job_card",
-   "fieldtype": "Check",
-   "label": "Skip Job Card"
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-01-05 14:29:11.887888",
+ "modified": "2021-01-12 14:48:09.596843",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "BOM Operation",
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js
index 57ec20b..266d5f6 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card.js
@@ -41,6 +41,10 @@
 			}
 		}
 
+		if (frm.doc.docstatus == 1 && !frm.doc.is_corrective_job_card) {
+			frm.trigger('setup_corrective_job_card')
+		}
+
 		frm.set_query("quality_inspection", function() {
 			return {
 				query: "erpnext.stock.doctype.quality_inspection.quality_inspection.quality_inspection_query",
@@ -53,12 +57,50 @@
 
 		frm.trigger("toggle_operation_number");
 
-		if (frm.doc.docstatus == 0 && (frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity)
+		if (frm.doc.docstatus == 0 && !frm.is_new() &&
+			(frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity)
 			&& (frm.doc.items || !frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) {
 			frm.trigger("prepare_timer_buttons");
 		}
 	},
 
+	setup_corrective_job_card: function(frm) {
+		frm.add_custom_button(__('Corrective Job Card'), () => {
+			let operations = frm.doc.sub_operations.map(d => d.sub_operation).concat(frm.doc.operation);
+
+			let fields = [
+				{
+					fieldtype: 'Link', label: __('Corrective Operation'), options: 'Operation',
+					fieldname: 'operation', get_query() { return { filters: { "is_corrective_operation": 1 }}}
+				}, {
+					fieldtype: 'Link', label: __('For Operation'), options: 'Operation',
+					fieldname: 'for_operation', get_query() { return { filters: { "name": ["in", operations] }}}
+				}
+			];
+
+			frappe.prompt(fields, d => {
+					frm.events.make_corrective_job_card(frm, d.operation, d.for_operation);
+			}, __("Select Corrective Operation"));
+		}, __('Make'));
+	},
+
+	make_corrective_job_card: function(frm, operation, for_operation) {
+		frappe.call({
+			method: 'erpnext.manufacturing.doctype.job_card.job_card.make_corrective_job_card',
+			args: {
+				source_name: frm.doc.name,
+				operation: operation,
+				for_operation: for_operation
+			},
+			callback: function(r) {
+				if (r.message) {
+					frappe.model.sync(r.message);
+					frappe.set_route("Form", r.message.doctype, r.message.name);
+				}
+			}
+		});
+	},
+
 	operation: function(frm) {
 		frm.trigger("toggle_operation_number");
 
@@ -110,10 +152,9 @@
 
 		if (!frm.doc.started_time && !frm.doc.current_time) {
 			frm.add_custom_button(__("Start Job"), () => {
-				frappe.prompt({fieldtype: 'Table MultiSelect', label: __('Employee'), options: "Job Card Time Log",
-					fieldname: 'employee'}, d => {
-					debugger
-					frm.events.start_job(frm, "Work In Progress", d.employee);
+				frappe.prompt({fieldtype: 'Table MultiSelect', label: __('Select Employees'),
+					options: "Job Card Time Log", fieldname: 'employees'}, d => {
+						frm.events.start_job(frm, "Work In Progress", d.employees);
 				}, __("Assign Job to Employee"));
 			}).addClass("btn-primary");
 		} else if (frm.doc.status == "On Hold") {
@@ -138,7 +179,7 @@
 		const args = {
 			job_card_id: frm.doc.name,
 			start_time: frappe.datetime.now_datetime(),
-			employee: employee,
+			employees: employee,
 			status: status
 		};
 		frm.events.make_time_log(frm, args);
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.json b/erpnext/manufacturing/doctype/job_card/job_card.json
index 0597cdb..be7a810 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.json
+++ b/erpnext/manufacturing/doctype/job_card/job_card.json
@@ -33,9 +33,14 @@
   "total_completed_qty",
   "column_break_15",
   "total_time_in_mins",
-  "hour_rate",
   "section_break_8",
   "items",
+  "corrective_operation_section",
+  "for_job_card",
+  "is_corrective_job_card",
+  "column_break_33",
+  "hour_rate",
+  "for_operation",
   "more_information",
   "operation_id",
   "sequence_id",
@@ -331,14 +336,48 @@
    "hide_border": 1
   },
   {
+   "depends_on": "is_corrective_job_card",
    "fieldname": "hour_rate",
    "fieldtype": "Currency",
    "label": "Hour Rate"
+  },
+  {
+   "collapsible": 1,
+   "depends_on": "is_corrective_job_card",
+   "fieldname": "corrective_operation_section",
+   "fieldtype": "Section Break",
+   "label": "Corrective Operation"
+  },
+  {
+   "default": "0",
+   "fieldname": "is_corrective_job_card",
+   "fieldtype": "Check",
+   "label": "Is Corrective Job Card",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_33",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "for_job_card",
+   "fieldtype": "Link",
+   "label": "For Job Card",
+   "options": "Job Card",
+   "read_only": 1
+  },
+  {
+   "fetch_from": "for_job_card.operation",
+   "fetch_if_empty": 1,
+   "fieldname": "for_operation",
+   "fieldtype": "Link",
+   "label": "For Operation",
+   "options": "Operation"
   }
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2021-01-11 12:09:00.452032",
+ "modified": "2021-02-03 20:36:51.826944",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Job Card",
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index b2d5667..b4202e1 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -178,18 +178,27 @@
 
 		self.reset_timer_value(args)
 		if last_row and args.get("complete_time"):
-			last_row.update({
-				"to_time": get_datetime(args.get("complete_time")),
-				"operation": args.get("sub_operation"),
-				"completed_qty": args.get("completed_qty") or 0.0
-			})
+			for row in self.time_logs:
+				if not row.to_time:
+					row.update({
+						"to_time": get_datetime(args.get("complete_time")),
+						"operation": args.get("sub_operation"),
+						"completed_qty": args.get("completed_qty") or 0.0
+					})
 		elif args.get("start_time"):
-			self.append("time_logs", {
-				"from_time": get_datetime(args.get("start_time")),
-				"employee": args.get("employee"),
-				"operation": args.get("sub_operation"),
-				"completed_qty": 0.0
-			})
+			employees = args.employees
+			print(args)
+			if isinstance(employees, string_types):
+				employees = json.loads(employees)
+
+			for name in employees:
+				print(name.get('employee'))
+				self.append("time_logs", {
+					"from_time": get_datetime(args.get("start_time")),
+					"employee": name.get('employee'),
+					"operation": args.get("sub_operation"),
+					"completed_qty": 0.0
+				})
 
 		if self.status == "On Hold":
 			self.current_time = time_diff_in_seconds(last_row.to_time, last_row.from_time)
@@ -300,10 +309,24 @@
 			time_in_mins = flt(data[0].time_in_mins)
 
 		wo = frappe.get_doc('Work Order', self.work_order)
-		if self.operation_id:
+
+		if self.is_corrective_job_card:
+			self.update_corrective_in_work_order(wo)
+
+		elif self.operation_id:
 			self.validate_produced_quantity(for_quantity, wo)
 			self.update_work_order_data(for_quantity, time_in_mins, wo)
 
+	def update_corrective_in_work_order(self, wo):
+		wo.corrective_operation_cost = 0.0
+		for row in frappe.get_all('Job Card', fields = ['total_time_in_mins', 'hour_rate'],
+			filters = {'is_corrective_job_card': 1, 'docstatus': 1, 'work_order': self.work_order}):
+			wo.corrective_operation_cost += flt(row.total_time_in_mins) * flt(row.hour_rate)
+
+		wo.calculate_operating_cost()
+		wo.flags.ignore_validate_update_after_submit = True
+		wo.save()
+
 	def validate_produced_quantity(self, for_quantity, wo):
 		if self.docstatus < 2: return
 
@@ -346,7 +369,8 @@
 	def get_current_operation_data(self):
 		return frappe.get_all('Job Card',
 			fields = ["sum(total_time_in_mins) as time_in_mins", "sum(total_completed_qty) as completed_qty"],
-			filters = {"docstatus": 1, "work_order": self.work_order, "operation_id": self.operation_id})
+			filters = {"docstatus": 1, "work_order": self.work_order, "operation_id": self.operation_id,
+				"is_corrective_job_card": 0})
 
 	def set_transferred_qty_in_job_card(self, ste_doc):
 		for row in ste_doc.items:
@@ -429,6 +453,8 @@
 				.format(bold(self.operation), work_order), OperationMismatchError)
 
 	def validate_sequence_id(self):
+		if self.is_corrective_job_card: return
+
 		if not (self.work_order and self.sequence_id): return
 
 		current_operation_qty = 0.0
@@ -440,8 +466,7 @@
 
 		data = frappe.get_all("Work Order Operation",
 			fields = ["operation", "status", "completed_qty"],
-			filters={"docstatus": 1, "parent": self.work_order, "sequence_id": ('<', self.sequence_id),
-				"skip_job_card": 0},
+			filters={"docstatus": 1, "parent": self.work_order, "sequence_id": ('<', self.sequence_id)},
 			order_by = "sequence_id, idx")
 
 		message = "Job Card {0}: As per the sequence of the operations in the work order {1}".format(bold(self.name),
@@ -598,3 +623,26 @@
 			events.append(job_card_data)
 
 	return events
+
+@frappe.whitelist()
+def make_corrective_job_card(source_name, operation=None, for_operation=None, target_doc=None):
+	def set_missing_values(source, target):
+		target.is_corrective_job_card = 1
+		target.operation = operation
+		target.for_operation = for_operation
+
+		target.set('time_logs', [])
+		target.get_sub_operations()
+		target.get_required_items()
+		target.validate_time_logs()
+
+	doclist = get_mapped_doc("Job Card", source_name, {
+		"Job Card": {
+			"doctype": "Job Card",
+			"field_map": {
+				"name": "for_job_card",
+			},
+		}
+	}, target_doc, set_missing_values)
+
+	return doclist
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card_item/job_card_item.json b/erpnext/manufacturing/doctype/job_card_item/job_card_item.json
index 60a2249..a239a24 100644
--- a/erpnext/manufacturing/doctype/job_card_item/job_card_item.json
+++ b/erpnext/manufacturing/doctype/job_card_item/job_card_item.json
@@ -102,7 +102,7 @@
    "fieldtype": "Float",
    "label": "Transferred Qty",
    "no_copy": 1,
-   "print_hide": 1,
+   "print_hide": 1
   },
   {
    "fieldname": "rate",
diff --git a/erpnext/manufacturing/doctype/operation/operation.json b/erpnext/manufacturing/doctype/operation/operation.json
index 9e6f8e1..10a97ed 100644
--- a/erpnext/manufacturing/doctype/operation/operation.json
+++ b/erpnext/manufacturing/doctype/operation/operation.json
@@ -10,7 +10,7 @@
  "field_order": [
   "workstation",
   "data_2",
-  "cost_of_poor_quality_operation",
+  "is_corrective_operation",
   "job_card_section",
   "create_job_card_based_on_batch_size",
   "column_break_6",
@@ -78,13 +78,6 @@
    "label": "Create Job Card based on Batch Size"
   },
   {
-   "default": "0",
-   "description": "Cost of poor quality operation",
-   "fieldname": "cost_of_poor_quality_operation",
-   "fieldtype": "Check",
-   "label": "Is COPQ Operation"
-  },
-  {
    "collapsible": 1,
    "fieldname": "job_card_section",
    "fieldtype": "Section Break",
@@ -93,12 +86,18 @@
   {
    "fieldname": "column_break_6",
    "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "fieldname": "is_corrective_operation",
+   "fieldtype": "Check",
+   "label": "Is Corrective Operation"
   }
  ],
  "icon": "fa fa-wrench",
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2020-12-24 14:25:03.428303",
+ "modified": "2021-01-12 15:09:23.593338",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Operation",
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js
index adf6453..acb3407 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order.js
@@ -242,13 +242,13 @@
 			if(data.completed_qty != frm.doc.qty) {
 				pending_qty = frm.doc.qty - flt(data.completed_qty);
 
-				if (pending_qty && !data.skip_job_card) {
+				if (pending_qty) {
 					dialog.fields_dict.operations.df.data.push({
 						'name': data.name,
 						'operation': data.operation,
 						'workstation': data.workstation,
 						'qty': pending_qty,
-						'pending_qty': pending_qty,
+						'pending_qty': pending_qty
 					});
 				}
 			}
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index c80decb..8e99c66 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -58,6 +58,7 @@
   "actual_operating_cost",
   "additional_operating_cost",
   "column_break_24",
+  "corrective_operation_cost",
   "total_operating_cost",
   "more_info",
   "description",
@@ -534,6 +535,16 @@
    "fieldname": "batch_size",
    "fieldtype": "Float",
    "label": "Batch Size"
+  },
+  {
+   "allow_on_submit": 1,
+   "description": "From Corrective Job Card",
+   "fieldname": "corrective_operation_cost",
+   "fieldtype": "Currency",
+   "label": "Corrective Operation Cost",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1
   }
  ],
  "icon": "fa fa-cogs",
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 06cafd2..c83f539 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -130,7 +130,9 @@
 
 		variable_cost = self.actual_operating_cost if self.actual_operating_cost \
 			else self.planned_operating_cost
-		self.total_operating_cost = flt(self.additional_operating_cost) + flt(variable_cost)
+
+		self.total_operating_cost = (flt(self.additional_operating_cost)
+			+ flt(variable_cost) + flt(self.corrective_operation_cost))
 
 	def validate_work_order_against_so(self):
 		# already ordered qty
@@ -343,7 +345,6 @@
 		plan_days = cint(manufacturing_settings_doc.capacity_planning_for_days) or 30
 
 		for index, row in enumerate(self.operations):
-			if row.skip_job_card: continue
 			qty = self.qty
 			i=0
 			while qty > 0:
@@ -357,6 +358,7 @@
 					qty -= row.batch_size
 				elif qty > 0:
 					job_card_qty = qty
+					qty = 0
 
 				if job_card_qty > 0:
 					self.prepare_data_for_job_card(row, job_card_qty, index,
@@ -496,7 +498,7 @@
 			select
 				operation, description, workstation, idx,
 				base_hour_rate as hour_rate, time_in_mins,
-				"Pending" as status, parent as bom, batch_size, sequence_id, skip_job_card
+				"Pending" as status, parent as bom, batch_size, sequence_id
 			from
 				`tabBOM Operation`
 			where
diff --git a/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json b/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json
index b776909..6d8fb80 100644
--- a/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json
+++ b/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json
@@ -9,7 +9,6 @@
   "operation",
   "bom",
   "column_break_4",
-  "skip_job_card",
   "description",
   "sequence_id",
   "col_break1",
@@ -201,19 +200,12 @@
   {
    "fieldname": "column_break_4",
    "fieldtype": "Column Break"
-  },
-  {
-   "allow_on_submit": 1,
-   "default": "0",
-   "fieldname": "skip_job_card",
-   "fieldtype": "Check",
-   "label": "Skip Job Card"
   }
  ],
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-01-08 17:42:05.372163",
+ "modified": "2021-01-12 14:48:31.061286",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Work Order Operation",
diff --git a/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.js b/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.js
index 7f5bc48..ef77566 100644
--- a/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.js
+++ b/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.js
@@ -4,6 +4,66 @@
 
 frappe.query_reports["Cost of Poor Quality Report"] = {
 	"filters": [
-
+		{
+			label: __("Company"),
+			fieldname: "company",
+			fieldtype: "Link",
+			options: "Company",
+			default: frappe.defaults.get_user_default("Company"),
+			reqd: 1
+		},
+		{
+			label: __("From Date"),
+			fieldname:"from_date",
+			fieldtype: "Datetime",
+			default: frappe.datetime.convert_to_system_tz(frappe.datetime.add_months(frappe.datetime.now_datetime(), -1)),
+			reqd: 1
+		},
+		{
+			label: __("To Date"),
+			fieldname:"to_date",
+			fieldtype: "Datetime",
+			default: frappe.datetime.now_datetime(),
+			reqd: 1,
+		},
+		{
+			label: __("Job Card"),
+			fieldname: "name",
+			fieldtype: "Link",
+			options: "Job Card",
+			get_query: function() {
+				return {
+					filters: {
+						is_corrective_job_card: 1,
+						docstatus: 1
+					}
+				}
+			}
+		},
+		{
+			label: __("Work Order"),
+			fieldname: "work_order",
+			fieldtype: "Link",
+			options: "Work Order"
+		},
+		{
+			label: __("Operation"),
+			fieldname: "operation",
+			fieldtype: "Link",
+			options: "Operation",
+			get_query: function() {
+				return {
+					filters: {
+						is_corrective_operation: 1
+					}
+				}
+			}
+		},
+		{
+			label: __("Workstation"),
+			fieldname: "workstation",
+			fieldtype: "Link",
+			options: "Workstation"
+		},
 	]
 };
diff --git a/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py b/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py
index 21e7be7..2e8c191 100644
--- a/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py
+++ b/erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py
@@ -14,24 +14,34 @@
 
 	return columns, data
 
-def get_data(filters):
+def get_data(report_filters):
 	data = []
-	operations = frappe.get_all("Operation", filters = {"cost_of_poor_quality_operation": 1})
+	operations = frappe.get_all("Operation", filters = {"is_corrective_operation": 1})
 	if operations:
 		operations = [d.name for d in operations]
 		fields = ["production_item as item_code", "item_name", "work_order", "operation",
 			"workstation", "total_time_in_mins", "name", "hour_rate"]
 
+		filters = get_filters(report_filters, operations)
+
 		job_cards = frappe.get_all("Job Card", fields = fields,
-			filters = {"docstatus": 1, "operation": ("in", operations)})
+			filters = filters)
 
 		for row in job_cards:
 			row.operating_cost = flt(row.hour_rate) * (flt(row.total_time_in_mins) / 60.0)
-			update_raw_material_cost(row, filters)
-			update_time_details(row, filters, data)
+			update_raw_material_cost(row, report_filters)
+			update_time_details(row, report_filters, data)
 
 	return data
 
+def get_filters(report_filters, operations):
+	filters = {"docstatus": 1, "operation": ("in", operations), "is_corrective_job_card": 1}
+	for field in ["name", "work_order", "operation", "workstation", "company"]:
+		if report_filters.get(field):
+			filters[field] = report_filters.get(field)
+
+	return filters
+
 def update_raw_material_cost(row, filters):
 	row.rm_cost = 0.0
 	for data in frappe.get_all("Job Card Item", fields = ["amount"],
@@ -43,8 +53,10 @@
 		"operation": "", "workstation":"", "operating_cost": "", "rm_cost": "", "total_time_in_mins": ""})
 
 	i=0
-	for time_log in frappe.get_all("Job Card Time Log", fields = ["from_time", "to_time", "time_in_mins"],
-		filters={"parent": row.name, "docstatus": 1}):
+	for time_log in frappe.get_all("Job Card Time Log",
+		fields = ["from_time", "to_time", "time_in_mins"],
+		filters={"parent": row.name, "docstatus": 1,
+			"from_time": (">=", filters.from_date), "to_time": ("<=", filters.to_date)}):
 
 		if i==0:
 			i += 1
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 4cc721b..e49c9a5 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -365,7 +365,6 @@
 			"overproduction_percentage_for_work_order"))
 
 		for d in prod_order.get("operations"):
-			if d.skip_job_card: continue
 			total_completed_qty = flt(self.fg_completed_qty) + flt(prod_order.produced_qty)
 			completed_qty = d.completed_qty + (allowance_percentage/100 * d.completed_qty)
 			if total_completed_qty > flt(completed_qty):