[fixes] test case and code rewrite
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 121fc93..cd42901 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -151,7 +151,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "eval:doc.is_drop_ship==1", 
+   "depends_on": "eval:doc.delivered_by_supplier==1", 
    "fieldname": "customer", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -164,7 +164,7 @@
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -175,7 +175,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "eval:doc.is_drop_ship==1", 
+   "depends_on": "eval:doc.delivered_by_supplier==1", 
    "fieldname": "customer_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -476,7 +476,7 @@
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 1, 
-   "read_only": 0, 
+   "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -1561,30 +1561,6 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "depends_on": "eval:doc.is_drop_ship==1", 
-   "fieldname": "customer_address", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Customer Address", 
-   "no_copy": 0, 
-   "options": "Address", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
    "fieldname": "cb_contact", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -1626,30 +1602,6 @@
   {
    "allow_on_submit": 0, 
    "bold": 0, 
-   "collapsible": 0, 
-   "depends_on": "eval:doc.is_drop_ship==1", 
-   "fieldname": "customer_contact_person", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Customer Contact Person", 
-   "no_copy": 0, 
-   "options": "Contact", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 1, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
    "collapsible": 1, 
    "fieldname": "more_info", 
    "fieldtype": "Section Break", 
@@ -2238,8 +2190,8 @@
  "is_submittable": 1, 
  "issingle": 0, 
  "istable": 0, 
- "modified": "2015-10-27 16:58:53.362949", 
- "modified_by": "saurabh@erpnext.com", 
+ "modified": "2015-10-29 16:41:30.749753", 
+ "modified_by": "Administrator", 
  "module": "Buying", 
  "name": "Purchase Order", 
  "owner": "Administrator", 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 26837f1..4f373e0 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -353,25 +353,13 @@
 	
 def update_delivered_qty(purchase_order):
 	sales_order_list = []
+	so_name = ''
 	for item in purchase_order.items:
 		if item.prevdoc_doctype == "Sales Order":
-			frappe.db.sql(""" update `tabSales Order Item` 
-				set delivered_qty = (ifnull(delivered_qty, 0) + %(qty)s)
-				where item_code='%(item_code)s' and parent = '%(name)s' 
-			"""%{"qty": item.qty, "item_code": item.item_code, "name": item.prevdoc_docname})
-		
-			sales_order_list.append(item.prevdoc_docname)
+			so_name = item.prevdoc_docname
 			
-	update_per_delivery(sales_order_list)
-		
-def update_per_delivery(sales_order_list):
-	for so in sales_order_list:
-		frappe.db.sql("""update `tabSales Order`
-			set per_delivered = (select 
-				sum(if(qty > ifnull(delivered_qty, 0), delivered_qty, qty))/ sum(qty)*100 
-				from `tabSales Order Item` where parent="%(name)s") where name = "%(name)s" """%{"name":so})
-	
-		so = frappe.get_doc("Sales Order", so)
-		so.set_status(update=True)
-		so.notify_update()
+	so = frappe.get_doc("Sales Order", so_name)
+	so.update_delivery_status(purchase_order.name)
+	so.set_status(update=True)
+	so.notify_update()
 	
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index 0c8fba6..1988a6d 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -71,19 +71,19 @@
 		po = create_purchase_order(qty=3.4, do_not_save=True)
 		self.assertRaises(UOMMustBeIntegerError, po.insert)
 	
-	def test_ordered_qty_for_closing_po(self):
-		from erpnext.stock.doctype.item.test_item import make_item
+	def test_ordered_qty_for_closing_po(self):			
+		bin = frappe.get_all("Bin", filters={"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, 
+			fields=["ordered_qty"])	
 		
-		item = make_item("_Test Close Item", {"is_stock_item": 1, "is_sales_item": 1,
-			"is_purchase_item": 1})
+		existing_ordered_qty = bin[0].ordered_qty if bin else 0.0
 			
-		po = create_purchase_order(item_code=item.item_code, qty=1)
+		po = create_purchase_order(item_code= "_Test Item", qty=1)
 		
-		self.assertEquals(get_ordered_qty(item_code=item.item_code, warehouse="_Test Warehouse - _TC"), 1)
+		self.assertEquals(get_ordered_qty(item_code= "_Test Item", warehouse="_Test Warehouse - _TC"), existing_ordered_qty+1)
 		
 		po.update_status("Closed")
 		
-		self.assertEquals(get_ordered_qty(item_code=item.item_code, warehouse="_Test Warehouse - _TC"), 0)
+		self.assertEquals(get_ordered_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"), existing_ordered_qty)
 
 def create_purchase_order(**args):
 	po = frappe.new_doc("Purchase Order")
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 2de6777..b68339c 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -174,9 +174,7 @@
 			if change_modified:
 				args['set_modified'] = ', modified = now(), modified_by = "{0}"'\
 					.format(frappe.db.escape(frappe.session.user))
-			
-			args["drop_ship_cond"] = ''
-			
+						
 			self._update_children(args)
 
 			if "percent_join_field" in args:
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 9ad6d56..2022ffd 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -22,8 +22,9 @@
 			if(doc.status != 'Stopped' && doc.status != 'Closed') {
 				
 				$.each(cur_frm.doc.items, function(i, item){
-					if((item.delivered_by_supplier == 1 || item.supplier) && (item.qty > item.ordered_qty)){
-						is_delivered_by_supplier = true;
+					if(item.delivered_by_supplier == 1 || item.supplier){
+						if(item.qty > item.ordered_qty)
+							is_delivered_by_supplier = true;
 					}
 					else{
 						if(item.qty > item.delivered_qty)
@@ -37,7 +38,7 @@
 				// 	doc.per_billed);
 
 				// indent
-				if(!doc.order_type || ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && flt(doc.per_delivered, 2) < 100)
+				if(!doc.order_type || ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && flt(doc.per_delivered, 2) < 100 && !is_delivered_by_supplier)
 					cur_frm.add_custom_button(__('Material Request'), this.make_material_request);
 
 				if(flt(doc.per_billed)==0) {
@@ -45,8 +46,7 @@
 				}
 
 				// stop
-				if((flt(doc.per_delivered, 2) < 100 && is_delivery_note) || doc.per_billed < 100 
-					|| (flt(doc.per_ordered,2) < 100 && is_delivered_by_supplier)){
+				if(flt(doc.per_delivered, 2) < 100 || flt(doc.per_billed) < 100) {
 						cur_frm.add_custom_button(__('Stop'), this.stop_sales_order)
 					}
 				
@@ -68,7 +68,7 @@
 					cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary");
 				}
 				
-				if(flt(doc.per_ordered, 2) < 100 && is_delivered_by_supplier)
+				if(flt(doc.per_delivered, 2) < 100 && is_delivered_by_supplier)
 					cur_frm.add_custom_button(__('Make Purchase Order'), cur_frm.cscript.make_purchase_order).addClass("btn-primary");
 
 			} else {
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index f452fa9..7ea796c 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -260,8 +260,34 @@
 		pass
 	
 	def before_update_after_submit(self):
-		self.validate_drop_ship()
+		self.validate_drop_ship()	
+		self.validate_po()
+		
+	def validate_po(self):
+		exc_list = []
+		
+		for item in self.items:
+			supplier = frappe.db.get_value("Sales Order Item", {"parent": self.name, "item_code": item.item_code}, 
+				"supplier")
+			if item.ordered_qty > 0.0 and item.supplier != supplier:
+				exc_list.append("Row #{0}: Not allowed to change supplier as Purchase Order already exists".format(item.idx))
+		
+		if exc_list:		
+			frappe.throw('\n'.join(exc_list))
+		
+	def update_delivery_status(self, po_name):
+		tot_qty, delivered_qty = 0.0, 0.0
 
+		for item in self.items:
+			if item.delivered_by_supplier:
+				delivered_qty = frappe.db.get_value("Purchase Order Item", {"parent": po_name, "item_code": item.item_code}, "qty")
+				frappe.db.set_value("Sales Order Item", item.name, "delivered_qty", delivered_qty)
+				
+			delivered_qty += item.delivered_qty
+			tot_qty += item.qty
+			
+		frappe.db.set_value("Sales Order", self.name, "per_delivered", flt(delivered_qty/tot_qty) * 100)
+		
 def get_list_context(context=None):
 	from erpnext.controllers.website_list_for_contact import get_list_context
 	list_context = get_list_context(context)
@@ -551,15 +577,9 @@
 			],
 			"postprocess": update_item,
 			"condition": lambda doc: doc.ordered_qty < doc.qty and doc.supplier == for_supplier
-		},
-		"Sales Taxes and Charges": {
-			"doctype": "Purchase Taxes and Charges",
-			"add_if_empty": True
 		}
 	}, target_doc, set_missing_values)
 	
-	
-
 	return doclist
 
 @frappe.whitelist()
@@ -595,4 +615,4 @@
 def update_status(status, name):
 	so = frappe.get_doc("Sales Order", name)
 	so.stop_sales_order(status)
-	return
\ No newline at end of file
+	
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index 3ef1a25..1d11a8b 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -317,7 +317,6 @@
 				"warehouse": "_Test Warehouse - _TC",
 				"qty": 2,
 				"rate": 400,
-				"conversion_factor": 1.0,
 				"delivered_by_supplier": 1,
 				"supplier": '_Test Supplier'
 			},
@@ -330,9 +329,19 @@
 			}
 		]
 		
+		#setuo existing qty from bin
 		bin = frappe.get_all("Bin", filters={"item_code": po_item.item_code, "warehouse": "_Test Warehouse - _TC"}, 
 			fields=["ordered_qty", "reserved_qty"])
-					
+			
+		existing_ordered_qty = bin[0].ordered_qty if bin else 0.0
+		existing_reserved_qty = bin[0].reserved_qty if bin else 0.0
+		
+		bin = frappe.get_all("Bin", filters={"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, 
+			fields=["reserved_qty"])
+		
+		existing_reserved_qty_for_dn_item = bin[0].reserved_qty if bin else 0.0
+		
+		#create so, po and partial dn
 		so = make_sales_order(item_list=so_items, do_not_submit=True)
 		so.submit()
 		
@@ -351,40 +360,56 @@
 		ordered_qty, reserved_qty = frappe.db.get_value("Bin", 
 			{"item_code": po_item.item_code, "warehouse": "_Test Warehouse - _TC"}, ["ordered_qty", "reserved_qty"])
 		
-		existing_ordered_qty = bin[0].ordered_qty if bin else 0.0
-		existing_reserved_qty = bin[0].reserved_qty if bin else 0.0	
-					
 		self.assertEquals(abs(ordered_qty), existing_ordered_qty + so_items[0]['qty'])			
-		self.assertEquals(abs(reserved_qty), existing_reserved_qty + so_items[0]['qty'])	
+		self.assertEquals(abs(reserved_qty), existing_reserved_qty + so_items[0]['qty'])
+		
+		reserved_qty = frappe.db.get_value("Bin", 
+					{"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, "reserved_qty")
+		
+		self.assertEquals(abs(reserved_qty), existing_reserved_qty_for_dn_item + 1)
 		
 		#test po_item length
 		self.assertEquals(len(po.items), 1)
 		
 		#test per_delivered status
 		delivered_by_supplier(po.name)
-		per_delivered = frappe.db.sql("""select sum(if(qty > ifnull(delivered_qty, 0), delivered_qty, qty))/sum(qty)*100 as per_delivered 
-			from `tabSales Order Item` where parent="{0}" """.format(so.name))
-
-		self.assertEquals(frappe.db.get_value("Sales Order", so.name, "per_delivered"), per_delivered[0][0])
+		self.assertEquals(flt(frappe.db.get_value("Sales Order", so.name, "per_delivered"), 2), 75.00)
 		
+		#test reserved qty after complete delivery
 		dn = create_dn_against_so(so.name, delivered_qty=1)
+		reserved_qty = frappe.db.get_value("Bin", 
+			{"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, "reserved_qty")
 		
+		self.assertEquals(abs(reserved_qty), existing_reserved_qty_for_dn_item)
+		
+		#test after closing so
 		so.db_set('status', "Closed")
 		so.update_reserved_qty()
 		
+		ordered_qty, reserved_qty = frappe.db.get_value("Bin", 
+			{"item_code": po_item.item_code, "warehouse": "_Test Warehouse - _TC"}, ["ordered_qty", "reserved_qty"])
+		
+		self.assertEquals(abs(ordered_qty), existing_ordered_qty)			
+		self.assertEquals(abs(reserved_qty), existing_reserved_qty)
+		
+		reserved_qty = frappe.db.get_value("Bin", 
+			{"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, "reserved_qty")
+		
+		self.assertEquals(abs(reserved_qty), existing_reserved_qty)
+		
 	def test_reserved_qty_for_closing_so(self):
-		from erpnext.stock.doctype.item.test_item import make_item
+		bin = frappe.get_all("Bin", filters={"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, 
+			fields=["reserved_qty"])	
 		
-		item = make_item("_Test Close Item", {"is_stock_item": 1, "is_sales_item": 1,
-			"is_purchase_item": 1})
+		existing_reserved_qty = bin[0].reserved_qty if bin else 0.0
 			
-		so = make_sales_order(item_code=item.item_code, qty=1)
+		so = make_sales_order(item_code="_Test Item", qty=1)
 		
-		self.assertEquals(get_reserved_qty(item_code=item.item_code, warehouse="_Test Warehouse - _TC"), 1)
+		self.assertEquals(get_reserved_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"), existing_reserved_qty+1)
 		
 		so.stop_sales_order("Closed")
 		
-		self.assertEquals(get_reserved_qty(item_code=item.item_code, warehouse="_Test Warehouse - _TC"), 0)
+		self.assertEquals(get_reserved_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"), existing_reserved_qty)
 		
 		
 def make_sales_order(**args):