Add option to clean description html in item description. (#11565)

* [fix] add item settings

* [docs] Item Settings

* [fix] enqueue in item_settings.py

* [refactor] move to stock settings

* [refactor] move to stock settings
diff --git a/erpnext/config/stock.py b/erpnext/config/stock.py
index d6b18fd..cb17deb 100644
--- a/erpnext/config/stock.py
+++ b/erpnext/config/stock.py
@@ -9,22 +9,18 @@
 				{
 					"type": "doctype",
 					"name": "Stock Entry",
-					"description": _("Record item movement."),
 				},
 				{
 					"type": "doctype",
 					"name": "Delivery Note",
-					"description": _("Shipments to customers."),
 				},
 				{
 					"type": "doctype",
 					"name": "Purchase Receipt",
-					"description": _("Goods received from Suppliers."),
 				},
 				{
 					"type": "doctype",
 					"name": "Material Request",
-					"description": _("Requests for items."),
 				},
 			]
 		},
@@ -69,17 +65,14 @@
 				{
 					"type": "doctype",
 					"name": "Item",
-					"description": _("All Products or Services."),
 				},
 				{
 					"type": "doctype",
 					"name": "Product Bundle",
-					"description": _("Bundle items at time of sale."),
 				},
 				{
 					"type": "doctype",
 					"name": "Price List",
-					"description": _("Price List master.")
 				},
 				{
 					"type": "doctype",
@@ -87,30 +80,24 @@
 					"icon": "fa fa-sitemap",
 					"label": _("Item Group"),
 					"link": "Tree/Item Group",
-					"description": _("Tree of Item Groups."),
 				},
 				{
 					"type": "doctype",
 					"name": "Item Price",
-					"description": _("Multiple Item prices."),
 					"route": "Report/Item Price"
 				},
 				{
 					"type": "doctype",
 					"name": "Shipping Rule",
-					"description": _("Rules for adding shipping costs.")
 				},
 				{
 					"type": "doctype",
 					"name": "Pricing Rule",
-					"description": _("Rules for applying pricing and discount.")
 				},
 				{
 					"type": "doctype",
 					"name": "Item Variant Settings",
-					"description": _("Item Variant Settings."),
 				},
-
 			]
 		},
 		{
@@ -119,17 +106,14 @@
 				{
 					"type": "doctype",
 					"name": "Serial No",
-					"description": _("Single unit of an Item."),
 				},
 				{
 					"type": "doctype",
 					"name": "Batch",
-					"description": _("Batch (lot) of an Item."),
 				},
 				{
 					"type": "doctype",
 					"name": "Installation Note",
-					"description": _("Installation record for a Serial No.")
 				},
 				{
 					"type": "report",
@@ -155,22 +139,18 @@
 				{
 					"type": "doctype",
 					"name": "Stock Reconciliation",
-					"description": _("Upload stock balance via csv.")
 				},
 				{
 					"type": "doctype",
 					"name": "Packing Slip",
-					"description": _("Split Delivery Note into packages.")
 				},
 				{
 					"type": "doctype",
 					"name": "Quality Inspection",
-					"description": _("Incoming quality inspection.")
 				},
 				{
 					"type": "doctype",
 					"name": "Landed Cost Voucher",
-					"description": _("Update additional costs to calculate landed cost of items"),
 				}
 			]
 		},
@@ -181,28 +161,27 @@
 				{
 					"type": "doctype",
 					"name": "Stock Settings",
-					"description": _("Default settings for stock transactions.")
 				},
 				{
 					"type": "doctype",
 					"name": "Warehouse",
-					"description": _("Where items are stored."),
 				},
 				{
 					"type": "doctype",
 					"name": "UOM",
 					"label": _("Unit of Measure") + " (UOM)",
-					"description": _("e.g. Kg, Unit, Nos, m")
 				},
 				{
 					"type": "doctype",
 					"name": "Item Attribute",
-					"description": _("Attributes for Item Variants. e.g Size, Color etc."),
 				},
 				{
 					"type": "doctype",
 					"name": "Brand",
-					"description": _("Brand master.")
+				},
+				{
+					"type": "doctype",
+					"name": "Item Variant Settings",
 				},
 			]
 		},
