[feature] ability to have variants based on manufacturer
This commit is contained in:
		
							parent
							
								
									f340e19ea7
								
							
						
					
					
						commit
						a07c43fd68
					
				| @ -12,19 +12,42 @@ class InvalidItemAttributeValueError(frappe.ValidationError): pass | |||||||
| class ItemTemplateCannotHaveStock(frappe.ValidationError): pass | class ItemTemplateCannotHaveStock(frappe.ValidationError): pass | ||||||
| 
 | 
 | ||||||
| @frappe.whitelist() | @frappe.whitelist() | ||||||
| def get_variant(template, args, variant=None): | def get_variant(template, args=None, variant=None, manufacturer=None, | ||||||
| 	"""Validates Attributes and their Values, then looks for an exactly matching Item Variant | 	manufacturer_part_no=None): | ||||||
|  | 	"""Validates Attributes and their Values, then looks for an exactly | ||||||
|  | 		matching Item Variant | ||||||
| 
 | 
 | ||||||
| 		:param item: Template Item | 		:param item: Template Item | ||||||
| 		:param args: A dictionary with "Attribute" as key and "Attribute Value" as value | 		:param args: A dictionary with "Attribute" as key and "Attribute Value" as value | ||||||
| 	""" | 	""" | ||||||
| 	if isinstance(args, basestring): | 	item_template = frappe.get_doc('Item', template) | ||||||
| 		args = json.loads(args) |  | ||||||
| 
 | 
 | ||||||
| 	if not args: | 	if item_template.variant_based_on=='Manufacturer' and manufacturer: | ||||||
| 		frappe.throw(_("Please specify at least one attribute in the Attributes table")) | 		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): | def validate_item_variant_attributes(item, args=None): | ||||||
| 	if isinstance(item, basestring): | 	if isinstance(item, basestring): | ||||||
| @ -131,6 +154,7 @@ def create_variant(item, args): | |||||||
| 
 | 
 | ||||||
| 	template = frappe.get_doc("Item", item) | 	template = frappe.get_doc("Item", item) | ||||||
| 	variant = frappe.new_doc("Item") | 	variant = frappe.new_doc("Item") | ||||||
|  | 	variant.variant_based_on = 'Item Attribute' | ||||||
| 	variant_attributes = [] | 	variant_attributes = [] | ||||||
| 
 | 
 | ||||||
| 	for d in template.attributes: | 	for d in template.attributes: | ||||||
| @ -147,17 +171,28 @@ def create_variant(item, args): | |||||||
| 
 | 
 | ||||||
| def copy_attributes_to_variant(item, variant): | def copy_attributes_to_variant(item, variant): | ||||||
| 	from frappe.model import no_value_fields | 	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: | 	for field in item.meta.fields: | ||||||
| 		if field.fieldtype not in no_value_fields and (not field.no_copy)\ | 		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): | 			if variant.get(field.fieldname) != item.get(field.fieldname): | ||||||
| 				variant.set(field.fieldname, item.get(field.fieldname)) | 				variant.set(field.fieldname, item.get(field.fieldname)) | ||||||
| 	variant.variant_of = item.name | 	variant.variant_of = item.name | ||||||
| 	variant.has_variants = 0 | 	variant.has_variants = 0 | ||||||
| 	if variant.attributes: | 
 | ||||||
| 		variant.description += "\n" | 	if item.variant_based_on=='Item Attribute': | ||||||
| 		for d in variant.attributes: | 		if variant.attributes: | ||||||
| 			variant.description += "<p>" + d.attribute + ": " + cstr(d.attribute_value) + "</p>" | 			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): | def make_variant_item_code(template_item_code, variant): | ||||||
| 	"""Uses template's item code and abbreviations to make variant's item code""" | 	"""Uses template's item code and abbreviations to make variant's item code""" | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								erpnext/docs/assets/img/stock/select-mfg-for-variant.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								erpnext/docs/assets/img/stock/select-mfg-for-variant.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 55 KiB | 
							
								
								
									
										
											BIN
										
									
								
								erpnext/docs/assets/img/stock/set-variant-by-mfg.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								erpnext/docs/assets/img/stock/set-variant-by-mfg.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 19 KiB | 
