feat: Partly billed status in Purchase Receipt (#39543)

diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index ac8c88f..e5f341f 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -99,7 +99,8 @@
 	],
 	"Purchase Receipt": [
 		["Draft", None],
-		["To Bill", "eval:self.per_billed < 100 and self.docstatus == 1"],
+		["To Bill", "eval:self.per_billed == 0 and self.docstatus == 1"],
+		["Partly Billed", "eval:self.per_billed > 0 and self.per_billed < 100 and self.docstatus == 1"],
 		["Return Issued", "eval:self.per_returned == 100 and self.docstatus == 1"],
 		["Completed", "eval:self.per_billed == 100 and self.docstatus == 1"],
 		["Cancelled", "eval:self.docstatus==2"],
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
index 4029f0c..f19f1ff 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
@@ -8,8 +8,10 @@
 			return [__("Closed"), "green", "status,=,Closed"];
 		} else if (flt(doc.per_returned, 2) === 100) {
 			return [__("Return Issued"), "grey", "per_returned,=,100"];
-		} else if (flt(doc.grand_total) !== 0 && flt(doc.per_billed, 2) < 100) {
+		} else if (flt(doc.grand_total) !== 0 && flt(doc.per_billed, 2) == 0) {
 			return [__("To Bill"), "orange", "per_billed,<,100"];
+		} else if (flt(doc.per_billed, 2) > 0 && flt(doc.per_billed, 2) < 100) {
+			return [__("Partly Billed"), "yellow", "per_billed,<,100"];
 		} else if (flt(doc.grand_total) === 0 || flt(doc.per_billed, 2) === 100) {
 			return [__("Completed"), "green", "per_billed,=,100"];
 		}
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index ee5a176..dd68d16 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -720,7 +720,7 @@
 		pr2.load_from_db()
 		self.assertEqual(pr2.get("items")[0].billed_amt, 2000)
 		self.assertEqual(pr2.per_billed, 80)
-		self.assertEqual(pr2.status, "To Bill")
+		self.assertEqual(pr2.status, "Partly Billed")
 
 		pr2.cancel()
 		pi2.reload()
@@ -1152,7 +1152,7 @@
 		pi.load_from_db()
 		pr.load_from_db()
 
-		self.assertEqual(pr.status, "To Bill")
+		self.assertEqual(pr.status, "Partly Billed")
 		self.assertAlmostEqual(pr.per_billed, 50.0, places=2)
 
 	def test_purchase_receipt_with_exchange_rate_difference(self):