diff --git a/erpnext/docs/user/manual/en/stock/item/index.txt b/erpnext/docs/user/manual/en/stock/item/index.txt
index 4e66875..db5fa0a 100644
--- a/erpnext/docs/user/manual/en/stock/item/index.txt
+++ b/erpnext/docs/user/manual/en/stock/item/index.txt
@@ -4,3 +4,4 @@
 purchase-details
 reorder
 item-valuation-fifo-and-moving-average
+item-settings
diff --git a/erpnext/docs/user/manual/en/stock/setup/stock-settings.md b/erpnext/docs/user/manual/en/stock/setup/stock-settings.md
index 32562c6..96d1627 100644
--- a/erpnext/docs/user/manual/en/stock/setup/stock-settings.md
+++ b/erpnext/docs/user/manual/en/stock/setup/stock-settings.md
@@ -4,4 +4,12 @@
 
 <img class="screenshot" alt="Stock Settings" src="/docs/assets/img/stock/stock-settings.png">
 
+### Clean HTML Description
+
+Usually descriptions are copy-pasted from a website or Word / PDF file and they contain a lot of embedded style. This messes up the Print view of your invoices or quotes.
+
+To fix this, you can check "Convert Item Description to Clean HTML" in Stock Settings. This will ensure that when you save your Items, their descriptions will be cleaned up.
+
+If you want control your description views and llow any HTML to be embedded, you can uncheck this property.
+
 {next}
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index fb4e0ba..1b86bb1 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -23,6 +23,7 @@
 execute:frappe.reload_doc('buying', 'doctype', 'supplier') # 2014-01-29
 execute:frappe.reload_doc('accounts', 'doctype', 'asset_category')
 execute:frappe.reload_doc('accounts', 'doctype', 'pricing_rule')
+execute:frappe.reload_doc('stock', 'doctype', 'item_settings')
 erpnext.patches.v4_0.map_charge_to_taxes_and_charges
 execute:frappe.reload_doc('support', 'doctype', 'newsletter') # 2014-01-31
 execute:frappe.reload_doc('hr', 'doctype', 'employee') # 2014-02-03
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index d6c4b7d..13c0027 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -9,6 +9,7 @@
 from frappe import msgprint, _
 from frappe.utils import (cstr, flt, cint, getdate, now_datetime, formatdate,
 	strip, get_timestamp, random_string)
+from frappe.utils.html_utils import clean_html
 from frappe.website.website_generator import WebsiteGenerator
 from erpnext.setup.doctype.item_group.item_group import invalidate_cache_for, get_parent_item_groups
 from frappe.website.render import clear_cache
@@ -82,6 +83,7 @@
 			self.description = self.item_name
 
 		self.validate_uom()
+		self.validate_description()
 		self.add_default_uom_in_conversion_factor_table()
 		self.validate_conversion_factor()
 		self.validate_item_type()
@@ -114,6 +116,11 @@
 		self.update_item_price()
 		self.update_template_item()
 
+	def validate_description(self):
+		'''Clean HTML description if set'''
+		if cint(frappe.db.get_single_value('Stock Settings', 'clean_description_html')):
+			self.description = clean_html(self.description)
+
 	def add_price(self, price_list=None):
 		'''Add a new price'''
 		if not price_list:
diff --git a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.json b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.json
index 8bdd46c..8ad73d1 100644
--- a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.json
+++ b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.json
@@ -47,7 +47,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "description": "If enabled then system will not update the fields of variants from the template but will copy the data of below mentioned fields while making new variant", 
+   "description": "Fields will be copied over only at time of creation.", 
    "fieldname": "do_not_update_variants", 
    "fieldtype": "Check", 
    "hidden": 0, 
@@ -57,7 +57,7 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Do not Update Variants", 
+   "label": "Do not update variants on save", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -144,7 +144,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-11-08 11:38:12.821404", 
+ "modified": "2017-11-14 15:54:12.190518", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Item Variant Settings", 
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json
index 4801d40..16726be 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.json
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
  "beta": 0, 
