feat: Provisional accounting for expenses (#29451)

* feat: Provisonal accounting for expenses

* fix: Method for provisional accounting entry

* chore: Add test case

* fix: Remove test case

* fix: Use company doctype

* fix: Add provisional expense account field in Purchase Receipt Item

* fix: Test case

* fix: Move provisional expense account to parent

* fix: Patch
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index b364218..279557a 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -548,6 +548,10 @@
 		exchange_rate_map, net_rate_map = get_purchase_document_details(self)
 
 		enable_discount_accounting = cint(frappe.db.get_single_value('Accounts Settings', 'enable_discount_accounting'))
+		provisional_accounting_for_non_stock_items = cint(frappe.db.get_value('Company', self.company, \
+			'enable_provisional_accounting_for_non_stock_items'))
+
+		purchase_receipt_doc_map = {}
 
 		for item in self.get("items"):
 			if flt(item.base_net_amount):
@@ -643,19 +647,23 @@
 					else:
 						amount = flt(item.base_net_amount + item.item_tax_amount, item.precision("base_net_amount"))
 
-					auto_accounting_for_non_stock_items = cint(frappe.db.get_value('Company', self.company, 'enable_perpetual_inventory_for_non_stock_items'))
-
-					if auto_accounting_for_non_stock_items:
-						service_received_but_not_billed_account = self.get_company_default("service_received_but_not_billed")
-
+					if provisional_accounting_for_non_stock_items:
 						if item.purchase_receipt:
+							provisional_account = self.get_company_default("default_provisional_account")
+							purchase_receipt_doc = purchase_receipt_doc_map.get(item.purchase_receipt)
+
+							if not purchase_receipt_doc:
+								purchase_receipt_doc = frappe.get_doc("Purchase Receipt", item.purchase_receipt)
+								purchase_receipt_doc_map[item.purchase_receipt] = purchase_receipt_doc
+
 							# Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt
 							expense_booked_in_pr = frappe.db.get_value('GL Entry', {'is_cancelled': 0,
 								'voucher_type': 'Purchase Receipt', 'voucher_no': item.purchase_receipt, 'voucher_detail_no': item.pr_detail,
-								'account':service_received_but_not_billed_account}, ['name'])
+								'account':provisional_account}, ['name'])
 
 							if expense_booked_in_pr:
-								expense_account = service_received_but_not_billed_account
+								# Intentionally passing purchase invoice item to handle partial billing
+								purchase_receipt_doc.add_provisional_gl_entry(item, gl_entries, self.posting_date, reverse=1)
 
 					if not self.is_internal_transfer():
 						gl_entries.append(self.get_gl_dict({
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 21846bb..d51a008 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -11,12 +11,17 @@
 import erpnext
 from erpnext.accounts.doctype.account.test_account import create_account, get_inventory_account
 from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
+from erpnext.buying.doctype.purchase_order.purchase_order import get_mapped_purchase_invoice
+from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
 from erpnext.buying.doctype.supplier.test_supplier import create_supplier
 from erpnext.controllers.accounts_controller import get_payment_terms
 from erpnext.controllers.buying_controller import QtyMismatchError
 from erpnext.exceptions import InvalidCurrency
 from erpnext.projects.doctype.project.test_project import make_project
 from erpnext.stock.doctype.item.test_item import create_item
+from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
+	make_purchase_invoice as create_purchase_invoice_from_receipt,
+)
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import (
 	get_taxes,
 	make_purchase_receipt,
@@ -1147,8 +1152,6 @@
 
 	def test_purchase_invoice_advance_taxes(self):
 		from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
-		from erpnext.buying.doctype.purchase_order.purchase_order import get_mapped_purchase_invoice
-		from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
 
 		# create a new supplier to test
 		supplier = create_supplier(supplier_name = '_Test TDS Advance Supplier',
@@ -1221,6 +1224,45 @@
 		payment_entry.load_from_db()
 		self.assertEqual(payment_entry.taxes[0].allocated_amount, 0)
 
+	def test_provisional_accounting_entry(self):
+		item = create_item("_Test Non Stock Item", is_stock_item=0)
+		provisional_account = create_account(account_name="Provision Account",
+			parent_account="Current Liabilities - _TC", company="_Test Company")
+
+		company = frappe.get_doc('Company', '_Test Company')
+		company.enable_provisional_accounting_for_non_stock_items = 1
+		company.default_provisional_account = provisional_account
+		company.save()
+
+		pr = make_purchase_receipt(item_code="_Test Non Stock Item", posting_date=add_days(nowdate(), -2))
+
+		pi = create_purchase_invoice_from_receipt(pr.name)
+		pi.set_posting_time = 1
+		pi.posting_date = add_days(pr.posting_date, -1)
+		pi.items[0].expense_account = 'Cost of Goods Sold - _TC'
+		pi.save()
+		pi.submit()
+
+		# Check GLE for Purchase Invoice
+		expected_gle = [
+			['Cost of Goods Sold - _TC', 250, 0, add_days(pr.posting_date, -1)],
+			['Creditors - _TC', 0, 250, add_days(pr.posting_date, -1)]
+		]
+
+		check_gl_entries(self, pi.name, expected_gle, pi.posting_date)
+
+		expected_gle_for_purchase_receipt = [
+			["Provision Account - _TC", 250, 0, pr.posting_date],
+			["_Test Account Cost for Goods Sold - _TC", 0, 250, pr.posting_date],
+			["Provision Account - _TC", 0, 250, pi.posting_date],
+			["_Test Account Cost for Goods Sold - _TC", 250, 0, pi.posting_date]
+		]
+
+		check_gl_entries(self, pr.name, expected_gle_for_purchase_receipt, pr.posting_date)
+
+		company.enable_provisional_accounting_for_non_stock_items = 0
+		company.save()
+
 def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
 	gl_entries = frappe.db.sql("""select account, debit, credit, posting_date
 		from `tabGL Entry`
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 2912d3e..8d17683 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -40,7 +40,10 @@
 		if self.docstatus == 2:
 			make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
 
-		if cint(erpnext.is_perpetual_inventory_enabled(self.company)):
+		provisional_accounting_for_non_stock_items = \
+			cint(frappe.db.get_value('Company', self.company, 'enable_provisional_accounting_for_non_stock_items'))
+
+		if cint(erpnext.is_perpetual_inventory_enabled(self.company)) or provisional_accounting_for_non_stock_items:
 			warehouse_account = get_warehouse_account_map(self.company)
 
 			if self.docstatus==1:
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 5a8f8ef..8bd2214 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -328,6 +328,7 @@
 erpnext.patches.v13_0.update_exchange_rate_settings
 erpnext.patches.v13_0.update_asset_quantity_field
 erpnext.patches.v13_0.delete_bank_reconciliation_detail
+erpnext.patches.v13_0.enable_provisional_accounting
 
 [post_model_sync]
 erpnext.patches.v14_0.rename_ongoing_status_in_sla_documents
diff --git a/erpnext/patches/v13_0/enable_provisional_accounting.py b/erpnext/patches/v13_0/enable_provisional_accounting.py
new file mode 100644
index 0000000..8e22270
--- /dev/null
+++ b/erpnext/patches/v13_0/enable_provisional_accounting.py
@@ -0,0 +1,19 @@
+import frappe
+
+
+def execute():
+	frappe.reload_doc("setup", "doctype", "company")
+
+	company = frappe.qb.DocType("Company")
+
+	frappe.qb.update(
+		company
+	).set(
+		company.enable_provisional_accounting_for_non_stock_items, company.enable_perpetual_inventory_for_non_stock_items
+	).set(
+		company.default_provisional_account, company.service_received_but_not_billed
+	).where(
+		company.enable_perpetual_inventory_for_non_stock_items == 1
+	).where(
+		company.service_received_but_not_billed.isnotnull()
+	).run()
\ No newline at end of file
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 63d96bf..370a327 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -3,7 +3,7 @@
  "allow_import": 1,
  "allow_rename": 1,
  "autoname": "field:company_name",
- "creation": "2013-04-10 08:35:39",
+ "creation": "2022-01-25 10:29:55.938239",
  "description": "Legal Entity / Subsidiary with a separate Chart of Accounts belonging to the Organization.",
  "doctype": "DocType",
  "document_type": "Setup",
@@ -77,13 +77,13 @@
   "default_finance_book",
   "auto_accounting_for_stock_settings",
   "enable_perpetual_inventory",
-  "enable_perpetual_inventory_for_non_stock_items",
+  "enable_provisional_accounting_for_non_stock_items",
   "default_inventory_account",
   "stock_adjustment_account",
   "default_in_transit_warehouse",
   "column_break_32",
   "stock_received_but_not_billed",
-  "service_received_but_not_billed",
+  "default_provisional_account",
   "expenses_included_in_valuation",
   "fixed_asset_defaults",
   "accumulated_depreciation_account",
@@ -685,20 +685,6 @@
    "options": "Terms and Conditions"
   },
   {
-   "fieldname": "service_received_but_not_billed",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Service Received But Not Billed",
-   "no_copy": 1,
-   "options": "Account"
-  },
-  {
-   "default": "0",
-   "fieldname": "enable_perpetual_inventory_for_non_stock_items",
-   "fieldtype": "Check",
-   "label": "Enable Perpetual Inventory For Non Stock Items"
-  },
-  {
    "fieldname": "default_in_transit_warehouse",
    "fieldtype": "Link",
    "label": "Default In-Transit Warehouse",
@@ -741,6 +727,20 @@
    "fieldname": "section_break_28",
    "fieldtype": "Section Break",
    "label": "Chart of Accounts"
+  },
+  {
+   "default": "0",
+   "fieldname": "enable_provisional_accounting_for_non_stock_items",
+   "fieldtype": "Check",
+   "label": "Enable Provisional Accounting For Non Stock Items"
+  },
+  {
+   "fieldname": "default_provisional_account",
+   "fieldtype": "Link",
+   "ignore_user_permissions": 1,
+   "label": "Default Provisional Account",
+   "no_copy": 1,
+   "options": "Account"
   }
  ],
  "icon": "fa fa-building",
@@ -748,7 +748,7 @@
  "image_field": "company_logo",
  "is_tree": 1,
  "links": [],
- "modified": "2021-10-04 12:09:25.833133",
+ "modified": "2022-01-25 10:33:16.826067",
  "modified_by": "Administrator",
  "module": "Setup",
  "name": "Company",
@@ -809,5 +809,6 @@
  "show_name_in_global_search": 1,
  "sort_field": "modified",
  "sort_order": "ASC",
+ "states": [],
  "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 0a02bcd..95b1e8b 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -10,6 +10,7 @@
 from frappe import _
 from frappe.cache_manager import clear_defaults_cache
 from frappe.contacts.address_and_contact import load_address_and_contact
+from frappe.custom.doctype.property_setter.property_setter import make_property_setter
 from frappe.utils import cint, formatdate, get_timestamp, today
 from frappe.utils.nestedset import NestedSet
 
@@ -45,7 +46,7 @@
 		self.validate_currency()
 		self.validate_coa_input()
 		self.validate_perpetual_inventory()
-		self.validate_perpetual_inventory_for_non_stock_items()
+		self.validate_provisional_account_for_non_stock_items()
 		self.check_country_change()
 		self.check_parent_changed()
 		self.set_chart_of_accounts()
@@ -187,11 +188,14 @@
 				frappe.msgprint(_("Set default inventory account for perpetual inventory"),
 					alert=True, indicator='orange')
 
-	def validate_perpetual_inventory_for_non_stock_items(self):
+	def validate_provisional_account_for_non_stock_items(self):
 		if not self.get("__islocal"):
-			if cint(self.enable_perpetual_inventory_for_non_stock_items) == 1 and not self.service_received_but_not_billed:
-				frappe.throw(_("Set default {0} account for perpetual inventory for non stock items").format(
-					frappe.bold('Service Received But Not Billed')))
+			if cint(self.enable_provisional_accounting_for_non_stock_items) == 1 and not self.default_provisional_account:
+				frappe.throw(_("Set default {0} account for non stock items").format(
+					frappe.bold('Provisional Account')))
+
+			make_property_setter("Purchase Receipt", "provisional_expense_account", "hidden",
+				not self.enable_provisional_accounting_for_non_stock_items, "Check", validate_fields_for_doctype=False)
 
 	def check_country_change(self):
 		frappe.flags.country_change = False
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index 112dded..b54a90e 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -106,6 +106,8 @@
   "terms",
   "bill_no",
   "bill_date",
+  "accounting_details_section",
+  "provisional_expense_account",
   "more_info",
   "project",
   "status",
@@ -1144,16 +1146,30 @@
    "label": "Represents Company",
    "options": "Company",
    "read_only": 1
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "accounting_details_section",
+   "fieldtype": "Section Break",
+   "label": "Accounting Details"
+  },
+  {
+   "fieldname": "provisional_expense_account",
+   "fieldtype": "Link",
+   "hidden": 1,
+   "label": "Provisional Expense Account",
+   "options": "Account"
   }
  ],
  "icon": "fa fa-truck",
  "idx": 261,
  "is_submittable": 1,
  "links": [],
- "modified": "2021-09-28 13:11:10.181328",
+ "modified": "2022-02-01 11:40:52.690984",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt",
+ "naming_rule": "By \"Naming Series\" field",
  "owner": "Administrator",
  "permissions": [
   {
@@ -1214,6 +1230,7 @@
  "show_name_in_global_search": 1,
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "timeline_field": "supplier",
  "title_field": "title",
  "track_changes": 1
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index c97b306..1257057 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -8,6 +8,7 @@
 from frappe.model.mapper import get_mapped_doc
 from frappe.utils import cint, flt, getdate, nowdate
 
+import erpnext
 from erpnext.accounts.utils import get_account_currency
 from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
 from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
@@ -112,6 +113,7 @@
 		self.validate_uom_is_integer("uom", ["qty", "received_qty"])
 		self.validate_uom_is_integer("stock_uom", "stock_qty")
 		self.validate_cwip_accounts()
+		self.validate_provisional_expense_account()
 
 		self.check_on_hold_or_closed_status()
 
@@ -133,6 +135,15 @@
 					company = self.company)
 				break
 
+	def validate_provisional_expense_account(self):
+		provisional_accounting_for_non_stock_items = \
+			cint(frappe.db.get_value('Company', self.company, 'enable_provisional_accounting_for_non_stock_items'))
+
+		if provisional_accounting_for_non_stock_items:
+			default_provisional_account = self.get_company_default("default_provisional_account")
+			if not self.provisional_expense_account:
+				self.provisional_expense_account = default_provisional_account
+
 	def validate_with_previous_doc(self):
 		super(PurchaseReceipt, self).validate_with_previous_doc({
 			"Purchase Order": {
@@ -258,13 +269,15 @@
 			get_purchase_document_details,
 		)
 
-		stock_rbnb = self.get_company_default("stock_received_but_not_billed")
-		landed_cost_entries = get_item_account_wise_additional_cost(self.name)
-		expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
-		auto_accounting_for_non_stock_items = cint(frappe.db.get_value('Company', self.company, 'enable_perpetual_inventory_for_non_stock_items'))
+		if erpnext.is_perpetual_inventory_enabled(self.company):
+			stock_rbnb = self.get_company_default("stock_received_but_not_billed")
+			landed_cost_entries = get_item_account_wise_additional_cost(self.name)
+			expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
 
 		warehouse_with_no_account = []
 		stock_items = self.get_stock_items()
+		provisional_accounting_for_non_stock_items = \
+				cint(frappe.db.get_value('Company', self.company, 'enable_provisional_accounting_for_non_stock_items'))
 
 		exchange_rate_map, net_rate_map = get_purchase_document_details(self)
 
@@ -422,43 +435,58 @@
 				elif d.warehouse not in warehouse_with_no_account or \
 					d.rejected_warehouse not in warehouse_with_no_account:
 						warehouse_with_no_account.append(d.warehouse)
-			elif d.item_code not in stock_items and not d.is_fixed_asset and flt(d.qty) and auto_accounting_for_non_stock_items:
-				service_received_but_not_billed_account = self.get_company_default("service_received_but_not_billed")
-				credit_currency = get_account_currency(service_received_but_not_billed_account)
-				debit_currency = get_account_currency(d.expense_account)
-				remarks = self.get("remarks") or _("Accounting Entry for Service")
-
-				self.add_gl_entry(
-					gl_entries=gl_entries,
-					account=service_received_but_not_billed_account,
-					cost_center=d.cost_center,
-					debit=0.0,
-					credit=d.amount,
-					remarks=remarks,
-					against_account=d.expense_account,
-					account_currency=credit_currency,
-					project=d.project,
-					voucher_detail_no=d.name, item=d)
-
-				self.add_gl_entry(
-					gl_entries=gl_entries,
-					account=d.expense_account,
-					cost_center=d.cost_center,
-					debit=d.amount,
-					credit=0.0,
-					remarks=remarks,
-					against_account=service_received_but_not_billed_account,
-					account_currency = debit_currency,
-					project=d.project,
-					voucher_detail_no=d.name,
-					item=d)
+			elif d.item_code not in stock_items and not d.is_fixed_asset and flt(d.qty) and provisional_accounting_for_non_stock_items:
+				self.add_provisional_gl_entry(d, gl_entries, self.posting_date)
 
 		if warehouse_with_no_account:
 			frappe.msgprint(_("No accounting entries for the following warehouses") + ": \n" +
 				"\n".join(warehouse_with_no_account))
 
+	def add_provisional_gl_entry(self, item, gl_entries, posting_date, reverse=0):
+		provisional_expense_account = self.get('provisional_expense_account')
+		credit_currency = get_account_currency(provisional_expense_account)
+		debit_currency = get_account_currency(item.expense_account)
+		expense_account = item.expense_account
+		remarks = self.get("remarks") or _("Accounting Entry for Service")
+		multiplication_factor = 1
+
+		if reverse:
+			multiplication_factor = -1
+			expense_account = frappe.db.get_value('Purchase Receipt Item', {'name': item.get('pr_detail')}, ['expense_account'])
+
+		self.add_gl_entry(
+			gl_entries=gl_entries,
+			account=provisional_expense_account,
+			cost_center=item.cost_center,
+			debit=0.0,
+			credit=multiplication_factor * item.amount,
+			remarks=remarks,
+			against_account=expense_account,
+			account_currency=credit_currency,
+			project=item.project,
+			voucher_detail_no=item.name,
+			item=item,
+			posting_date=posting_date)
+
+		self.add_gl_entry(
+			gl_entries=gl_entries,
+			account=expense_account,
+			cost_center=item.cost_center,
+			debit=multiplication_factor * item.amount,
+			credit=0.0,
+			remarks=remarks,
+			against_account=provisional_expense_account,
+			account_currency = debit_currency,
+			project=item.project,
+			voucher_detail_no=item.name,
+			item=item,
+			posting_date=posting_date)
+
 	def make_tax_gl_entries(self, gl_entries):
-		expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
+
+		if erpnext.is_perpetual_inventory_enabled(self.company):
+			expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
+
 		negative_expense_to_be_booked = sum([flt(d.item_tax_amount) for d in self.get('items')])
 		# Cost center-wise amount breakup for other charges included for valuation
 		valuation_tax = {}
@@ -515,7 +543,8 @@
 
 	def add_gl_entry(self, gl_entries, account, cost_center, debit, credit, remarks, against_account,
 		debit_in_account_currency=None, credit_in_account_currency=None, account_currency=None,
-		project=None, voucher_detail_no=None, item=None):
+		project=None, voucher_detail_no=None, item=None, posting_date=None):
+
 		gl_entry = {
 			"account": account,
 			"cost_center": cost_center,
@@ -534,6 +563,9 @@
 		if credit_in_account_currency:
 			gl_entry.update({"credit_in_account_currency": credit_in_account_currency})
 
+		if posting_date:
+			gl_entry.update({"posting_date": posting_date})
+
 		gl_entries.append(self.get_gl_dict(gl_entry, item=item))
 
 	def get_asset_gl_entry(self, gl_entries):
@@ -562,6 +594,7 @@
 		# debit cwip account
 		debit_in_account_currency = (base_asset_amount
 			if cwip_account_currency == self.company_currency else asset_amount)
+
 		self.add_gl_entry(
 			gl_entries=gl_entries,
 			account=cwip_account,
@@ -577,6 +610,7 @@
 		# credit arbnb account
 		credit_in_account_currency = (base_asset_amount
 			if asset_rbnb_currency == self.company_currency else asset_amount)
+
 		self.add_gl_entry(
 			gl_entries=gl_entries,
 			account=arbnb_account,
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 2909a2d..b87d920 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -1312,58 +1312,6 @@
 		self.assertEqual(pr.status, "To Bill")
 		self.assertAlmostEqual(pr.per_billed, 50.0, places=2)
 
-	def test_service_item_purchase_with_perpetual_inventory(self):
-		company = '_Test Company with perpetual inventory'
-		service_item = '_Test Non Stock Item'
-
-		before_test_value = frappe.db.get_value(
-			'Company', company, 'enable_perpetual_inventory_for_non_stock_items'
-		)
-		frappe.db.set_value(
-			'Company', company,
-			'enable_perpetual_inventory_for_non_stock_items', 1
-		)
-		srbnb_account = 'Stock Received But Not Billed - TCP1'
-		frappe.db.set_value(
-			'Company', company,
-			'service_received_but_not_billed', srbnb_account
-		)
-
-		pr = make_purchase_receipt(
-			company=company, item=service_item,
-			warehouse='Finished Goods - TCP1', do_not_save=1
-		)
-		item_row_with_diff_rate = frappe.copy_doc(pr.items[0])
-		item_row_with_diff_rate.rate = 100
-		pr.append('items', item_row_with_diff_rate)
-
-		pr.save()
-		pr.submit()
-
-		item_one_gl_entry = frappe.db.get_all("GL Entry", {
-			'voucher_type': pr.doctype,
-			'voucher_no': pr.name,
-			'account': srbnb_account,
-			'voucher_detail_no': pr.items[0].name
-		}, pluck="name")
-
-		item_two_gl_entry = frappe.db.get_all("GL Entry", {
-			'voucher_type': pr.doctype,
-			'voucher_no': pr.name,
-			'account': srbnb_account,
-			'voucher_detail_no': pr.items[1].name
-		}, pluck="name")
-
-		# check if the entries are not merged into one
-		# seperate entries should be made since voucher_detail_no is different
-		self.assertEqual(len(item_one_gl_entry), 1)
-		self.assertEqual(len(item_two_gl_entry), 1)
-
-		frappe.db.set_value(
-			'Company', company,
-			'enable_perpetual_inventory_for_non_stock_items', before_test_value
-		)
-
 	def test_purchase_receipt_with_exchange_rate_difference(self):
 		from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import (
 			make_purchase_receipt as create_purchase_receipt,
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index 30ea1c3..e5994b2 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -976,7 +976,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-11-15 15:46:10.591600",
+ "modified": "2022-02-01 11:32:27.980524",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt Item",
@@ -985,5 +985,6 @@
  "permissions": [],
  "quick_entry": 1,
  "sort_field": "modified",
- "sort_order": "DESC"
+ "sort_order": "DESC",
+ "states": []
 }
\ No newline at end of file