diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 44abb33..3d38aca 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -29,7 +29,6 @@
 		"public/js/help_links.js",
 		"public/js/agriculture/ternary_plot.js",
 		"public/js/templates/item_quick_entry.html",
-		"public/js/utils/item_quick_entry.js",
 		"public/js/utils/customer_quick_entry.js",
 		"public/js/utils/supplier_quick_entry.js",
 		"public/js/education/student_button.html",
diff --git a/erpnext/public/js/erpnext.bundle.js b/erpnext/public/js/erpnext.bundle.js
index 7b230af..cc020fc 100644
--- a/erpnext/public/js/erpnext.bundle.js
+++ b/erpnext/public/js/erpnext.bundle.js
@@ -12,7 +12,6 @@
 import "./help_links";
 import "./agriculture/ternary_plot";
 import "./templates/item_quick_entry.html";
-import "./utils/item_quick_entry";
 import "./utils/contact_address_quick_entry";
 import "./utils/customer_quick_entry";
 import "./utils/supplier_quick_entry";
diff --git a/erpnext/public/js/utils/item_quick_entry.js b/erpnext/public/js/utils/item_quick_entry.js
deleted file mode 100644
index 7e0198d..0000000
--- a/erpnext/public/js/utils/item_quick_entry.js
+++ /dev/null
@@ -1,407 +0,0 @@
-frappe.provide('frappe.ui.form');
-
-frappe.ui.form.ItemQuickEntryForm = class ItemQuickEntryForm extends frappe.ui.form.QuickEntryForm {
-	constructor(doctype, after_insert) {
-		super(doctype, after_insert);
-	}
-
-	render_dialog() {
-		this.mandatory = this.get_variant_fields().concat(this.mandatory);
-		this.mandatory = this.mandatory.concat(this.get_attributes_fields());
-		this.check_naming_series_based_on();
-		super.render_dialog();
-		this.init_post_render_dialog_operations();
-		this.preset_fields_for_template();
-		this.dialog.$wrapper.find('.edit-full').text(__('Edit in full page for more options like assets, serial nos, batches etc.'))
-	}
-
-	check_naming_series_based_on() {
-		if (frappe.defaults.get_default("item_naming_by") === "Naming Series") {
-			this.mandatory = this.mandatory.filter(d => d.fieldname !== "item_code");
-		}
-	}
-
-	init_post_render_dialog_operations() {
-		this.dialog.fields_dict.attribute_html.$wrapper.append(frappe.render_template("item_quick_entry"));
-		this.init_for_create_variant_trigger();
-		this.init_for_item_template_trigger();
-		// explicitly hide manufacturing fields as hidden not working.
-		this.toggle_manufacturer_fields();
-		this.dialog.get_field("item_template").df.hidden = 1;
-		this.dialog.get_field("item_template").refresh();
-	}
-
-	register_primary_action() {
-		var me = this;
-		this.dialog.set_primary_action(__('Save'), function() {
-			if (me.dialog.working) return;
-
-			var data = me.dialog.get_values();
-			var variant_values = {};
-
-			if (me.dialog.fields_dict.create_variant.$input.prop("checked")) {
-				variant_values = me.get_variant_doc();
-				if (!Object.keys(variant_values).length) {
-					data = null;
-				}
-				variant_values.stock_uom = me.template_doc.stock_uom;
-				variant_values.item_group = me.template_doc.item_group;
-			}
-
-			if (data) {
-				me.dialog.working = true;
-				var values = me.update_doc();
-				//patch for manufacturer type variants as extend is overwriting it.
-				if (variant_values['variant_based_on'] == "Manufacturer") {
-					values['variant_based_on'] = "Manufacturer";
-				}
-				$.extend(variant_values, values);
-				me.insert(variant_values);
-			}
-		});
-	}
-
-	insert(variant_values) {
-		let me = this;
-		return new Promise(resolve => {
-			frappe.call({
-				method: "frappe.client.insert",
-				args: {
-					doc: variant_values
-				},
-				callback: function(r) {
-					me.dialog.hide();
-					// delete the old doc
-					frappe.model.clear_doc(me.dialog.doc.doctype, me.dialog.doc.name);
-					me.dialog.doc = r.message;
-					if (frappe._from_link) {
-						frappe.ui.form.update_calling_link(me.dialog.doc);
-					} else {
-						if (me.after_insert) {
-							me.after_insert(me.dialog.doc);
-						} else {
-							me.open_form_if_not_list();
-						}
-					}
-				},
-				error: function() {
-					me.open_doc();
-				},
-				always: function() {
-					me.dialog.working = false;
-					resolve(me.dialog.doc);
-				},
-				freeze: true
-			});
-		});
-	}
-
-	open_doc() {
-		this.dialog.hide();
-		this.update_doc();
-		if (this.dialog.fields_dict.create_variant.$input.prop("checked")) {
-			var template = this.dialog.fields_dict.item_template.input.value;
-			if (template)
-				frappe.set_route("Form", this.doctype, template);
-		} else {
-			frappe.set_route('Form', this.doctype, this.doc.name);
-		}
-	}
-
-	get_variant_fields() {
-		var variant_fields = [{
-			fieldname: "create_variant",
-			fieldtype: "Check",
-			label: __("Create Variant")
-		},
-		{
-			fieldname: 'item_template',
-			label: __('Item Template'),
-			reqd: 0,
-			fieldtype: 'Link',
-			options: "Item",
-			get_query: function() {
-				return {
-					filters: {
-						"has_variants": 1
-					}
-				};
-			}
-		}];
-
-		return variant_fields;
-	}
-
-	get_manufacturing_fields() {
-		this.manufacturer_fields = [{
-			fieldtype: 'Link',
-			options: 'Manufacturer',
-			label: 'Manufacturer',
-			fieldname: "manufacturer",
-			hidden: 1,
-			reqd: 0
-		}, {
-			fieldtype: 'Data',
-			label: 'Manufacturer Part Number',
-			fieldname: 'manufacturer_part_no',
-			hidden: 1,
-			reqd: 0
-		}];
-		return this.manufacturer_fields;
-	}
-
-	get_attributes_fields() {
-		var attribute_fields = [{
-			fieldname: 'attribute_html',
-			fieldtype: 'HTML'
-		}]
-
-		attribute_fields = attribute_fields.concat(this.get_manufacturing_fields());
-		return attribute_fields;
-	}
-
-	init_for_create_variant_trigger() {
-		var me = this;
-
-		this.dialog.fields_dict.create_variant.$input.on("click", function() {
-			me.preset_fields_for_template();
-			me.init_post_template_trigger_operations(false, [], true);
-		});
-	}
-
-	preset_fields_for_template() {
-		var for_variant = this.dialog.get_value('create_variant');
-
-		// setup template field, seen and mandatory if variant
-		let template_field = this.dialog.get_field("item_template");
-		template_field.df.reqd = for_variant;
-		template_field.set_value('');
-		template_field.df.hidden = !for_variant;
-		template_field.refresh();
-
-		// hide properties for variant
-		['item_code', 'item_name', 'item_group', 'stock_uom'].forEach((d) => {
-			let f = this.dialog.get_field(d);
-			f.df.hidden = for_variant;
-			f.refresh();
-		});
-
-		this.dialog.get_field('attribute_html').toggle(false);
-
-		// non mandatory for variants
-		['item_code', 'stock_uom', 'item_group'].forEach((d) => {
-			let f = this.dialog.get_field(d);
-			f.df.reqd = !for_variant;
-			f.refresh();
-		});
-
-	}
-
-	init_for_item_template_trigger() {
-		var me = this;
-
-		me.dialog.fields_dict["item_template"].df.onchange = () => {
-			var template = me.dialog.fields_dict.item_template.input.value;
-			me.template_doc = null;
-			if (template) {
-				frappe.call({
-					method: "frappe.client.get",
-					args: {
-						doctype: "Item",
-						name: template
-					},
-					callback: function(r) {
-						me.template_doc = r.message;
-						me.is_manufacturer = false;
-
-						if (me.template_doc.variant_based_on === "Manufacturer") {
-							me.init_post_template_trigger_operations(true, [], true);
-						} else {
-
-							me.init_post_template_trigger_operations(false, me.template_doc.attributes, false);
-							me.render_attributes(me.template_doc.attributes);
-						}
-					}
-				});
-			} else {
-				me.dialog.get_field('attribute_html').toggle(false);
-				me.init_post_template_trigger_operations(false, [], true);
-			}
-		}
-	}
-
-	init_post_template_trigger_operations(is_manufacturer, attributes, attributes_flag) {
-		this.attributes = attributes;
-		this.attribute_values = {};
-		this.attributes_count = attributes.length;
-
-		this.dialog.fields_dict.attribute_html.$wrapper.find(".attributes").empty();
-		this.is_manufacturer = is_manufacturer;
-		this.toggle_manufacturer_fields();
-		this.dialog.fields_dict.attribute_html.$wrapper.find(".attributes").toggleClass("hide-control", attributes_flag);
-		this.dialog.fields_dict.attribute_html.$wrapper.find(".attributes-header").toggleClass("hide-control", attributes_flag);
-	}
-
-	toggle_manufacturer_fields() {
-		var me = this;
-		$.each(this.manufacturer_fields, function(i, dialog_field) {
-			me.dialog.get_field(dialog_field.fieldname).df.hidden = !me.is_manufacturer;
-			me.dialog.get_field(dialog_field.fieldname).df.reqd = dialog_field.fieldname == 'manufacturer' ? me.is_manufacturer : false;
-			me.dialog.get_field(dialog_field.fieldname).refresh();
-		});
-	}
-
-	initiate_render_attributes() {
-		this.dialog.fields_dict.attribute_html.$wrapper.find(".attributes").empty();
-		this.render_attributes(this.attributes);
-	}
-
-	render_attributes(attributes) {
-		var me = this;
-
-		this.dialog.get_field('attribute_html').toggle(true);
-
-		$.each(attributes, function(index, row) {
-			var desc = "";
-			var fieldtype = "Data";
-			if (row.numeric_values) {
-				fieldtype = "Float";
-				desc = "Min Value: " + row.from_range + " , Max Value: " + row.to_range + ", in Increments of: " + row.increment;
-			}
-
-			me.init_make_control(fieldtype, row);
-			me[row.attribute].set_value(me.attribute_values[row.attribute] || "");
-			me[row.attribute].$wrapper.toggleClass("has-error", me.attribute_values[row.attribute] ? false : true);
-
-			// Set Label explicitly as make_control is not displaying label
-			$(me[row.attribute].label_area).text(__(row.attribute));
-
-			if (desc) {
-				$(repl(`<p class="help-box small text-muted hidden-xs">%(desc)s</p>`, {
-					"desc": desc
-				})).insertAfter(me[row.attribute].input_area);
-			}
-
-			if (!row.numeric_values) {
-				me.init_awesomplete_for_attribute(row);
-			} else {
-				me[row.attribute].$input.on("change", function() {
-					me.attribute_values[row.attribute] = $(this).val();
-					$(this).closest(".frappe-control").toggleClass("has-error", $(this).val() ? false : true);
-				});
-			}
-		});
-	}
-
-	init_make_control(fieldtype, row) {
-		this[row.attribute] = frappe.ui.form.make_control({
-			df: {
-				"fieldtype": fieldtype,
-				"label": row.attribute,
-				"fieldname": row.attribute,
-				"options": row.options || ""
-			},
-			parent: $(this.dialog.fields_dict.attribute_html.wrapper).find(".attributes"),
-			only_input: false
-		});
-		this[row.attribute].make_input();
-	}
-
-	init_awesomplete_for_attribute(row) {
-		var me = this;
-
-		this[row.attribute].input.awesomplete = new Awesomplete(this[row.attribute].input, {
-			minChars: 0,
-			maxItems: 99,
-			autoFirst: true,
-			list: [],
-		});
-
-		this[row.attribute].$input.on('input', function(e) {
-			frappe.call({
-				method: "frappe.client.get_list",
-				args: {
-					doctype: "Item Attribute Value",
-					filters: [
-						["parent", "=", $(e.target).attr("data-fieldname")],
-						["attribute_value", "like", e.target.value + "%"]
-					],
-					fields: ["attribute_value"],
-					parent: "Item Attribute"
-				},
-				callback: function(r) {
-					if (r.message) {
-						e.target.awesomplete.list = r.message.map(function(d) {
-							return d.attribute_value;
-						});
-					}
-				}
-			});
-		}).on('focus', function(e) {
-			$(e.target).val('').trigger('input');
-		}).on("awesomplete-close", function (e) {
-			me.attribute_values[$(e.target).attr("data-fieldname")] = e.target.value;
-			$(e.target).closest(".frappe-control").toggleClass("has-error", e.target.value ? false : true);
-		});
-	}
-
-	get_variant_doc() {
-		var me = this;
-		var variant_doc = {};
-		var attribute = this.validate_mandatory_attributes();
-
-		if (Object.keys(attribute).length) {
-			frappe.call({
-				method: "erpnext.controllers.item_variant.create_variant_doc_for_quick_entry",
-				args: {
-					"template": me.dialog.fields_dict.item_template.$input.val(),
-					args: attribute
-				},
-				async: false,
-				callback: function(r) {
-					if (Object.prototype.toString.call(r.message) == "[object Object]") {
-						variant_doc = r.message;
-					} else {
-						var msgprint_dialog = frappe.msgprint(__("Item Variant {0} already exists with same attributes", [repl('<a class="strong variant-click" data-item-code="%(item)s" \
-								>%(item)s</a>', {
-								item: r.message
-							})]));
-
-						msgprint_dialog.$wrapper.find(".variant-click").on("click", function() {
-							msgprint_dialog.hide();
-							me.dialog.hide();
-							if (frappe._from_link) {
-								frappe._from_link.set_value($(this).attr("data-item-code"));
-							} else {
-								frappe.set_route('Form', "Item", $(this).attr("data-item-code"));
-							}
-						});
-					}
-				}
-			})
-		}
-		return variant_doc;
-	}
-
-	validate_mandatory_attributes() {
-		var me = this;
-		var attribute = {};
-		var mandatory = [];
-
-		$.each(this.attributes, function(index, attr) {
-			var value = me.attribute_values[attr.attribute] || "";
-			if (value) {
-				attribute[attr.attribute] = attr.numeric_values ? flt(value) : value;
-			} else {
-				mandatory.push(attr.attribute);
-			}
-		})
-
-		if (this.is_manufacturer) {
-			$.each(this.manufacturer_fields, function(index, field) {
-				attribute[field.fieldname] = me.dialog.fields_dict[field.fieldname].input.value;
-			});
-		}
-		return attribute;
-	}
-};