@@ -11,6 +12,7 @@
  "editable_grid": 0, 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -22,6 +24,7 @@
    "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 Naming By", 
@@ -40,6 +43,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -51,6 +55,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 1, 
    "in_standard_filter": 0, 
    "label": "Default Item Group", 
@@ -69,6 +74,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -79,6 +85,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 1, 
    "in_standard_filter": 0, 
    "label": "Default Stock UOM", 
@@ -97,6 +104,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -107,6 +115,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Default Warehouse", 
@@ -126,6 +135,38 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "1", 
+   "fieldname": "clean_description_html", 
+   "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": "Convert Item Description to Clean HTML", 
+   "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, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -136,6 +177,7 @@
    "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, 
@@ -152,6 +194,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -162,6 +205,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Default Valuation Method", 
@@ -180,6 +224,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -191,6 +236,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Limit Percent", 
@@ -208,6 +254,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -219,6 +266,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Show Barcode Field", 
@@ -237,6 +285,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -247,6 +296,7 @@
    "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, 
@@ -264,6 +314,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -274,6 +325,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Auto insert Price List rate if missing", 
@@ -292,6 +344,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -302,6 +355,7 @@
    "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 Negative Stock", 
@@ -319,6 +373,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -329,6 +384,7 @@
    "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, 
@@ -346,6 +402,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -357,6 +414,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Automatically Set Serial Nos based on FIFO", 
@@ -375,6 +433,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -385,6 +444,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Auto Material Request", 
@@ -402,6 +462,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -412,6 +473,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Raise Material Request when stock reaches re-order level", 
@@ -429,6 +491,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -439,6 +502,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Notify by Email on creation of automatic Material Request", 
@@ -456,6 +520,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -466,6 +531,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Freeze Stock Entries", 
@@ -483,6 +549,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -493,6 +560,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Stock Frozen Upto", 
@@ -510,6 +578,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -520,6 +589,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Freeze Stocks Older Than [Days]", 
@@ -537,6 +607,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -547,6 +618,7 @@
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Role Allowed to edit frozen stock", 
@@ -565,18 +637,18 @@
    "unique": 0
   }
  ], 
+ "has_web_view": 0, 
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "icon": "icon-cog", 
  "idx": 1, 
  "image_view": 0, 
  "in_create": 0, 
- "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-12-16 02:18:58.187847", 
+ "modified": "2017-11-14 16:19:50.274518", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Stock Settings", 
@@ -592,7 +664,6 @@
    "export": 0, 
    "if_owner": 0, 
    "import": 0, 
-   "is_custom": 0, 
    "permlevel": 0, 
    "print": 1, 
    "read": 1, 
@@ -607,6 +678,8 @@
  "quick_entry": 1, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
  "sort_order": "ASC", 
+ "track_changes": 0, 
  "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.py b/erpnext/stock/doctype/stock_settings/stock_settings.py
index 186eaee..89ece33 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.py
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.py
@@ -7,6 +7,7 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
+from frappe.utils.html_utils import clean_html
 
 class StockSettings(Document):
 	def validate(self):
@@ -26,19 +27,34 @@
 		# show/hide barcode field
 		frappe.make_property_setter({'fieldname': 'barcode', 'property': 'hidden',
 			'value': 0 if self.show_barcode_field else 1})
-			
+
 		self.cant_change_valuation_method()
-		
+		self.validate_clean_description_html()
+
 	def cant_change_valuation_method(self):
 		db_valuation_method = frappe.db.get_single_value("Stock Settings", "valuation_method")
-		
+
 		if db_valuation_method and db_valuation_method != self.valuation_method:
-			# check if there are any stock ledger entries against items 
+			# check if there are any stock ledger entries against items
 			# which does not have it's own valuation method
 			sle = frappe.db.sql("""select name from `tabStock Ledger Entry` sle
-				where exists(select name from tabItem 
-					where name=sle.item_code and (valuation_method is null or valuation_method=''))
+				where exists(select name from tabItem
+					where name=sle.item_code and (valuation_method is null or valuation_method='')) limit 1
 			""")
