[Fix] 'To Bill' status even if the amount is zero (#14784)

* Fix 'To Bill' status even if the invoice amount is zero

* Modify fix to only apply on Delivery Note documents
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index b13e404..d94564e 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -129,7 +129,7 @@
 					self.status = s[0]
 					break
 				elif s[1].startswith("eval:"):
-					if frappe.safe_eval(s[1][5:], None, { "self": self.as_dict(), "getdate": getdate, 
+					if frappe.safe_eval(s[1][5:], None, { "self": self.as_dict(), "getdate": getdate,
 							"nowdate": nowdate, "get_value": frappe.db.get_value }):
 						self.status = s[0]
 						break
@@ -256,7 +256,7 @@
 
 			if args['detail_id']:
 				if not args.get("extra_cond"): args["extra_cond"] = ""
-				
+
 				frappe.db.sql("""update `tab%(target_dt)s`
 					set %(target_field)s = (
 						(select ifnull(sum(%(source_field)s), 0)
@@ -281,7 +281,7 @@
 		"""Update percent field in parent transaction"""
 
 		self._update_modified(args, update_modified)
-		
+
 		if args.get('target_parent_field'):
 			frappe.db.sql("""update `tab%(target_parent_dt)s`
 				set %(target_parent_field)s = round(
@@ -335,8 +335,7 @@
 				from `tab%s Item` where %s=%s and docstatus=1""" %
 				(self.doctype, ref_fieldname, '%s'), (ref_dn))[0][0])
 
-			per_billed = ((ref_doc_qty if billed_qty > ref_doc_qty else billed_qty)\
-				/ ref_doc_qty)*100
+			per_billed = (min(ref_doc_qty, billed_qty) / ref_doc_qty) * 100
 
 			ref_doc = frappe.get_doc(ref_dt, ref_dn)
 
diff --git a/erpnext/selling/doctype/sales_order/sales_order_list.js b/erpnext/selling/doctype/sales_order/sales_order_list.js
index 43c91b9..69c2100 100644
--- a/erpnext/selling/doctype/sales_order/sales_order_list.js
+++ b/erpnext/selling/doctype/sales_order/sales_order_list.js
@@ -1,20 +1,25 @@
 frappe.listview_settings['Sales Order'] = {
 	add_fields: ["base_grand_total", "customer_name", "currency", "delivery_date",
 		"per_delivered", "per_billed", "status", "order_type", "name"],
-	get_indicator: function(doc) {
-		if(doc.status==="Closed"){
+	get_indicator: function (doc) {
+		if (doc.status === "Closed") {
 			return [__("Closed"), "green", "status,=,Closed"];
 
 		} else if (doc.order_type !== "Maintenance"
 			&& flt(doc.per_delivered, 6) < 100 && frappe.datetime.get_diff(doc.delivery_date) < 0) {
-			// to bill & overdue
+			// not delivered & overdue
 			return [__("Overdue"), "red", "per_delivered,<,100|delivery_date,<,Today|status,!=,Closed"];
 
 		} else if (doc.order_type !== "Maintenance"
-			&& flt(doc.per_delivered, 6) < 100 && doc.status!=="Closed") {
+			&& flt(doc.per_delivered, 6) < 100 && doc.status !== "Closed") {
 			// not delivered
 
-			if(flt(doc.per_billed, 6) < 100) {
+			if (flt(doc.grand_total) === 0) {
+				// not delivered (zero-amount order)
+
+				return [__("To Deliver"), "orange",
+					"per_delivered,<,100|grand_total,=,0|status,!=,Closed"];
+			} else if (flt(doc.per_billed, 6) < 100) {
 				// not delivered & not billed
 
 				return [__("To Deliver and Bill"), "orange",
@@ -27,13 +32,13 @@
 			}
 
 		} else if ((doc.order_type === "Maintenance" || flt(doc.per_delivered, 6) == 100)
-			&& flt(doc.per_billed, 6) < 100 && doc.status!=="Closed") {
-
+			&& flt(doc.grand_total) !== 0 && flt(doc.per_billed, 6) < 100 && doc.status !== "Closed") {
 			// to bill
+
 			return [__("To Bill"), "orange", "per_delivered,=,100|per_billed,<,100|status,!=,Closed"];
 
-		} else if((doc.order_type === "Maintenance" || flt(doc.per_delivered, 6) == 100)
-			&& flt(doc.per_billed, 6) == 100 && doc.status!=="Closed") {
+		} else if ((doc.order_type === "Maintenance" || flt(doc.per_delivered, 6) == 100)
+			&& (flt(doc.grand_total) === 0 || flt(doc.per_billed, 6) == 100) && doc.status !== "Closed") {
 
 			return [__("Completed"), "green", "per_delivered,=,100|per_billed,=,100|status,!=,Closed"];
 		}
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 1df07a2..91912cb 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -311,8 +311,7 @@
 
 		for dn in set(updated_delivery_notes):
 			dn_doc = self if (dn == self.name) else frappe.get_doc("Delivery Note", dn)
-			if dn_doc.net_total > 0:
-				dn_doc.update_billing_percentage(update_modified=update_modified)
+			dn_doc.update_billing_percentage(update_modified=update_modified)
 
 		self.load_from_db()
 
@@ -400,7 +399,7 @@
 		# set company address
 		target.update(get_company_address(target.company))
 		if target.company_address:
-			target.update(get_fetch_values("Sales Invoice", 'company_address', target.company_address))	
+			target.update(get_fetch_values("Sales Invoice", 'company_address', target.company_address))
 
 	def update_item(source_doc, target_doc, source_parent):
 		target_doc.qty = source_doc.qty - invoiced_qty_map.get(source_doc.name, 0)
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_list.js b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
index f1ad929..9ec2a38 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note_list.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
@@ -1,14 +1,13 @@
 frappe.listview_settings['Delivery Note'] = {
-	add_fields: ["customer", "customer_name", "base_grand_total", "per_installed", "per_billed", 
-		"transporter_name", "grand_total", "is_return", "status"],
-	get_indicator: function(doc) {
-		if(cint(doc.is_return)==1) {
+	add_fields: ["grand_total", "is_return", "per_billed", "status"],
+	get_indicator: function (doc) {
+		if (cint(doc.is_return) == 1) {
 			return [__("Return"), "darkgrey", "is_return,=,Yes"];
-		} else if(doc.status==="Closed") {
+		} else if (doc.status === "Closed") {
 			return [__("Closed"), "green", "status,=,Closed"];
-		}  else if (flt(doc.per_billed, 2) < 100) {
+		} else if (doc.grand_total !== 0 && flt(doc.per_billed, 2) < 100) {
 			return [__("To Bill"), "orange", "per_billed,<,100"];
-		} else if (flt(doc.per_billed, 2) == 100) {
+		} else if (doc.grand_total === 0 || flt(doc.per_billed, 2) == 100) {
 			return [__("Completed"), "green", "per_billed,=,100"];
 		}
 	}
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
index 5c57fb5..e1d5b08 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
@@ -1,14 +1,13 @@
 frappe.listview_settings['Purchase Receipt'] = {
-	add_fields: ["supplier", "supplier_name", "base_grand_total", "is_subcontracted",
-		"transporter_name", "is_return", "status", "per_billed"],
-	get_indicator: function(doc) {
-		if(cint(doc.is_return)==1) {
+	add_fields: ["is_return", "grand_total", "status", "per_billed"],
+	get_indicator: function (doc) {
+		if (cint(doc.is_return) == 1) {
 			return [__("Return"), "darkgrey", "is_return,=,Yes"];
-		} else if(doc.status==="Closed") {
+		} else if (doc.status === "Closed") {
 			return [__("Closed"), "green", "status,=,Closed"];
-		}  else if (flt(doc.per_billed, 2) < 100) {
+		} else if (flt(doc.grand_total) !== 0 && flt(doc.per_billed, 2) < 100) {
 			return [__("To Bill"), "orange", "per_billed,<,100"];
-		} else if (flt(doc.per_billed, 2) == 100) {
+		} else if (flt(doc.grand_total) === 0 || flt(doc.per_billed, 2) == 100) {
 			return [__("Completed"), "green", "per_billed,=,100"];
 		}
 	}