[feature] ability to have variants based on manufacturer
diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py
index f8c9c0a..53421b7 100644
--- a/erpnext/controllers/item_variant.py
+++ b/erpnext/controllers/item_variant.py
@@ -12,19 +12,42 @@
 class ItemTemplateCannotHaveStock(frappe.ValidationError): pass
 
 @frappe.whitelist()
-def get_variant(template, args, variant=None):
-	"""Validates Attributes and their Values, then looks for an exactly matching Item Variant
+def get_variant(template, args=None, variant=None, manufacturer=None,
+	manufacturer_part_no=None):
+	"""Validates Attributes and their Values, then looks for an exactly
+		matching Item Variant
 
 		:param item: Template Item
 		:param args: A dictionary with "Attribute" as key and "Attribute Value" as value
 	"""
-	if isinstance(args, basestring):
-		args = json.loads(args)
+	item_template = frappe.get_doc('Item', template)
 
-	if not args:
-		frappe.throw(_("Please specify at least one attribute in the Attributes table"))
+	if item_template.variant_based_on=='Manufacturer' and manufacturer:
+		return make_variant_based_on_manufacturer(item_template, manufacturer,
+			manufacturer_part_no)
+	else:
+		if isinstance(args, basestring):
+			args = json.loads(args)
 
-	return find_variant(template, args, variant)
+		if not args:
+			frappe.throw(_("Please specify at least one attribute in the Attributes table"))
+		return find_variant(template, args, variant)
+
+def make_variant_based_on_manufacturer(template, manufacturer, manufacturer_part_no):
+	'''Make and return a new variant based on manufacturer and
+		manufacturer part no'''
+	from frappe.model.naming import append_number_if_name_exists
+
+	variant = frappe.new_doc('Item')
+
+	copy_attributes_to_variant(template, variant)
+
+	variant.manufacturer = manufacturer
+	variant.manufacturer_part_no = manufacturer_part_no
+
+	variant.item_code = append_number_if_name_exists('Item', template.name)
+
+	return variant
 
 def validate_item_variant_attributes(item, args=None):
 	if isinstance(item, basestring):
@@ -131,6 +154,7 @@
 
 	template = frappe.get_doc("Item", item)
 	variant = frappe.new_doc("Item")
+	variant.variant_based_on = 'Item Attribute'
 	variant_attributes = []
 
 	for d in template.attributes:
@@ -147,17 +171,28 @@
 
 def copy_attributes_to_variant(item, variant):
 	from frappe.model import no_value_fields
+
+	# copy non no-copy fields
+
+	exclude_fields = ["item_code", "item_name", "show_in_website"]
+
+	if item.variant_based_on=='Manufacturer':
+		# don't copy manufacturer values if based on part no
+		exclude_fields += ['manufacturer', 'manufacturer_part_no']
+
 	for field in item.meta.fields:
 		if field.fieldtype not in no_value_fields and (not field.no_copy)\
-			and field.fieldname not in ("item_code", "item_name", "show_in_website"):
+			and field.fieldname not in exclude_fields:
 			if variant.get(field.fieldname) != item.get(field.fieldname):
 				variant.set(field.fieldname, item.get(field.fieldname))
 	variant.variant_of = item.name
 	variant.has_variants = 0
-	if variant.attributes:
-		variant.description += "\n"
-		for d in variant.attributes:
-			variant.description += "<p>" + d.attribute + ": " + cstr(d.attribute_value) + "</p>"
+
+	if item.variant_based_on=='Item Attribute':
+		if variant.attributes:
+			variant.description += "\n"
+			for d in variant.attributes:
+				variant.description += "<p>" + d.attribute + ": " + cstr(d.attribute_value) + "</p>"
 
 def make_variant_item_code(template_item_code, variant):
 	"""Uses template's item code and abbreviations to make variant's item code"""