-			
+
 			if sle:
-				frappe.throw(_("Can't change valuation method, as there are transactions against some items which does not have it's own valuation method"))
\ No newline at end of file
+				frappe.throw(_("Can't change valuation method, as there are transactions against some items which does not have it's own valuation method"))
+
+	def validate_clean_description_html(self):
+		if int(self.clean_description_html or 0) \
+			and not int(self.db_get('clean_description_html') or 0):
+			# changed to text
+			frappe.enqueue('erpnext.stock.doctype.stock_settings.stock_settings.clean_all_descriptions', now=frappe.flags.in_test)
+
+
+def clean_all_descriptions():
+	for item in frappe.get_all('Item', ['name', 'description']):
+		if item.description:
+			clean_description = clean_html(item.description)
+		if item.description != clean_description:
+			frappe.db.set_value('Item', item.name, 'description', clean_description)
diff --git a/erpnext/stock/doctype/stock_settings/test_stock_settings.js b/erpnext/stock/doctype/stock_settings/test_stock_settings.js
new file mode 100644
index 0000000..57d9fc6
--- /dev/null
+++ b/erpnext/stock/doctype/stock_settings/test_stock_settings.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: Stock Settings", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Stock Settings
+		() => frappe.tests.make('Stock Settings', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/stock/doctype/stock_settings/test_stock_settings.py b/erpnext/stock/doctype/stock_settings/test_stock_settings.py
new file mode 100644
index 0000000..43c0c57
--- /dev/null
+++ b/erpnext/stock/doctype/stock_settings/test_stock_settings.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestStockSettings(unittest.TestCase):
+	def setUp(self):
+		settings = frappe.get_single('Stock Settings')
+		settings.clean_description_html = 0
+		settings.save()
+
+		frappe.delete_doc('Item', 'Item for description test')
+
+	def tearDown(self):
+		settings = frappe.get_single('Stock Settings')
+		settings.clean_description_html = 1
+		settings.save()
+
+	def test_settings(self):
+		item = frappe.get_doc(dict(
+			doctype = 'Item',
+			item_code = 'Item for description test',
+			item_group = 'Products',
+			description = '<p><span style="font-size: 12px;">Drawing No. 07-xxx-PO132<br></span><span style="font-size: 12px;">1800 x 1685 x 750<br></span><span style="font-size: 12px;">All parts made of Marine Ply<br></span><span style="font-size: 12px;">Top w/ Corian dd<br></span><span style="font-size: 12px;">CO, CS, VIP Day Cabin</span></p>'
+		)).insert()
+
+		settings = frappe.get_single('Stock Settings')
+		settings.clean_description_html = 1
+		settings.save()
+
+		item.reload()
+
+		self.assertEquals(item.description, '<p>Drawing No. 07-xxx-PO132<br>1800 x 1685 x 750<br>All parts made of Marine Ply<br>Top w/ Corian dd<br>CO, CS, VIP Day Cabin</p>')
+
+		item.delete()
+
+	def test_clean_html(self):
+		settings = frappe.get_single('Stock Settings')
+		settings.clean_description_html = 1
+		settings.save()
+
+		item = frappe.get_doc(dict(
+			doctype = 'Item',
+			item_code = 'Item for description test',
+			item_group = 'Products',
+			description = '<p><span style="font-size: 12px;">Drawing No. 07-xxx-PO132<br></span><span style="font-size: 12px;">1800 x 1685 x 750<br></span><span style="font-size: 12px;">All parts made of Marine Ply<br></span><span style="font-size: 12px;">Top w/ Corian dd<br></span><span style="font-size: 12px;">CO, CS, VIP Day Cabin</span></p>'
+		)).insert()
+
+		self.assertEquals(item.description, '<p>Drawing No. 07-xxx-PO132<br>1800 x 1685 x 750<br>All parts made of Marine Ply<br>Top w/ Corian dd<br>CO, CS, VIP Day Cabin</p>')
+
+		item.delete()