| @ -1,7 +1,20 @@ | |||||||
|  | # Item Variants | ||||||
|  | 
 | ||||||
|  | ### What are Variants? | ||||||
|  | 
 | ||||||
| A Item Variant is a version of a Item, such as differing sizes or differing colours (like a _blue_ t-shirt in size _small_ rather then just a t-shirt). | A Item Variant is a version of a Item, such as differing sizes or differing colours (like a _blue_ t-shirt in size _small_ rather then just a t-shirt). | ||||||
| Without Item variants, you would have to treat the _small, medium_ and _large_ versions of a t-shirt as three separate Items; | Without Item variants, you would have to treat the _small, medium_ and _large_ versions of a t-shirt as three separate Items; | ||||||
| Item variants let you treat the _small, medium_ and _large_ versions of a t-shirt as variations of the one Item 't-shirt'. | Item variants let you treat the _small, medium_ and _large_ versions of a t-shirt as variations of the one Item 't-shirt'. | ||||||
| 
 | 
 | ||||||
|  | ### Using Variants | ||||||
|  | 
 | ||||||
|  | Variants can be based on two things | ||||||
|  | 
 | ||||||
|  | 1. Item Attributes | ||||||
|  | 1. Manufacturers | ||||||
|  | 
 | ||||||
|  | ### Variants Based on Item Attributes | ||||||
|  | 
 | ||||||
| To use Item Variants in ERPNext, create an Item and check 'Has Variants'. | To use Item Variants in ERPNext, create an Item and check 'Has Variants'. | ||||||
| 
 | 
 | ||||||
| * The Item shall then be referred to as a so called 'Template'. Such a Template is not identical to a regular 'Item' any longer. For example it (the Template) can not be used directly in any Transactions (Sales Order, Delivery Note, Purchase Invoice) itself. Only the Variants of an Item (_blue_ t-shirt in size _small)_ can be practically used in such. Therefore it would be ideal to decide whether an item 'Has Variants' or not directly when creating it. | * The Item shall then be referred to as a so called 'Template'. Such a Template is not identical to a regular 'Item' any longer. For example it (the Template) can not be used directly in any Transactions (Sales Order, Delivery Note, Purchase Invoice) itself. Only the Variants of an Item (_blue_ t-shirt in size _small)_ can be practically used in such. Therefore it would be ideal to decide whether an item 'Has Variants' or not directly when creating it. | ||||||
| @ -22,3 +35,17 @@ To create 'Item Variants' against a 'Template' select 'Make Variants' | |||||||
| <img class="screenshot" alt="Make Variants" src="{{docs_base_url}}/assets/img/stock/make-variant-1.png"> | <img class="screenshot" alt="Make Variants" src="{{docs_base_url}}/assets/img/stock/make-variant-1.png"> | ||||||
| 
 | 
 | ||||||
| To learn more about setting Attributes Master check [Item Attributes]({{docs_base_url}}/user/manual/en/stock/setup/item-attribute.html) | To learn more about setting Attributes Master check [Item Attributes]({{docs_base_url}}/user/manual/en/stock/setup/item-attribute.html) | ||||||
|  | 
 | ||||||
|  | ### Variants Based on Manufacturers | ||||||
|  | 
 | ||||||
|  | To setup variants based on Manufactueres, in your Item template, set "Variants Based On" as "Manufacturers" | ||||||
|  | 
 | ||||||
|  | <img class='screenshot' alt='Setup Item Variant by Manufacturer' | ||||||
|  | 	src='{{docs_base_url}}/assets/img/stock/select-mfg-for-variant.png'> | ||||||
|  | 
 | ||||||
|  | When you make a new Variant, the system will prompt you to select a Manufacturer. You can also optionally put in a Manufacturer Part Number | ||||||
|  | 
 | ||||||
|  | <img class='screenshot' alt='Setup Item Variant by Manufacturer' | ||||||
|  | 	src='{{docs_base_url}}/assets/img/stock/set-variant-by-mfg.png'> | ||||||
|  | 
 | ||||||
