[fix] Reserved and ordered qty fix for drop ship orders
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 6abf1ba..b9dfec8 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -379,6 +379,8 @@
 				msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
 
 	def validate_warehouse(self):
+		super(SalesInvoice, self).validate_warehouse()
+		
 		for d in self.get('items'):
 			if not d.warehouse:
 				frappe.throw(_("Warehouse required at Row No {0}").format(d.idx))
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 3700d96..74936da 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -19,7 +19,7 @@
 		this._super();
 		// this.frm.dashboard.reset();
 		var allow_receipt = false;
-		var allow_delivery = false;
+		var is_drop_ship = false;
 
 		for (var i in cur_frm.doc.items) {
 			var item = cur_frm.doc.items[i];
@@ -27,16 +27,16 @@
 				allow_receipt = true;
 			}
 			
-			if(item.delivered_by_supplier === 1) {
-				allow_delivery = true
+			else {
+				is_drop_ship = true
 			}
 			
-			if(allow_delivery && allow_receipt) {
+			if(is_drop_ship && allow_receipt) {
 				break;
 			}
 		}
 		
-		cur_frm.set_df_property("drop_ship", "hidden", !allow_delivery);
+		cur_frm.set_df_property("drop_ship", "hidden", !is_drop_ship);
 		
 		if(doc.docstatus == 1 && !in_list(["Stopped", "Closed", "Delivered"], doc.status)) {
 			if (this.frm.has_perm("submit")) {
@@ -47,7 +47,7 @@
 				cur_frm.add_custom_button(__('Close'), this.close_purchase_order);
 			}
 
-			if(allow_delivery && doc.status!="Delivered"){
+			if(is_drop_ship && doc.status!="Delivered"){
 				cur_frm.add_custom_button(__('Mark as Delivered'), this.delivered_by_supplier);
 			}
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 74fe371..4670e35 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -138,9 +138,11 @@
 		"""update requested qty (before ordered_qty is updated)"""
 		item_wh_list = []
 		for d in self.get("items"):
-			if (not po_item_rows or d.name in po_item_rows) and [d.item_code, d.warehouse] not in item_wh_list \
-					and frappe.db.get_value("Item", d.item_code, "is_stock_item") and d.warehouse:
-				item_wh_list.append([d.item_code, d.warehouse])
+			if (not po_item_rows or d.name in po_item_rows) \
+				and [d.item_code, d.warehouse] not in item_wh_list \
+				and frappe.db.get_value("Item", d.item_code, "is_stock_item") \
+				and d.warehouse and not d.delivered_by_supplier:
+					item_wh_list.append([d.item_code, d.warehouse])
 
 		for item_code, warehouse in item_wh_list:
 			update_bin_qty(item_code, warehouse, {
@@ -165,7 +167,7 @@
 		clear_doctype_notifications(self)
 
 	def on_submit(self):
-		if self.is_drop_ship_item():
+		if self.has_drop_ship_item():
 			self.update_status_updater()
 
 		super(PurchaseOrder, self).on_submit()
@@ -182,7 +184,7 @@
 		purchase_controller.update_last_purchase_rate(self, is_submit = 1)
 
 	def on_cancel(self):
-		if self.is_drop_ship_item():
+		if self.has_drop_ship_item():
 			self.update_status_updater()
 
 		pc_obj = frappe.get_doc('Purchase Common')
@@ -245,7 +247,7 @@
 			so.set_status(update=True)
 			so.notify_update()
 
-	def is_drop_ship_item(self):
+	def has_drop_ship_item(self):
 		is_drop_ship = False
 		
 		for item in self.items:
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 5ccf29d..69561e1 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -52,15 +52,6 @@
 					self.supplier = supplier
 					break
 
-	def validate_warehouse(self):
-		from erpnext.stock.utils import validate_warehouse_company
-
-		warehouses = list(set([d.warehouse for d in
-			self.get("items") if getattr(d, "warehouse", None)]))
-
-		for w in warehouses:
-			validate_warehouse_company(w, self.company)
-
 	def validate_stock_or_nonstock_items(self):
 		if self.meta.get_field("taxes") and not self.get_stock_items():
 			tax_for_valuation = [d.account_head for d in self.get("taxes")
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 2a9fa17..5deb839 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -303,6 +303,15 @@
 						}))
 
 		self.make_sl_entries(sl_entries)
+		
+	def validate_warehouse(self):
+		from erpnext.stock.utils import validate_warehouse_company
+
+		warehouses = list(set([d.warehouse for d in
+			self.get("items") if getattr(d, "warehouse", None)]))
+
+		for w in warehouses:
+			validate_warehouse_company(w, self.company)
 
 def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
 		warehouse_account=None):
diff --git a/erpnext/patches/v6_8/move_drop_ship_to_po_items.py b/erpnext/patches/v6_8/move_drop_ship_to_po_items.py
index 8163e8f..44ba3f0 100644
--- a/erpnext/patches/v6_8/move_drop_ship_to_po_items.py
+++ b/erpnext/patches/v6_8/move_drop_ship_to_po_items.py
@@ -6,14 +6,14 @@
 		
 		for item in purchase_order.items:
 			if item.prevdoc_doctype == "Sales Order":
-				delivered_by_supplier = frappe.get_value("Sales Order Item", {"parent": item.prevdoc_docname, 
-					"item_code": item.item_code}, "delivered_by_supplier")
+				delivered_by_supplier = frappe.get_value("Sales Order Item", item.prevdoc_detail_docname, 
+					"delivered_by_supplier")
 				
 				if delivered_by_supplier:
-					frappe.db.set_value("Purchase Order Item", item.name, "delivered_by_supplier", 1)
-					frappe.db.set_value("Purchase Order Item", item.name, "billed_amt", item.amount)
-					frappe.db.set_value("Purchase Order Item", item.name, "received_qty", item.qty)
-					
+					frappe.db.sql("""update `tabPurchase Order Item` 
+						set delivered_by_supplier=1, billed_amt=amount, received_qty=qty
+						where name=%s """, item.name)
+						
 		update_per_received(purchase_order)
 		update_per_billed(purchase_order)
 	
@@ -22,15 +22,15 @@
 				set per_received = round((select sum(if(qty > ifnull(received_qty, 0), 
 					ifnull(received_qty, 0), qty)) / sum(qty) *100 
 				from `tabPurchase Order Item` 
-				where parent = "%(name)s"), 2) 
-			where name = "%(name)s" """ % po.as_dict())
+				where parent = %(name)s), 2) 
+			where name = %(name)s """, {"name": po.name})
 
 def update_per_billed(po):
 	frappe.db.sql(""" update `tabPurchase Order` 
 				set per_billed = round((select sum( if(amount > ifnull(billed_amt, 0), 
 					ifnull(billed_amt, 0), amount)) / sum(amount) *100 
 				from `tabPurchase Order Item` 
-				where parent = "%(name)s"), 2) 
-			where name = "%(name)s" """ % po.as_dict())
+				where parent = %(name)s), 2) 
+			where name = %(name)s """, {"name": po.name})
 
 				
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 5ceeea8..d2b1653 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -66,12 +66,6 @@
 		for d in self.get('items'):
 			check_list.append(cstr(d.item_code))
 
-			if (frappe.db.get_value("Item", d.item_code, "is_stock_item")==1 or
-				(self.has_product_bundle(d.item_code) and self.product_bundle_has_stock_item(d.item_code))) \
-				and not d.warehouse and not cint(d.delivered_by_supplier):
-				frappe.throw(_("Delivery warehouse required for stock item {0}").format(d.item_code),
-					WarehouseRequired)
-
 			# used for production plan
 			d.transaction_date = self.transaction_date
 
@@ -116,14 +110,15 @@
 				frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project_name))
 
 	def validate_warehouse(self):
-		from erpnext.stock.utils import validate_warehouse_company
-
-		warehouses = list(set([d.warehouse for d in
-			self.get("items") if d.warehouse]))
-
-		for w in warehouses:
-			validate_warehouse_company(w, self.company)
-
+		super(SalesOrder, self).validate_warehouse()
+		
+		for d in self.get("items"):
+			if (frappe.db.get_value("Item", d.item_code, "is_stock_item")==1 or
+				(self.has_product_bundle(d.item_code) and self.product_bundle_has_stock_item(d.item_code))) \
+				and not d.warehouse and not cint(d.delivered_by_supplier):
+				frappe.throw(_("Delivery warehouse required for stock item {0}").format(d.item_code),
+					WarehouseRequired)
+			
 	def validate_with_previous_doc(self):
 		super(SalesOrder, self).validate_with_previous_doc({
 			"Quotation": {
@@ -236,13 +231,13 @@
 					item_wh_list.append([item_code, warehouse])
 
 		for d in self.get("items"):
-			if (not so_item_rows or d.name in so_item_rows):
-				_valid_for_reserve(d.item_code, d.warehouse)
-
+			if (not so_item_rows or d.name in so_item_rows) and not d.delivered_by_supplier:
 				if self.has_product_bundle(d.item_code):
 					for p in self.get("packed_items"):
 						if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
 							_valid_for_reserve(p.item_code, p.warehouse)
+				else:
+					_valid_for_reserve(d.item_code, d.warehouse)
 
 		for item_code, warehouse in item_wh_list:
 			update_bin_qty(item_code, warehouse, {
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 60cc430..d653250 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -170,6 +170,8 @@
 					chk_dupl_itm.append(f)
 
 	def validate_warehouse(self):
+		super(DeliveryNote, self).validate_warehouse()
+		
 		for d in self.get_item_list():
 			if frappe.db.get_value("Item", d['item_code'], "is_stock_item") == 1:
 				if not d['warehouse']:
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 609c986..87e7fcd 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -76,10 +76,12 @@
 					(
 						select qty from `tabSales Order Item`
 						where name = dnpi.parent_detail_docname
+						and (delivered_by_supplier is null or delivered_by_supplier = 0)
 					) as so_item_qty,
 					(
 						select ifnull(delivered_qty, 0) from `tabSales Order Item`
-						where name = dnpi.parent_detail_docname
+						where name = dnpi.parent_detail_docname 
+						and (delivered_by_supplier is null or delivered_by_supplier = 0)
 					) as so_item_delivered_qty,
 					parent, name
 				from
@@ -96,7 +98,8 @@
 				(select qty as dnpi_qty, qty as so_item_qty,
 					ifnull(delivered_qty, 0) as so_item_delivered_qty, parent, name
 				from `tabSales Order Item` so_item
-				where item_code = %s and warehouse = %s
+				where item_code = %s and warehouse = %s 
+				and (so_item.delivered_by_supplier is null or so_item.delivered_by_supplier = 0)
 				and exists(select * from `tabSales Order` so
 					where so.name = so_item.parent and so.docstatus = 1
 					and so.status not in ('Stopped','Closed')))
@@ -122,7 +125,9 @@
 		from `tabPurchase Order Item` po_item, `tabPurchase Order` po
 		where po_item.item_code=%s and po_item.warehouse=%s
 		and po_item.qty > ifnull(po_item.received_qty, 0) and po_item.parent=po.name
-		and po.status not in ('Stopped', 'Closed', 'Delivered') and po.docstatus=1""", (item_code, warehouse))
+		and po.status not in ('Stopped', 'Closed', 'Delivered') and po.docstatus=1
+		and (po_item.delivered_by_supplier is null or po_item.delivered_by_supplier = 0)
+		""", (item_code, warehouse))
 
 	return flt(ordered_qty[0][0]) if ordered_qty else 0