|  | The naming of the variant will be the name (ID) of the template Item with a number suffix. e.g. "ITEM000" will have variant "ITEM000-1" | ||||||
| @ -327,4 +327,3 @@ body[data-route="pos"] .btn-more { | |||||||
| body[data-route="pos"] .collapse-btn { | body[data-route="pos"] .collapse-btn { | ||||||
|   cursor: pointer; |   cursor: pointer; | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -177,11 +177,11 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( | |||||||
| 							fields: [ | 							fields: [ | ||||||
| 								{fieldtype:'Read Only', fieldname:'item_code', | 								{fieldtype:'Read Only', fieldname:'item_code', | ||||||
| 									label: __('Item Code'), in_list_view:1}, | 									label: __('Item Code'), in_list_view:1}, | ||||||
| 								{fieldtype:'Link', fieldname:'bom', options: 'BOM', | 								{fieldtype:'Link', fieldname:'bom', options: 'BOM', reqd: 1, | ||||||
| 									label: __('Select BOM'), in_list_view:1, get_query: function(doc) { | 									label: __('Select BOM'), in_list_view:1, get_query: function(doc) { | ||||||
| 										return {filters: {item: doc.item_code}}; | 										return {filters: {item: doc.item_code}}; | ||||||
| 									}}, | 									}}, | ||||||
| 								{fieldtype:'Float', fieldname:'pending_qty', | 								{fieldtype:'Float', fieldname:'pending_qty', reqd: 1, | ||||||
| 									label: __('Qty'), in_list_view:1}, | 									label: __('Qty'), in_list_view:1}, | ||||||
| 							], | 							], | ||||||
| 							get_data: function() { | 							get_data: function() { | ||||||
|  | |||||||
| @ -261,6 +261,45 @@ $.extend(erpnext.item, { | |||||||
| 	make_variant: function(frm) { | 	make_variant: function(frm) { | ||||||
| 		var fields = [] | 		var fields = [] | ||||||
| 
 | 
 | ||||||
|  | 		if(frm.doc.variant_based_on==="Item Attribute") { | ||||||
|  | 			erpnext.item.show_modal_for_item_attribute_selection(frm); | ||||||
|  | 		} else { | ||||||
|  | 			erpnext.item.show_modal_for_manufacturers(frm); | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	show_modal_for_manufacturers: function(frm) { | ||||||
|  | 		var dialog = new frappe.ui.Dialog({ | ||||||
|  | 			fields: [ | ||||||
|  | 				{fieldtype:'Link', options:'Manufacturer', | ||||||
|  | 					reqd:1, label:'Manufacturer'}, | ||||||
|  | 				{fieldtype:'Data', label:'Manufacturer Part Number', | ||||||
|  | 					fieldname: 'manufacturer_part_no'}, | ||||||
|  | 			] | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		dialog.set_primary_action(__('Make'), function() { | ||||||
|  | 			var data = dialog.get_values(); | ||||||
|  | 			if(!data) return; | ||||||
|  | 
 | ||||||
|  | 			// call the server to make the variant
 | ||||||
|  | 			data.template = frm.doc.name; | ||||||
|  | 			frappe.call({ | ||||||
|  | 				method:"erpnext.controllers.item_variant.get_variant", | ||||||
|  | 				args: data, | ||||||
|  | 				callback: function(r) { | ||||||
|  | 					var doclist = frappe.model.sync(r.message); | ||||||
|  | 					console.log(doclist); | ||||||
|  | 					dialog.hide(); | ||||||
|  | 					frappe.set_route("Form", doclist[0].doctype, doclist[0].name); | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		dialog.show(); | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	show_modal_for_item_attribute_selection: function(frm) { | ||||||
| 		for(var i=0;i< frm.doc.attributes.length;i++){ | 		for(var i=0;i< frm.doc.attributes.length;i++){ | ||||||
| 			var fieldtype, desc; | 			var fieldtype, desc; | ||||||
| 			var row = frm.doc.attributes[i]; | 			var row = frm.doc.attributes[i]; | ||||||
| @ -371,13 +410,42 @@ $.extend(erpnext.item, { | |||||||
| 				}) | 				}) | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
| 	toggle_attributes: function(frm) { |  | ||||||
| 		frm.toggle_display("attributes", frm.doc.has_variants || frm.doc.variant_of); |  | ||||||
| 		frm.fields_dict.attributes.grid.toggle_reqd("attribute_value", frm.doc.variant_of ? 1 : 0); |  | ||||||
| 		frm.fields_dict.attributes.grid.set_column_disp("attribute_value", frm.doc.variant_of ? 1 : 0); |  | ||||||
| 
 | 
 | ||||||
| 		frm.toggle_enable("attributes", !frm.doc.variant_of); | 	toggle_attributes: function(frm) { | ||||||
| 		frm.fields_dict.attributes.grid.toggle_enable("attribute", !frm.doc.variant_of); | 		if((frm.doc.has_variants || frm.doc.variant_of) | ||||||
| 		frm.fields_dict.attributes.grid.toggle_enable("attribute_value", !frm.doc.variant_of); | 			&& frm.doc.variant_based_on==='Item Attribute') { | ||||||
|  | 			frm.toggle_display("attributes", true); | ||||||
|  | 
 | ||||||
|  | 			var grid = frm.fields_dict.attributes.grid; | ||||||
|  | 
 | ||||||
|  | 			if(frm.doc.variant_of) { | ||||||
|  | 				// variant
 | ||||||
|  | 
 | ||||||
|  | 				// value column is displayed but not editable
 | ||||||
|  | 				grid.set_column_disp("attribute_value", true); | ||||||
|  | 				grid.toggle_enable("attribute_value", false); | ||||||
|  | 
 | ||||||
|  | 				grid.toggle_enable("attribute", false); | ||||||
|  | 
 | ||||||
|  | 				// can't change attributes since they are
 | ||||||
|  | 				// saved when the variant was created
 | ||||||
|  | 				frm.toggle_enable("attributes", false); | ||||||
|  | 			} else { | ||||||
|  | 				// template - values not required!
 | ||||||
|  | 
 | ||||||
|  | 				// make the grid editable
 | ||||||
|  | 				frm.toggle_enable("attributes", true); | ||||||
|  | 
 | ||||||
|  | 				// value column is hidden
 | ||||||
|  | 				grid.set_column_disp("attribute_value", false); | ||||||
|  | 
 | ||||||
|  | 				// enable the grid so you can add more attributes
 | ||||||
|  | 				grid.toggle_enable("attribute", true); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 		} else { | ||||||
|  | 			// nothing to do with attributes, hide it
 | ||||||
|  | 			frm.toggle_display("attributes", false); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| { | { | ||||||
|  "allow_copy": 0,  |  "allow_copy": 0,  | ||||||
|  |  "allow_guest_to_view": 0,  | ||||||
|  "allow_import": 1,  |  "allow_import": 1,  | ||||||
|  "allow_rename": 1,  |  "allow_rename": 1,  | ||||||
|  "autoname": "field:item_code",  |  "autoname": "field:item_code",  | ||||||
| @ -1218,7 +1219,39 @@ | |||||||
|    "bold": 0,  |    "bold": 0,  | ||||||
|    "collapsible": 0,  |    "collapsible": 0,  | ||||||
|    "columns": 0,  |    "columns": 0,  | ||||||
|    "depends_on": "",  |    "default": "Item Attribute",  | ||||||
|  |    "depends_on": "has_variants",  | ||||||
|  |    "fieldname": "variant_based_on",  | ||||||
|  |    "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": "Variant Based On",  | ||||||
|  |    "length": 0,  | ||||||
|  |    "no_copy": 0,  | ||||||
|  |    "options": "Item Attribute\nManufacturer",  | ||||||
|  |    "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,  | ||||||
|  |    "unique": 0 | ||||||
|  |   },  | ||||||
|  |   { | ||||||
|  |    "allow_on_submit": 0,  | ||||||
|  |    "bold": 0,  | ||||||
|  |    "collapsible": 0,  | ||||||
|  |    "columns": 0,  | ||||||
|  |    "depends_on": "eval:doc.has_variants && doc.variant_based_on==='Item Attribute'",  | ||||||
|    "fieldname": "attributes",  |    "fieldname": "attributes",  | ||||||
|    "fieldtype": "Table",  |    "fieldtype": "Table",  | ||||||
|    "hidden": 1,  |    "hidden": 1,  | ||||||
| @ -2792,6 +2825,7 @@ | |||||||
|    "unique": 0 |    "unique": 0 | ||||||
|   } |   } | ||||||
|  ],  |  ],  | ||||||
|  |  "has_web_view": 0,  | ||||||
|  "hide_heading": 0,  |  "hide_heading": 0,  | ||||||
|  "hide_toolbar": 0,  |  "hide_toolbar": 0,  | ||||||
|  "icon": "fa fa-tag",  |  "icon": "fa fa-tag",  | ||||||
| @ -2799,12 +2833,11 @@ | |||||||
|  "image_field": "image",  |  "image_field": "image",  | ||||||
|  "image_view": 0,  |  "image_view": 0,  | ||||||
|  "in_create": 0,  |  "in_create": 0,  | ||||||
|  "in_dialog": 0,  |  | ||||||
|  "is_submittable": 0,  |  "is_submittable": 0,  | ||||||
|  "issingle": 0,  |  "issingle": 0,  | ||||||
|  "istable": 0,  |  "istable": 0,  | ||||||
|  "max_attachments": 1,  |  "max_attachments": 1,  | ||||||
|  "modified": "2017-02-20 13:26:45.446617",  |  "modified": "2017-03-21 21:03:10.715674",  | ||||||
|  "modified_by": "Administrator",  |  "modified_by": "Administrator",  | ||||||
|  "module": "Stock",  |  "module": "Stock",  | ||||||
|  "name": "Item",  |  "name": "Item",  | ||||||
|  | |||||||
| @ -643,7 +643,7 @@ class Item(WebsiteGenerator): | |||||||
| 					.format(self.stock_uom, template_uom)) | 					.format(self.stock_uom, template_uom)) | ||||||
| 
 | 
 | ||||||
| 	def validate_attributes(self): | 	def validate_attributes(self): | ||||||
| 		if self.has_variants or self.variant_of: | 		if (self.has_variants or self.variant_of) and self.variant_based_on=='Item Attribute': | ||||||
| 			attributes = [] | 			attributes = [] | ||||||
| 			if not self.attributes: | 			if not self.attributes: | ||||||
| 				frappe.throw(_("Attribute table is mandatory")) | 				frappe.throw(_("Attribute table is mandatory")) | ||||||
| @ -654,7 +654,7 @@ class Item(WebsiteGenerator): | |||||||
| 					attributes.append(d.attribute) | 					attributes.append(d.attribute) | ||||||
| 
 | 
 | ||||||
| 	def validate_variant_attributes(self): | 	def validate_variant_attributes(self): | ||||||
| 		if self.variant_of: | 		if self.variant_of and self.variant_based_on=='Item Attribute': | ||||||
| 			args = {} | 			args = {} | ||||||
| 			for d in self.attributes: | 			for d in self.attributes: | ||||||
| 				if not d.attribute_value: | 				if not d.attribute_value: | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ import frappe | |||||||
| 
 | 
 | ||||||
| from frappe.test_runner import make_test_records | from frappe.test_runner import make_test_records | ||||||
| from erpnext.controllers.item_variant import (create_variant, ItemVariantExistsError, | from erpnext.controllers.item_variant import (create_variant, ItemVariantExistsError, | ||||||
| 	InvalidItemAttributeValueError) | 	InvalidItemAttributeValueError, get_variant) | ||||||
| 
 | 
 | ||||||
| from frappe.model.rename_doc import rename_doc | from frappe.model.rename_doc import rename_doc | ||||||
| from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry | from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry | ||||||
| @ -193,6 +193,41 @@ class TestItem(unittest.TestCase): | |||||||
| 		self.assertTrue(frappe.db.get_value("Bin", | 		self.assertTrue(frappe.db.get_value("Bin", | ||||||
| 			{"item_code": "Test Item for Merging 2", "warehouse": "_Test Warehouse 1 - _TC"})) | 			{"item_code": "Test Item for Merging 2", "warehouse": "_Test Warehouse 1 - _TC"})) | ||||||
| 
 | 
 | ||||||
|  | 	def test_item_variant_by_manufacturer(self): | ||||||
|  | 		if frappe.db.exists('Item', '_Test Variant Mfg'): | ||||||
|  | 			frappe.delete_doc('Item', '_Test Variant Mfg') | ||||||
|  | 		if frappe.db.exists('Item', '_Test Variant Mfg-1'): | ||||||
|  | 			frappe.delete_doc('Item', '_Test Variant Mfg-1') | ||||||
|  | 		if frappe.db.exists('Manufacturer', 'MSG1'): | ||||||
|  | 			frappe.delete_doc('Manufacturer', 'MSG1') | ||||||
|  | 
 | ||||||
|  | 		template = frappe.get_doc(dict( | ||||||
|  | 			doctype='Item', | ||||||
|  | 			item_code='_Test Variant Mfg', | ||||||
|  | 			has_variant=1, | ||||||
|  | 			item_group='Products', | ||||||
|  | 			variant_based_on='Manufacturer' | ||||||
|  | 		)).insert() | ||||||
|  | 
 | ||||||
|  | 		manufacturer = frappe.get_doc(dict( | ||||||
|  | 			doctype='Manufacturer', | ||||||
|  | 			short_name='MSG1' | ||||||
|  | 		)).insert() | ||||||
|  | 
 | ||||||
|  | 		variant = get_variant(template.name, manufacturer=manufacturer.name) | ||||||
|  | 		self.assertEquals(variant.item_code, '_Test Variant Mfg-1') | ||||||
|  | 		self.assertEquals(variant.description, '_Test Variant Mfg') | ||||||
|  | 		self.assertEquals(variant.manufacturer, 'MSG1') | ||||||
|  | 		variant.insert() | ||||||
|  | 
 | ||||||
|  | 		variant = get_variant(template.name, manufacturer=manufacturer.name, | ||||||
|  | 			manufacturer_part_no='007') | ||||||
|  | 		self.assertEquals(variant.item_code, '_Test Variant Mfg-2') | ||||||
|  | 		self.assertEquals(variant.description, '_Test Variant Mfg') | ||||||
|  | 		self.assertEquals(variant.manufacturer, 'MSG1') | ||||||
|  | 		self.assertEquals(variant.manufacturer_part_no, '007') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def make_item_variant(): | def make_item_variant(): | ||||||
| 	if not frappe.db.exists("Item", "_Test Variant Item-S"): | 	if not frappe.db.exists("Item", "_Test Variant Item-S"): | ||||||
| 		variant = create_variant("_Test Variant Item", """{"Test Size": "Small"}""") | 		variant = create_variant("_Test Variant Item", """{"Test Size": "Small"}""") | ||||||
| @ -217,4 +252,3 @@ def create_item(item_code, is_stock_item=None): | |||||||
| 		item.item_group = "All Item Groups" | 		item.item_group = "All Item Groups" | ||||||
| 		item.is_stock_item = is_stock_item or 1 | 		item.is_stock_item = is_stock_item or 1 | ||||||
| 		item.save() | 		item.save() | ||||||
| 		 |  | ||||||
| @ -63,7 +63,7 @@ def get_list_context(context=None): | |||||||
| 		'no_breadcrumbs': True | 		'no_breadcrumbs': True | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20): | def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20, order_by=None): | ||||||
| 	from frappe.www.list import get_list | 	from frappe.www.list import get_list | ||||||
| 	user = frappe.session.user | 	user = frappe.session.user | ||||||
| 	ignore_permissions = False | 	ignore_permissions = False | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user