Merge pull request #38891 from ruthra-kumar/customer_wise_report_price_issue

fix: incorrect price list in customer-wise item price report
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 30be903..6ea121f 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -5,7 +5,7 @@
 
 repos:
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.0.1
+    rev: v4.3.0
     hooks:
       - id: trailing-whitespace
         files: "erpnext.*"
@@ -15,6 +15,10 @@
         args: ['--branch', 'develop']
       - id: check-merge-conflict
       - id: check-ast
+      - id: check-json
+      - id: check-toml
+      - id: check-yaml
+      - id: debug-statements
 
   - repo: https://github.com/pre-commit/mirrors-eslint
     rev: v8.44.0
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/unverified/at_austria_chart_template.json b/erpnext/accounts/doctype/account/chart_of_accounts/unverified/at_austria_chart_template.json
index 58d67be..bd7228e 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/unverified/at_austria_chart_template.json
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/unverified/at_austria_chart_template.json
@@ -26,7 +26,7 @@
 				"0360 Bauliche Investitionen in fremden (gepachteten) Betriebs- und Geschäftsgebäuden": {"account_type": "Fixed Asset"},
 				"0370 Bauliche Investitionen in fremden (gepachteten) Wohn- und Sozialgebäuden": {"account_type": "Fixed Asset"},
 				"0390 Kumulierte Abschreibungen zu Grundstücken ": {"account_type": "Fixed Asset"},
-				"0400 Maschinen und Geräte ": {"account_type": "Fixed Asset"},				
+				"0400 Maschinen und Geräte ": {"account_type": "Fixed Asset"},
 				"0500 Maschinenwerkzeuge ": {"account_type": "Fixed Asset"},
 				"0510 Allgemeine Werkzeuge und Handwerkzeuge ": {"account_type": "Fixed Asset"},
 				"0520 Prototypen, Formen, Modelle ": {"account_type": "Fixed Asset"},
@@ -65,42 +65,41 @@
 				"0980 Geleistete Anzahlungen auf Finanzanlagen ": {"account_type": "Fixed Asset"},
 				"0990 Kumulierte Abschreibungen zu Finanzanlagen ": {"account_type": "Fixed Asset"},
             "root_type": "Asset"
-        },    
+        },
         "Klasse 1 Aktiva: Vorr\u00e4te": {
             "1000 Bezugsverrechnung": {"account_type": "Stock"},
             "1100 Rohstoffe": {"account_type": "Stock"},
             "1200 Bezogene Teile": {"account_type": "Stock"},
             "1300 Hilfsstoffe": {"account_type": "Stock"},
             "1350 Betriebsstoffe": {"account_type": "Stock"},
-            "1360 Vorrat Energietraeger": {"account_type": "Stock"},            
+            "1360 Vorrat Energietraeger": {"account_type": "Stock"},
             "1400 Unfertige Erzeugnisse": {"account_type": "Stock"},
             "1500 Fertige Erzeugnisse": {"account_type": "Stock"},
             "1600 Handelswarenvorrat": {"account_type": "Stock Received But Not Billed"},
             "1700 Noch nicht abrechenbare Leistungen": {"account_type": "Stock"},
-            "1900 Wertberichtigungen": {"account_type": "Stock"},
             "1800 Geleistete Anzahlungen": {"account_type": "Stock"},
             "1900 Wertberichtigungen": {"account_type": "Stock"},
             "root_type": "Asset"
-        },    
+        },
         "Klasse 3 Passiva: Verbindlichkeiten": {
             "3000 Allgemeine Verbindlichkeiten (Schuld)": {"account_type": "Payable"},
             "3010 R\u00fcckstellungen f\u00fcr Pensionen": {"account_type": "Payable"},
             "3020 Steuerr\u00fcckstellungen": {"account_type": "Tax"},
-            "3041 Sonstige R\u00fcckstellungen": {"account_type": "Payable"},            
+            "3041 Sonstige R\u00fcckstellungen": {"account_type": "Payable"},
             "3110 Verbindlichkeiten gegen\u00fcber Bank": {"account_type": "Payable"},
             "3150 Verbindlichkeiten Darlehen": {"account_type": "Payable"},
-            "3185 Verbindlichkeiten Kreditkarte": {"account_type": "Payable"},            
+            "3185 Verbindlichkeiten Kreditkarte": {"account_type": "Payable"},
             "3380 Verbindlichkeiten aus der Annahme gezogener Wechsel u. d. Ausstellungen eigener Wechsel": {
                 "account_type": "Payable"
             },
             "3400 Verbindlichkeiten gegen\u00fc. verb. Untern., Verbindl. gegen\u00fc. Untern., mit denen eine Beteiligungsverh\u00e4lnis besteht": {},
             "3460 Verbindlichkeiten gegenueber Gesellschaftern": {"account_type": "Payable"},
             "3470 Einlagen stiller Gesellschafter": {"account_type": "Payable"},
-            "3585 Verbindlichkeiten Lohnsteuer": {"account_type": "Tax"},             
-            "3590 Verbindlichkeiten Kommunalabgaben": {"account_type": "Tax"},  
-            "3595 Verbindlichkeiten Dienstgeberbeitrag": {"account_type": "Tax"},                       
+            "3585 Verbindlichkeiten Lohnsteuer": {"account_type": "Tax"},
+            "3590 Verbindlichkeiten Kommunalabgaben": {"account_type": "Tax"},
+            "3595 Verbindlichkeiten Dienstgeberbeitrag": {"account_type": "Tax"},
             "3600 Verbindlichkeiten Sozialversicherung": {"account_type": "Payable"},
-            "3640 Verbindlichkeiten Loehne und Gehaelter": {"account_type": "Payable"},            
+            "3640 Verbindlichkeiten Loehne und Gehaelter": {"account_type": "Payable"},
             "3700 Sonstige Verbindlichkeiten": {"account_type": "Payable"},
             "3900 Passive Rechnungsabgrenzungsposten": {"account_type": "Payable"},
             "3100 Anleihen (einschlie\u00dflich konvertibler)": {"account_type": "Payable"},
@@ -119,13 +118,13 @@
             },
             "3515 Umsatzsteuer Inland 10%": {
                 "account_type": "Tax"
-            },            
+            },
             "3520 Umsatzsteuer aus i.g. Erwerb 20%": {
                 "account_type": "Tax"
             },
             "3525 Umsatzsteuer aus i.g. Erwerb 10%": {
                 "account_type": "Tax"
-            },            
+            },
             "3560 Umsatzsteuer-Evidenzkonto f\u00fcr erhaltene Anzahlungen auf Bestellungen": {},
             "3360 Verbindlichkeiten aus Lieferungen u. Leistungen EU": {
                 "account_type": "Payable"
@@ -141,7 +140,7 @@
                 "account_type": "Tax"
             },
             "root_type": "Liability"
-        },      
+        },
         "Klasse 2 Aktiva: Umlaufverm\u00f6gen, Rechnungsabgrenzungen": {
             "2030 Forderungen aus Lieferungen und Leistungen Inland (0% USt, umsatzsteuerfrei)": {
                 "account_type": "Receivable"
@@ -154,7 +153,7 @@
             },
             "2040 Forderungen aus Lieferungen und Leistungen Inland (sonstiger USt-Satz)": {
                 "account_type": "Receivable"
-            },                                    
+            },
             "2100 Forderungen aus Lieferungen und Leistungen EU": {
                 "account_type": "Receivable"
             },
@@ -192,7 +191,7 @@
                 "account_type": "Receivable"
             },
             "2570 Einfuhrumsatzsteuer (bezahlt)": {"account_type": "Tax"},
-            
+
             "2460 Eingeforderte aber noch nicht eingezahlte Einlagen": {
                 "account_type": "Receivable"
             },
@@ -243,10 +242,10 @@
             },
             "2800 Guthaben bei Bank": {
                 "account_type": "Bank"
-            },  
+            },
             "2801 Guthaben bei Bank - Sparkonto": {
                 "account_type": "Bank"
-            },                      
+            },
             "2810 Guthaben bei Paypal": {
                 "account_type": "Bank"
             },
@@ -264,19 +263,19 @@
             },
             "2895 Schwebende Geldbewegugen": {
                 "account_type": "Bank"
-            },            
+            },
             "2513 Vorsteuer Inland 5%": {
                 "account_type": "Tax"
             },
             "2515 Vorsteuer Inland 20%": {
                 "account_type": "Tax"
-            },                        
+            },
             "2520 Vorsteuer aus innergemeinschaftlichem Erwerb 10%": {
                 "account_type": "Tax"
             },
             "2525 Vorsteuer aus innergemeinschaftlichem Erwerb 20%": {
                 "account_type": "Tax"
-            },            
+            },
             "2530 Vorsteuer \u00a719/Art 19 ( reverse charge ) ": {
                 "account_type": "Tax"
             },
@@ -286,16 +285,16 @@
             "root_type": "Asset"
         },
           "Klasse 4: Betriebliche Erträge": {
-            "4000 Erlöse 20 %": {"account_type": "Income Account"},          
-            "4020 Erl\u00f6se 0 % steuerbefreit": {"account_type": "Income Account"},            
+            "4000 Erlöse 20 %": {"account_type": "Income Account"},
+            "4020 Erl\u00f6se 0 % steuerbefreit": {"account_type": "Income Account"},
             "4010 Erl\u00f6se 10 %": {"account_type": "Income Account"},
-            "4030 Erl\u00f6se 13 %": {"account_type": "Income Account"},            
-            "4040 Erl\u00f6se 0 % innergemeinschaftliche Lieferungen": {"account_type": "Income Account"},      
-            "4400 Erl\u00f6sreduktion 0 % steuerbefreit": {"account_type": "Expense Account"},            
+            "4030 Erl\u00f6se 13 %": {"account_type": "Income Account"},
+            "4040 Erl\u00f6se 0 % innergemeinschaftliche Lieferungen": {"account_type": "Income Account"},
+            "4400 Erl\u00f6sreduktion 0 % steuerbefreit": {"account_type": "Expense Account"},
             "4410 Erl\u00f6sreduktion 10 %": {"account_type": "Expense Account"},
             "4420 Erl\u00f6sreduktion 20 %": {"account_type": "Expense Account"},
-            "4430 Erl\u00f6sreduktion 13 %": {"account_type": "Expense Account"},            
-            "4440 Erl\u00f6sreduktion 0 % innergemeinschaftliche Lieferungen": {"account_type": "Expense Account"}, 
+            "4430 Erl\u00f6sreduktion 13 %": {"account_type": "Expense Account"},
+            "4440 Erl\u00f6sreduktion 0 % innergemeinschaftliche Lieferungen": {"account_type": "Expense Account"},
             "4500 Ver\u00e4nderungen des Bestandes an fertigen und unfertigen Erzeugn. sowie an noch nicht abrechenbaren Leistungen": {"account_type": "Income Account"},
             "4580 Aktivierte Eigenleistungen": {"account_type": "Income Account"},
             "4600 Erl\u00f6se aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {"account_type": "Income Account"},
@@ -304,15 +303,15 @@
             "4700 Ertr\u00e4ge aus der Aufl\u00f6sung von R\u00fcckstellungen": {"account_type": "Income Account"},
             "4800 \u00dcbrige betriebliche Ertr\u00e4ge": {"account_type": "Income Account"},
             "root_type": "Income"
-        },        
+        },
         "Klasse 5: Aufwand f\u00fcr Material und Leistungen": {
-            "5000 Einkauf Partnerleistungen": {"account_type": "Cost of Goods Sold"},        
+            "5000 Einkauf Partnerleistungen": {"account_type": "Cost of Goods Sold"},
             "5100 Verbrauch an Rohstoffen": {"account_type": "Cost of Goods Sold"},
             "5200 Verbrauch von bezogenen Fertig- und Einzelteilen": {"account_type": "Cost of Goods Sold"},
             "5300 Verbrauch von Hilfsstoffen": {"account_type": "Cost of Goods Sold"},
             "5340 Verbrauch Verpackungsmaterial": {"account_type": "Cost of Goods Sold"},
             "5470 Verbrauch von Kleinmaterial": {"account_type": "Cost of Goods Sold"},
-            "5450 Verbrauch von Reinigungsmaterial": {"account_type": "Cost of Goods Sold"},                                  
+            "5450 Verbrauch von Reinigungsmaterial": {"account_type": "Cost of Goods Sold"},
             "5400 Verbrauch von Betriebsstoffen": {"account_type": "Cost of Goods Sold"},
             "5500 Verbrauch von Werkzeugen und anderen Erzeugungshilfsmittel": {"account_type": "Cost of Goods Sold"},
             "5600 Verbrauch von Brenn- und Treibstoffen, Energie und Wasser": {"account_type": "Cost of Goods Sold"},
@@ -340,7 +339,7 @@
             "6700 Sonstige Sozialaufwendungen": {"account_type": "Payable"},
             "6900 Aufwandsstellenrechnung Personal": {"account_type": "Payable"},
             "root_type": "Expense"
-        },       
+        },
          "Klasse 7: Abschreibungen und sonstige betriebliche Aufwendungen": {
             "7010 Abschreibungen auf das Anlageverm\u00f6gen (ausgenommen Finanzanlagen)": {"account_type": "Depreciation"},
             "7100 Sonstige Steuern und Geb\u00fchren": {"account_type": "Tax"},
@@ -349,7 +348,7 @@
             "7310 Fahrrad - Aufwand": {"account_type": "Expense Account"},
             "7320 Kfz - Aufwand": {"account_type": "Expense Account"},
             "7330 LKW - Aufwand": {"account_type": "Expense Account"},
-            "7340 Lastenrad - Aufwand": {"account_type": "Expense Account"},            
+            "7340 Lastenrad - Aufwand": {"account_type": "Expense Account"},
             "7350 Reise- und Fahraufwand": {"account_type": "Expense Account"},
             "7360 Tag- und N\u00e4chtigungsgelder": {"account_type": "Expense Account"},
             "7380 Nachrichtenaufwand": {"account_type": "Expense Account"},
@@ -409,7 +408,7 @@
             "8990 Gewinnabfuhr bzw. Verlust\u00fcberrechnung aus Ergebnisabf\u00fchrungsvertr\u00e4gen": {"account_type": "Expense Account"},
             "8350 nicht ausgenutzte Lieferantenskonti": {"account_type": "Expense Account"},
             "root_type": "Income"
-        },       
+        },
         "Klasse 9 Passiva: Eigenkapital, R\u00fccklagen, stille Einlagen, Abschlusskonten": {
             "9000 Gezeichnetes bzw. gewidmetes Kapital": {
                 "account_type": "Equity"
@@ -435,5 +434,5 @@
             },
             "root_type": "Equity"
         }
-     }   
+     }
   }
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json
index 16df40f..09912e9 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.json
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json
@@ -23,6 +23,7 @@
   "against_voucher_type",
   "against_voucher",
   "voucher_type",
+  "voucher_subtype",
   "voucher_no",
   "voucher_detail_no",
   "project",
@@ -138,19 +139,19 @@
    "options": "DocType"
   },
   {
-    "fieldname": "against",
-    "fieldtype": "Text",
-    "in_filter": 1,
-    "label": "Against",
-    "oldfieldname": "against",
-    "oldfieldtype": "Text"
+   "fieldname": "against",
+   "fieldtype": "Text",
+   "in_filter": 1,
+   "label": "Against",
+   "oldfieldname": "against",
+   "oldfieldtype": "Text"
   },
   {
-    "fieldname": "against_link",
-    "fieldtype": "Dynamic Link",
-    "in_filter": 1,
-    "label": "Against",
-    "options": "against_type"
+   "fieldname": "against_link",
+   "fieldtype": "Dynamic Link",
+   "in_filter": 1,
+   "label": "Against",
+   "options": "against_type"
   },
   {
    "fieldname": "against_voucher_type",
@@ -158,8 +159,7 @@
    "label": "Against Voucher Type",
    "oldfieldname": "against_voucher_type",
    "oldfieldtype": "Data",
-   "options": "DocType",
-   "search_index": 1
+   "options": "DocType"
   },
   {
    "fieldname": "against_voucher",
@@ -178,8 +178,7 @@
    "label": "Voucher Type",
    "oldfieldname": "voucher_type",
    "oldfieldtype": "Select",
-   "options": "DocType",
-   "search_index": 1
+   "options": "DocType"
   },
   {
    "fieldname": "voucher_no",
@@ -296,13 +295,18 @@
    "fieldtype": "Currency",
    "label": "Credit Amount in Transaction Currency",
    "options": "transaction_currency"
+  },
+  {
+   "fieldname": "voucher_subtype",
+   "fieldtype": "Small Text",
+   "label": "Voucher Subtype"
   }
  ],
  "icon": "fa fa-list",
  "idx": 1,
  "in_create": 1,
  "links": [],
- "modified": "2023-11-08 12:20:23.031733",
+ "modified": "2023-12-18 15:38:14.006208",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "GL Entry",
@@ -337,4 +341,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "states": []
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index f7dd29a..139f526 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -39,6 +39,8 @@
 		account: DF.Link | None
 		account_currency: DF.Link | None
 		against: DF.Text | None
+		against_link: DF.DynamicLink | None
+		against_type: DF.Link | None
 		against_voucher: DF.DynamicLink | None
 		against_voucher_type: DF.Link | None
 		company: DF.Link | None
@@ -66,6 +68,7 @@
 		transaction_exchange_rate: DF.Float
 		voucher_detail_no: DF.Data | None
 		voucher_no: DF.DynamicLink | None
+		voucher_subtype: DF.SmallText | None
 		voucher_type: DF.Link | None
 	# end: auto-generated types
 
diff --git a/erpnext/accounts/doctype/journal_entry/test_records.json b/erpnext/accounts/doctype/journal_entry/test_records.json
index dafcf56..717c579 100644
--- a/erpnext/accounts/doctype/journal_entry/test_records.json
+++ b/erpnext/accounts/doctype/journal_entry/test_records.json
@@ -1,97 +1,94 @@
 [
- {
-  "cheque_date": "2013-03-14",
-  "cheque_no": "33",
-  "company": "_Test Company",
-  "doctype": "Journal Entry",
-  "accounts": [
-   {
-    "account": "Debtors - _TC",
-	  "party_type": "Customer",
-	  "party": "_Test Customer",
-    "credit_in_account_currency": 400.0,
-    "debit_in_account_currency": 0.0,
-    "doctype": "Journal Entry Account",
-    "parentfield": "accounts",
-    "cost_center": "_Test Cost Center - _TC"
-   },
-   {
-    "account": "_Test Bank - _TC",
-    "credit_in_account_currency": 0.0,
-    "debit_in_account_currency": 400.0,
-    "doctype": "Journal Entry Account",
-    "parentfield": "accounts",
-    "cost_center": "_Test Cost Center - _TC"
-   }
-  ],
-  "naming_series": "_T-Journal Entry-",
-  "posting_date": "2013-02-14",
-  "user_remark": "test",
-  "voucher_type": "Bank Entry"
- },
- 
- 
- {
-  "cheque_date": "2013-02-14",
-  "cheque_no": "33",
-  "company": "_Test Company",
-  "doctype": "Journal Entry",
-  "accounts": [
-   {
-    "account": "_Test Payable - _TC",
-  	"party_type": "Supplier",
-	  "party": "_Test Supplier",
-    "credit_in_account_currency": 0.0,
-    "debit_in_account_currency": 400.0,
-    "doctype": "Journal Entry Account",
-    "parentfield": "accounts",
-    "cost_center": "_Test Cost Center - _TC"
-   },
-   {
-    "account": "_Test Bank - _TC",
-    "credit_in_account_currency": 400.0,
-    "debit_in_account_currency": 0.0,
-    "doctype": "Journal Entry Account",
-    "parentfield": "accounts",
-    "cost_center": "_Test Cost Center - _TC"
-   }
-  ],
-  "naming_series": "_T-Journal Entry-",
-  "posting_date": "2013-02-14",
-  "user_remark": "test",
-  "voucher_type": "Bank Entry"
- },
- 
- 
- {
-  "cheque_date": "2013-02-14",
-  "cheque_no": "33",
-  "company": "_Test Company",
-  "doctype": "Journal Entry",
-  "accounts": [
-   {
-    "account": "Debtors - _TC",
-	  "party_type": "Customer",
-  	"party": "_Test Customer",
-    "credit_in_account_currency": 0.0,
-    "debit_in_account_currency": 400.0,
-    "doctype": "Journal Entry Account",
-    "parentfield": "accounts",
-    "cost_center": "_Test Cost Center - _TC"
-   },
-   {
-    "account": "Sales - _TC",
-    "cost_center": "_Test Cost Center - _TC",
-    "credit_in_account_currency": 400.0,
-    "debit_in_account_currency": 0.0,
-    "doctype": "Journal Entry Account",
-    "parentfield": "accounts",
-    "cost_center": "_Test Cost Center - _TC"
-   }
-  ],
-  "naming_series": "_T-Journal Entry-",
-  "posting_date": "2013-02-14",
-  "user_remark": "test",
-  "voucher_type": "Bank Entry"
- }
+	{
+		"cheque_date": "2013-03-14",
+		"cheque_no": "33",
+		"company": "_Test Company",
+		"doctype": "Journal Entry",
+		"accounts": [
+			{
+				"account": "Debtors - _TC",
+				"party_type": "Customer",
+				"party": "_Test Customer",
+				"credit_in_account_currency": 400.0,
+				"debit_in_account_currency": 0.0,
+				"doctype": "Journal Entry Account",
+				"parentfield": "accounts",
+				"cost_center": "_Test Cost Center - _TC"
+			},
+			{
+				"account": "_Test Bank - _TC",
+				"credit_in_account_currency": 0.0,
+				"debit_in_account_currency": 400.0,
+				"doctype": "Journal Entry Account",
+				"parentfield": "accounts",
+				"cost_center": "_Test Cost Center - _TC"
+			}
+		],
+		"naming_series": "_T-Journal Entry-",
+		"posting_date": "2013-02-14",
+		"user_remark": "test",
+		"voucher_type": "Bank Entry"
+	},
+
+	{
+		"cheque_date": "2013-02-14",
+		"cheque_no": "33",
+		"company": "_Test Company",
+		"doctype": "Journal Entry",
+		"accounts": [
+			{
+				"account": "_Test Payable - _TC",
+				"party_type": "Supplier",
+				"party": "_Test Supplier",
+				"credit_in_account_currency": 0.0,
+				"debit_in_account_currency": 400.0,
+				"doctype": "Journal Entry Account",
+				"parentfield": "accounts",
+				"cost_center": "_Test Cost Center - _TC"
+			},
+			{
+				"account": "_Test Bank - _TC",
+				"credit_in_account_currency": 400.0,
+				"debit_in_account_currency": 0.0,
+				"doctype": "Journal Entry Account",
+				"parentfield": "accounts",
+				"cost_center": "_Test Cost Center - _TC"
+			}
+		],
+		"naming_series": "_T-Journal Entry-",
+		"posting_date": "2013-02-14",
+		"user_remark": "test",
+		"voucher_type": "Bank Entry"
+	},
+
+	{
+		"cheque_date": "2013-02-14",
+		"cheque_no": "33",
+		"company": "_Test Company",
+		"doctype": "Journal Entry",
+		"accounts": [
+			{
+				"account": "Debtors - _TC",
+				"party_type": "Customer",
+				"party": "_Test Customer",
+				"credit_in_account_currency": 0.0,
+				"debit_in_account_currency": 400.0,
+				"doctype": "Journal Entry Account",
+				"parentfield": "accounts",
+				"cost_center": "_Test Cost Center - _TC"
+			},
+			{
+				"account": "Sales - _TC",
+				"credit_in_account_currency": 400.0,
+				"debit_in_account_currency": 0.0,
+				"doctype": "Journal Entry Account",
+				"parentfield": "accounts",
+				"cost_center": "_Test Cost Center - _TC"
+			}
+		],
+		"naming_series": "_T-Journal Entry-",
+		"posting_date": "2013-02-14",
+		"user_remark": "test",
+		"voucher_type": "Bank Entry"
+	}
 ]
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index cebd61a..215d8ec 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -163,6 +163,18 @@
 					}
 				})
 			}, __("Get Items From"));
+
+			if (!this.frm.doc.is_return) {
+				frappe.db.get_single_value("Buying Settings", "maintain_same_rate").then((value) => {
+					if (value) {
+						this.frm.doc.items.forEach((item) => {
+							this.frm.fields_dict.items.grid.update_docfield_property(
+								"rate", "read_only", (item.purchase_receipt && item.pr_detail)
+							);
+						});
+					}
+				});
+			}
 		}
 		this.frm.toggle_reqd("supplier_warehouse", this.frm.doc.is_subcontracted);
 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 931b48d..f40824d 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -1858,10 +1858,6 @@
 	return make_inter_company_transaction("Purchase Invoice", source_name, target_doc)
 
 
-def on_doctype_update():
-	frappe.db.add_index("Purchase Invoice", ["supplier", "is_return", "return_against"])
-
-
 @frappe.whitelist()
 def make_purchase_receipt(source_name, target_doc=None):
 	def update_item(obj, target, source_parent):
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index 7cad3ae..9cf4e4f 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -288,7 +288,6 @@
    "oldfieldname": "import_rate",
    "oldfieldtype": "Currency",
    "options": "currency",
-   "read_only_depends_on": "eval: (!parent.is_return && doc.purchase_receipt && doc.pr_detail)",
    "reqd": 1
   },
   {
@@ -919,7 +918,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-11-30 16:26:05.629780",
+ "modified": "2023-12-25 22:00:28.043555",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index c0228e6..2cddb86 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -2575,10 +2575,6 @@
 		return lp_details
 
 
-def on_doctype_update():
-	frappe.db.add_index("Sales Invoice", ["customer", "is_return", "return_against"])
-
-
 @frappe.whitelist()
 def create_invoice_discounting(source_name, target_doc=None):
 	invoice = frappe.get_doc("Sales Invoice", source_name)
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index b45ff60..4054dca 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -200,7 +200,7 @@
 		"""
 		select
 			name as gl_entry, posting_date, account, party_type, party,
-			voucher_type, voucher_no, {dimension_fields}
+			voucher_type, voucher_subtype, voucher_no, {dimension_fields}
 			cost_center, project, {transaction_currency_fields}
 			against_voucher_type, against_voucher, account_currency,
 			against_link, against, is_opening, creation {select_fields}
@@ -610,6 +610,12 @@
 	columns += [
 		{"label": _("Voucher Type"), "fieldname": "voucher_type", "width": 120},
 		{
+			"label": _("Voucher Subtype"),
+			"fieldname": "voucher_subtype",
+			"fieldtype": "Data",
+			"width": 180,
+		},
+		{
 			"label": _("Voucher No"),
 			"fieldname": "voucher_no",
 			"fieldtype": "Dynamic Link",
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index 540a4f5..ac712d4 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -35,6 +35,8 @@
   "purchase_receipt",
   "purchase_invoice",
   "available_for_use_date",
+  "total_asset_cost",
+  "additional_asset_cost",
   "column_break_23",
   "gross_purchase_amount",
   "asset_quantity",
@@ -529,6 +531,22 @@
    "label": "Capitalized In",
    "options": "Asset Capitalization",
    "read_only": 1
+  },
+  {
+   "depends_on": "eval:doc.docstatus > 0",
+   "fieldname": "total_asset_cost",
+   "fieldtype": "Currency",
+   "label": "Total Asset Cost",
+   "options": "Company:company:default_currency",
+   "read_only": 1
+  },
+  {
+   "depends_on": "eval:doc.docstatus > 0",
+   "fieldname": "additional_asset_cost",
+   "fieldtype": "Currency",
+   "label": "Additional Asset Cost",
+   "options": "Company:company:default_currency",
+   "read_only": 1
   }
  ],
  "idx": 72,
@@ -572,7 +590,7 @@
    "link_fieldname": "target_asset"
   }
  ],
- "modified": "2023-11-20 20:57:37.010467",
+ "modified": "2023-12-21 16:46:20.732869",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset",
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 3b3ed0a..dd34189 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -50,6 +50,7 @@
 
 		from erpnext.assets.doctype.asset_finance_book.asset_finance_book import AssetFinanceBook
 
+		additional_asset_cost: DF.Currency
 		amended_from: DF.Link | None
 		asset_category: DF.Link | None
 		asset_name: DF.Data
@@ -111,6 +112,7 @@
 			"Decapitalized",
 		]
 		supplier: DF.Link | None
+		total_asset_cost: DF.Currency
 		total_number_of_depreciations: DF.Int
 		value_after_depreciation: DF.Currency
 	# end: auto-generated types
@@ -144,6 +146,7 @@
 							).format(asset_depr_schedules_links)
 						)
 
+		self.total_asset_cost = self.gross_purchase_amount
 		self.status = self.get_status()
 
 	def on_submit(self):
diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py
index 31dd63d..bb627d4 100644
--- a/erpnext/assets/doctype/asset_repair/asset_repair.py
+++ b/erpnext/assets/doctype/asset_repair/asset_repair.py
@@ -93,6 +93,10 @@
 
 			self.increase_asset_value()
 
+			if self.capitalize_repair_cost:
+				self.asset_doc.total_asset_cost += self.repair_cost
+				self.asset_doc.additional_asset_cost += self.repair_cost
+
 			if self.get("stock_consumption"):
 				self.check_for_stock_items_and_warehouse()
 				self.decrease_stock_quantity()
@@ -128,6 +132,10 @@
 
 			self.decrease_asset_value()
 
+			if self.capitalize_repair_cost:
+				self.asset_doc.total_asset_cost -= self.repair_cost
+				self.asset_doc.additional_asset_cost -= self.repair_cost
+
 			if self.get("stock_consumption"):
 				self.increase_stock_quantity()
 			if self.get("capitalize_repair_cost"):
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index 98c1b38..5a24cc2 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -123,8 +123,7 @@
    "oldfieldname": "item_code",
    "oldfieldtype": "Link",
    "options": "Item",
-   "reqd": 1,
-   "search_index": 1
+   "reqd": 1
   },
   {
    "fieldname": "supplier_part_no",
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index d88424b..febad18 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -874,6 +874,7 @@
 				"project": self.get("project"),
 				"post_net_value": args.get("post_net_value"),
 				"voucher_detail_no": args.get("voucher_detail_no"),
+				"voucher_subtype": self.get_voucher_subtype(),
 			}
 		)
 
@@ -929,6 +930,25 @@
 
 		return gl_dict
 
+	def get_voucher_subtype(self):
+		voucher_subtypes = {
+			"Journal Entry": "voucher_type",
+			"Payment Entry": "payment_type",
+			"Stock Entry": "stock_entry_type",
+			"Asset Capitalization": "entry_type",
+		}
+		if self.doctype in voucher_subtypes:
+			return self.get(voucher_subtypes[self.doctype])
+		elif self.doctype == "Purchase Receipt" and self.is_return:
+			return "Purchase Return"
+		elif self.doctype == "Delivery Note" and self.is_return:
+			return "Sales Return"
+		elif (self.doctype == "Sales Invoice" and self.is_return) or self.doctype == "Purchase Invoice":
+			return "Credit Note"
+		elif (self.doctype == "Purchase Invoice" and self.is_return) or self.doctype == "Sales Invoice":
+			return "Debit Note"
+		return self.doctype
+
 	def get_value_in_transaction_currency(self, account_currency, args, field):
 		if account_currency == self.get("currency"):
 			return args.get(field + "_in_account_currency")
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 63dca63..2650753 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -896,3 +896,31 @@
 			as_list=1,
 		)
 	return terms
+
+
+@frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
+def get_filtered_child_rows(doctype, txt, searchfield, start, page_len, filters) -> list:
+	table = frappe.qb.DocType(doctype)
+	query = (
+		frappe.qb.from_(table)
+		.select(
+			table.name,
+			Concat("#", table.idx, ", ", table.item_code),
+		)
+		.orderby(table.idx)
+		.offset(start)
+		.limit(page_len)
+	)
+
+	if filters:
+		for field, value in filters.items():
+			query = query.where(table[field] == value)
+
+	if txt:
+		txt += "%"
+		query = query.where(
+			((table.idx.like(txt.replace("#", ""))) | (table.item_code.like(txt))) | (table.name.like(txt))
+		)
+
+	return query.run(as_dict=False)
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 4489d60..919e459 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -438,7 +438,9 @@
 				# Get incoming rate based on original item cost based on valuation method
 				qty = flt(d.get("stock_qty") or d.get("actual_qty"))
 
-				if not d.incoming_rate:
+				if not d.incoming_rate or (
+					get_valuation_method(d.item_code) == "Moving Average" and self.get("is_return")
+				):
 					d.incoming_rate = get_incoming_rate(
 						{
 							"item_code": d.item_code,
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index f0381d2..d86b6d4 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -744,6 +744,9 @@
 		base_total_rm_cost = 0
 
 		for d in self.get("items"):
+			if not d.is_stock_item and self.rm_cost_as_per == "Valuation Rate":
+				continue
+
 			old_rate = d.rate
 			if self.rm_cost_as_per != "Manual":
 				d.rate = self.get_rm_rate(
@@ -1017,6 +1020,8 @@
 		item_doc = frappe.get_cached_doc("Item", args.get("item_code"))
 		price_list_data = get_price_list_rate(bom_args, item_doc)
 		rate = price_list_data.price_list_rate
+	elif bom_doc.rm_cost_as_per == "Manual":
+		return
 
 	return flt(rate)
 
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index 051b475..2debf91 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -698,6 +698,35 @@
 		bom.update_cost()
 		self.assertFalse(bom.flags.cost_updated)
 
+	def test_bom_with_service_item_cost(self):
+		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
+
+		rm_item = make_item(properties={"is_stock_item": 1, "valuation_rate": 1000.0}).name
+
+		service_item = make_item(properties={"is_stock_item": 0}).name
+
+		fg_item = make_item(properties={"is_stock_item": 1}).name
+
+		from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
+
+		bom = make_bom(item=fg_item, raw_materials=[rm_item, service_item], do_not_save=True)
+		bom.rm_cost_as_per = "Valuation Rate"
+
+		for row in bom.items:
+			if row.item_code == service_item:
+				row.rate = 566.00
+			else:
+				row.rate = 800.00
+
+		bom.save()
+
+		for row in bom.items:
+			if row.item_code == service_item:
+				self.assertEqual(row.is_stock_item, 0)
+				self.assertEqual(row.rate, 566.00)
+			else:
+				self.assertEqual(row.is_stock_item, 1)
+
 	def test_do_not_include_manufacturing_and_fixed_items(self):
 		from erpnext.manufacturing.doctype.bom.bom import item_query
 
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index cb58af1..dfd6612 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -14,6 +14,7 @@
   "bom_no",
   "source_warehouse",
   "allow_alternative_item",
+  "is_stock_item",
   "section_break_5",
   "description",
   "col_break1",
@@ -185,7 +186,7 @@
    "in_list_view": 1,
    "label": "Rate",
    "options": "currency",
-   "read_only": 1,
+   "read_only_depends_on": "eval:doc.is_stock_item == 1",
    "reqd": 1
   },
   {
@@ -284,13 +285,21 @@
    "fieldname": "do_not_explode",
    "fieldtype": "Check",
    "label": "Do Not Explode"
+  },
+  {
+   "default": "0",
+   "fetch_from": "item_code.is_stock_item",
+   "fieldname": "is_stock_item",
+   "fieldtype": "Check",
+   "label": "Is Stock Item",
+   "read_only": 1
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-11-14 18:35:51.378513",
+ "modified": "2023-12-20 16:21:55.477883",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "BOM Item",
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 56f6347..7ade21d 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -352,6 +352,8 @@
 erpnext.patches.v14_0.update_zero_asset_quantity_field
 execute:frappe.db.set_single_value("Buying Settings", "project_update_frequency", "Each Transaction")
 execute:frappe.db.set_default("date_format", frappe.db.get_single_value("System Settings", "date_format"))
+erpnext.patches.v14_0.update_total_asset_cost_field
 # below migration patch should always run last
 erpnext.patches.v14_0.migrate_gl_to_payment_ledger
-erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index
+erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index # 2023-12-20
+erpnext.patches.v14_0.set_maintain_stock_for_bom_item
diff --git a/erpnext/patches/v14_0/set_maintain_stock_for_bom_item.py b/erpnext/patches/v14_0/set_maintain_stock_for_bom_item.py
new file mode 100644
index 0000000..f0b618f
--- /dev/null
+++ b/erpnext/patches/v14_0/set_maintain_stock_for_bom_item.py
@@ -0,0 +1,19 @@
+import frappe
+
+
+def execute():
+	if not frappe.db.exists("BOM", {"docstatus": 1}):
+		return
+
+	# Added is_stock_item to handle Read Only based on condition for the rate field
+	frappe.db.sql(
+		"""
+		UPDATE
+			`tabBOM Item` boi,
+			`tabItem` i
+		SET
+			boi.is_stock_item = i.is_stock_item
+		WHERE
+			boi.item_code = i.name
+	"""
+	)
diff --git a/erpnext/patches/v14_0/update_total_asset_cost_field.py b/erpnext/patches/v14_0/update_total_asset_cost_field.py
new file mode 100644
index 0000000..57cf71b
--- /dev/null
+++ b/erpnext/patches/v14_0/update_total_asset_cost_field.py
@@ -0,0 +1,17 @@
+import frappe
+
+
+def execute():
+	asset = frappe.qb.DocType("Asset")
+	frappe.qb.update(asset).set(asset.total_asset_cost, asset.gross_purchase_amount).run()
+
+	asset_repair_list = frappe.db.get_all(
+		"Asset Repair",
+		filters={"docstatus": 1, "repair_status": "Completed", "capitalize_repair_cost": 1},
+		fields=["asset", "repair_cost"],
+	)
+
+	for asset_repair in asset_repair_list:
+		frappe.qb.update(asset).set(
+			asset.total_asset_cost, asset.total_asset_cost + asset_repair.repair_cost
+		).where(asset.name == asset_repair.asset).run()
diff --git a/erpnext/public/js/utils/sales_common.js b/erpnext/public/js/utils/sales_common.js
index 084cca7..b92b02e 100644
--- a/erpnext/public/js/utils/sales_common.js
+++ b/erpnext/public/js/utils/sales_common.js
@@ -184,6 +184,12 @@
 				refresh_field("incentives",row.name,row.parentfield);
 			}
 
+			warehouse(doc, cdt, cdn) {
+				if (doc.docstatus === 0 && doc.is_return && !doc.return_against) {
+					frappe.model.set_value(cdt, cdn, "incoming_rate", 0.0);
+				}
+			}
+
 			toggle_editable_price_list_rate() {
 				var df = frappe.meta.get_docfield(this.frm.doc.doctype + " Item", "price_list_rate", this.frm.doc.name);
 				var editable_price_list_rate = cint(frappe.defaults.get_default("editable_price_list_rate"));
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 97b214e..b206e3f 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -182,7 +182,7 @@
 	create_stock_reservation_entries(frm) {
 		const dialog = new frappe.ui.Dialog({
 			title: __("Stock Reservation"),
-			size: "large",
+			size: "extra-large",
 			fields: [
 				{
 					fieldname: "set_warehouse",
@@ -207,6 +207,50 @@
 					},
 				},
 				{fieldtype: "Column Break"},
+				{
+					fieldname: "add_item",
+					fieldtype: "Link",
+					label: __("Add Item"),
+					options: "Sales Order Item",
+					get_query: () => {
+						return {
+							query: "erpnext.controllers.queries.get_filtered_child_rows",
+							filters: {
+								"parenttype": frm.doc.doctype,
+								"parent": frm.doc.name,
+								"reserve_stock": 1,
+							}
+						}
+					},
+					onchange: () => {
+						let sales_order_item = dialog.get_value("add_item");
+
+						if (sales_order_item) {
+							frm.doc.items.forEach(item => {
+								if (item.name === sales_order_item) {
+									let unreserved_qty = (flt(item.stock_qty) - (item.stock_reserved_qty ? flt(item.stock_reserved_qty) : (flt(item.delivered_qty) * flt(item.conversion_factor)))) / flt(item.conversion_factor);
+
+									if (unreserved_qty > 0) {
+										dialog.fields_dict.items.df.data.forEach((row) => {
+											if (row.sales_order_item === sales_order_item) {
+												unreserved_qty -= row.qty_to_reserve;
+											}
+										});
+									}
+
+									dialog.fields_dict.items.df.data.push({
+										'sales_order_item': item.name,
+										'item_code': item.item_code,
+										'warehouse': dialog.get_value("set_warehouse") || item.warehouse,
+										'qty_to_reserve': Math.max(unreserved_qty, 0)
+									});
+									dialog.fields_dict.items.grid.refresh();
+									dialog.set_value("add_item", undefined);
+								}
+							});
+						}
+					},
+				},
 				{fieldtype: "Section Break"},
 				{
 					fieldname: "items",
@@ -218,10 +262,34 @@
 					fields: [
 						{
 							fieldname: "sales_order_item",
-							fieldtype: "Data",
+							fieldtype: "Link",
 							label: __("Sales Order Item"),
+							options: "Sales Order Item",
 							reqd: 1,
-							read_only: 1,
+							in_list_view: 1,
+							get_query: () => {
+								return {
+									query: "erpnext.controllers.queries.get_filtered_child_rows",
+									filters: {
+										"parenttype": frm.doc.doctype,
+										"parent": frm.doc.name,
+										"reserve_stock": 1,
+									}
+								}
+							},
+							onchange: (event) => {
+								if (event) {
+									let name = $(event.currentTarget).closest(".grid-row").attr("data-name");
+									let item_row = dialog.fields_dict.items.grid.grid_rows_by_docname[name].doc;
+
+									frm.doc.items.forEach(item => {
+										if (item.name === item_row.sales_order_item) {
+											item_row.item_code = item.item_code;
+										}
+									});
+									dialog.fields_dict.items.grid.refresh();
+								}
+							}
 						},
 						{
 							fieldname: "item_code",
@@ -284,14 +352,14 @@
 
 		frm.doc.items.forEach(item => {
 			if (item.reserve_stock) {
-				let unreserved_qty = (flt(item.stock_qty) - (item.stock_reserved_qty ? flt(item.stock_reserved_qty) : (flt(item.delivered_qty) * flt(item.conversion_factor))))
+				let unreserved_qty = (flt(item.stock_qty) - (item.stock_reserved_qty ? flt(item.stock_reserved_qty) : (flt(item.delivered_qty) * flt(item.conversion_factor)))) / flt(item.conversion_factor);
 
 				if (unreserved_qty > 0) {
 					dialog.fields_dict.items.df.data.push({
 						'sales_order_item': item.name,
 						'item_code': item.item_code,
 						'warehouse': item.warehouse,
-						'qty_to_reserve': (unreserved_qty / flt(item.conversion_factor))
+						'qty_to_reserve': unreserved_qty
 					});
 				}
 			}
diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js
index 193048f..bd85792 100644
--- a/erpnext/selling/page/point_of_sale/pos_item_cart.js
+++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js
@@ -520,7 +520,7 @@
 	}
 
 	render_taxes(taxes) {
-		if (taxes.length) {
+		if (taxes && taxes.length) {
 			const currency = this.events.get_frm().doc.currency;
 			const taxes_html = taxes.map(t => {
 				if (t.tax_amount_after_discount_amount == 0.0) return;
diff --git a/erpnext/setup/demo_data/journal_entry.json b/erpnext/setup/demo_data/journal_entry.json
index b751c7c..a681be4 100644
--- a/erpnext/setup/demo_data/journal_entry.json
+++ b/erpnext/setup/demo_data/journal_entry.json
@@ -4,22 +4,22 @@
         "cheque_no": "33",
         "doctype": "Journal Entry",
         "accounts": [
-         {
-          "party_type": "Customer",
-          "party": "ABC Enterprises",
-          "credit_in_account_currency": 40000.0,
-          "debit_in_account_currency": 0.0,
-          "doctype": "Journal Entry Account",
-          "parentfield": "accounts",
-         },
-         {
-          "credit_in_account_currency": 0.0,
-          "debit_in_account_currency": 40000.0,
-          "doctype": "Journal Entry Account",
-          "parentfield": "accounts",
-         }
+            {
+                "party_type": "Customer",
+                "party": "ABC Enterprises",
+                "credit_in_account_currency": 40000.0,
+                "debit_in_account_currency": 0.0,
+                "doctype": "Journal Entry Account",
+                "parentfield": "accounts"
+            },
+            {
+                "credit_in_account_currency": 0.0,
+                "debit_in_account_currency": 40000.0,
+                "doctype": "Journal Entry Account",
+                "parentfield": "accounts"
+            }
         ],
         "user_remark": "test",
         "voucher_type": "Bank Entry"
     }
-]
\ No newline at end of file
+]
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 0e8ee2d..9897847 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -274,7 +274,7 @@
 						"parent_warehouse": "{0} - {1}".format(_("All Warehouses"), self.abbr)
 						if not wh_detail["is_group"]
 						else "",
-						"warehouse_type": wh_detail["warehouse_type"] if "warehouse_type" in wh_detail else None,
+						"warehouse_type": wh_detail.get("warehouse_type"),
 					}
 				)
 				warehouse.flags.ignore_permissions = True
diff --git a/erpnext/stock/doctype/bin/bin.json b/erpnext/stock/doctype/bin/bin.json
index 312470d..10d9511 100644
--- a/erpnext/stock/doctype/bin/bin.json
+++ b/erpnext/stock/doctype/bin/bin.json
@@ -52,8 +52,7 @@
    "oldfieldtype": "Link",
    "options": "Item",
    "read_only": 1,
-   "reqd": 1,
-   "search_index": 1
+   "reqd": 1
   },
   {
    "default": "0.00",
diff --git a/erpnext/stock/doctype/delivery_note/patches/drop_unused_return_against_index.py b/erpnext/stock/doctype/delivery_note/patches/drop_unused_return_against_index.py
index 8fe4ffb..cc29e67 100644
--- a/erpnext/stock/doctype/delivery_note/patches/drop_unused_return_against_index.py
+++ b/erpnext/stock/doctype/delivery_note/patches/drop_unused_return_against_index.py
@@ -1,15 +1,27 @@
+import click
 import frappe
 
+UNUSED_INDEXES = [
+	("Delivery Note", ["customer", "is_return", "return_against"]),
+	("Sales Invoice", ["customer", "is_return", "return_against"]),
+	("Purchase Invoice", ["supplier", "is_return", "return_against"]),
+	("Purchase Receipt", ["supplier", "is_return", "return_against"]),
+]
+
 
 def execute():
-	"""Drop unused return_against index"""
+	for doctype, index_fields in UNUSED_INDEXES:
+		table = f"tab{doctype}"
+		index_name = frappe.db.get_index_name(index_fields)
+		drop_index_if_exists(table, index_name)
+
+
+def drop_index_if_exists(table: str, index: str):
+	if not frappe.db.has_index(table, index):
+		return
 
 	try:
-		frappe.db.sql_ddl(
-			"ALTER TABLE `tabDelivery Note` DROP INDEX `customer_is_return_return_against_index`"
-		)
-		frappe.db.sql_ddl(
-			"ALTER TABLE `tabPurchase Receipt` DROP INDEX `supplier_is_return_return_against_index`"
-		)
+		frappe.db.sql_ddl(f"ALTER TABLE `{table}` DROP INDEX `{index}`")
+		click.echo(f"✓ dropped {index} index from {table}")
 	except Exception:
-		frappe.log_error("Failed to drop unused index")
+		frappe.log_error("Failed to drop index")
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index da8ee02..933be53 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -1425,6 +1425,59 @@
 
 		self.assertAlmostEqual(dn1.items[0].incoming_rate, 250.0)
 
+	def test_sales_return_valuation_for_moving_average_case2(self):
+		# Make DN return
+		# Make Bakcdated Purchase Receipt and check DN return valuation rate
+		# The rate should be recalculate based on the backdated purchase receipt
+		frappe.flags.print_debug_messages = False
+		item_code = make_item(
+			"_Test Item Sales Return with MA Case2",
+			{"is_stock_item": 1, "valuation_method": "Moving Average", "stock_uom": "Nos"},
+		).name
+
+		make_stock_entry(
+			item_code=item_code,
+			target="_Test Warehouse - _TC",
+			qty=5,
+			basic_rate=100.0,
+			posting_date=add_days(nowdate(), -5),
+		)
+
+		dn = create_delivery_note(
+			item_code=item_code,
+			warehouse="_Test Warehouse - _TC",
+			qty=5,
+			rate=500,
+			posting_date=add_days(nowdate(), -4),
+		)
+
+		returned_dn = create_delivery_note(
+			is_return=1,
+			item_code=item_code,
+			return_against=dn.name,
+			qty=-5,
+			rate=500,
+			company=dn.company,
+			warehouse="_Test Warehouse - _TC",
+			expense_account="Cost of Goods Sold - _TC",
+			cost_center="Main - _TC",
+			posting_date=add_days(nowdate(), -1),
+		)
+
+		self.assertAlmostEqual(returned_dn.items[0].incoming_rate, 100.0)
+
+		# Make backdated purchase receipt
+		make_stock_entry(
+			item_code=item_code,
+			target="_Test Warehouse - _TC",
+			qty=5,
+			basic_rate=200.0,
+			posting_date=add_days(nowdate(), -3),
+		)
+
+		returned_dn.reload()
+		self.assertAlmostEqual(returned_dn.items[0].incoming_rate, 200.0)
+
 
 def create_delivery_note(**args):
 	dn = frappe.new_doc("Delivery Note")
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 6c9d339..2cbccb0 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -88,6 +88,20 @@
 			}, __('Create'));
 		}
 
+		if (frm.doc.docstatus === 0) {
+			if (!frm.doc.is_return) {
+				frappe.db.get_single_value("Buying Settings", "maintain_same_rate").then((value) => {
+					if (value) {
+						frm.doc.items.forEach((item) => {
+							frm.fields_dict.items.grid.update_docfield_property(
+								"rate", "read_only", (item.purchase_order && item.purchase_order_item)
+							);
+						});
+					}
+				});
+			}
+		}
+
 		frm.events.add_custom_buttons(frm);
 	},
 
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 7344d2a..9bd692a 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -359,7 +359,6 @@
    "oldfieldtype": "Currency",
    "options": "currency",
    "print_width": "100px",
-   "read_only_depends_on": "eval: (!parent.is_return && doc.purchase_order && doc.purchase_order_item)",
    "width": "100px"
   },
   {
@@ -1104,7 +1103,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-11-30 16:12:02.364608",
+ "modified": "2023-12-25 22:32:09.801965",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 7af5d1a..8da3e8f 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -512,7 +512,12 @@
 				},
 				callback: function(r) {
 					if (!r.exc) {
-						["actual_qty", "basic_rate"].forEach((field) => {
+						let fields = ["actual_qty", "basic_rate"];
+						if (frm.doc.purpose == "Material Receipt") {
+							fields = ["actual_qty"];
+						}
+
+						fields.forEach((field) => {
 							frappe.model.set_value(cdt, cdn, field, (r.message[field] || 0.0));
 						});
 						frm.events.calculate_basic_amount(frm, child);
diff --git a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
index 24650fd..7e03ac3 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
+++ b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
@@ -9,7 +9,7 @@
 from frappe.query_builder.functions import Sum
 from frappe.utils import cint, flt
 
-from erpnext.stock.utils import get_or_make_bin
+from erpnext.stock.utils import get_or_make_bin, get_stock_balance
 
 
 class StockReservationEntry(Document):
@@ -151,7 +151,7 @@
 		"""Validates `Reserved Qty` when `Reservation Based On` is `Qty`."""
 
 		if self.reservation_based_on == "Qty":
-			self.validate_with_max_reserved_qty(self.reserved_qty)
+			self.validate_with_allowed_qty(self.reserved_qty)
 
 	def auto_reserve_serial_and_batch(self, based_on: str = None) -> None:
 		"""Auto pick Serial and Batch Nos to reserve when `Reservation Based On` is `Serial and Batch`."""
@@ -324,7 +324,7 @@
 				frappe.throw(msg)
 
 			# Should be called after validating Serial and Batch Nos.
-			self.validate_with_max_reserved_qty(qty_to_be_reserved)
+			self.validate_with_allowed_qty(qty_to_be_reserved)
 			self.db_set("reserved_qty", qty_to_be_reserved)
 
 	def update_reserved_qty_in_voucher(
@@ -429,7 +429,7 @@
 			msg = _("Stock Reservation Entry cannot be updated as it has been delivered.")
 			frappe.throw(msg)
 
-	def validate_with_max_reserved_qty(self, qty_to_be_reserved: float) -> None:
+	def validate_with_allowed_qty(self, qty_to_be_reserved: float) -> None:
 		"""Validates `Reserved Qty` with `Max Reserved Qty`."""
 
 		self.db_set(
@@ -448,12 +448,12 @@
 			)
 			voucher_delivered_qty = flt(delivered_qty) * flt(conversion_factor)
 
-		max_reserved_qty = min(
+		allowed_qty = min(
 			self.available_qty, (self.voucher_qty - voucher_delivered_qty - total_reserved_qty)
 		)
 
-		if max_reserved_qty <= 0 and self.voucher_type == "Sales Order":
-			msg = _("Item {0} is already delivered for Sales Order {1}.").format(
+		if self.get("_action") != "submit" and self.voucher_type == "Sales Order" and allowed_qty <= 0:
+			msg = _("Item {0} is already reserved/delivered against Sales Order {1}.").format(
 				frappe.bold(self.item_code), frappe.bold(self.voucher_no)
 			)
 
@@ -463,19 +463,33 @@
 			else:
 				frappe.throw(msg)
 
-		if qty_to_be_reserved > max_reserved_qty:
+		if qty_to_be_reserved > allowed_qty:
+			actual_qty = get_stock_balance(self.item_code, self.warehouse)
 			msg = """
-				Cannot reserve more than Max Reserved Qty {0} {1}.<br /><br />
-				The <b>Max Reserved Qty</b> is calculated as follows:<br />
+				Cannot reserve more than Allowed Qty {0} {1} for Item {2} against {3} {4}.<br /><br />
+				The <b>Allowed Qty</b> is calculated as follows:<br />
 				<ul>
-					<li><b>Available Qty To Reserve</b> = (Actual Stock Qty - Reserved Stock Qty)</li>
-					<li><b>Voucher Qty</b> = Voucher Item Qty</li>
-					<li><b>Delivered Qty</b> = Qty delivered against the Voucher Item</li>
-					<li><b>Total Reserved Qty</b> = Qty reserved against the Voucher Item</li>
-					<li><b>Max Reserved Qty</b> = Minimum of (Available Qty To Reserve, (Voucher Qty - Delivered Qty - Total Reserved Qty))</li>
+					<li>Actual Qty [Available Qty at Warehouse] = {5}</li>
+					<li>Reserved Stock [Ignore current SRE] = {6}</li>
+					<li>Available Qty To Reserve [Actual Qty - Reserved Stock] = {7}</li>
+					<li>Voucher Qty [Voucher Item Qty] = {8}</li>
+					<li>Delivered Qty [Qty delivered against the Voucher Item] = {9}</li>
+					<li>Total Reserved Qty [Qty reserved against the Voucher Item] = {10}</li>
+					<li>Allowed Qty [Minimum of (Available Qty To Reserve, (Voucher Qty - Delivered Qty - Total Reserved Qty))] = {11}</li>
 				</ul>
 			""".format(
-				frappe.bold(max_reserved_qty), self.stock_uom
+				frappe.bold(allowed_qty),
+				self.stock_uom,
+				frappe.bold(self.item_code),
+				self.voucher_type,
+				frappe.bold(self.voucher_no),
+				actual_qty,
+				actual_qty - self.available_qty,
+				self.available_qty,
+				self.voucher_qty,
+				voucher_delivered_qty,
+				total_reserved_qty,
+				allowed_qty,
 			)
 			frappe.throw(msg)
 
@@ -509,7 +523,6 @@
 	"""Returns `Available Qty to Reserve (Actual Qty - Reserved Qty)` for Item, Warehouse and Batch combination."""
 
 	from erpnext.stock.doctype.batch.batch import get_batch_qty
-	from erpnext.stock.utils import get_stock_balance
 
 	if batch_no:
 		return get_batch_qty(
diff --git a/erpnext/stock/report/reserved_stock/reserved_stock.js b/erpnext/stock/report/reserved_stock/reserved_stock.js
index 6872741..2b075e2 100644
--- a/erpnext/stock/report/reserved_stock/reserved_stock.js
+++ b/erpnext/stock/report/reserved_stock/reserved_stock.js
@@ -149,34 +149,36 @@
 	formatter: (value, row, column, data, default_formatter) => {
 		value = default_formatter(value, row, column, data);
 
-		if (column.fieldname == "status") {
-			switch (data.status) {
-				case "Partially Reserved":
-					value = "<span style='color:orange'>" + value + "</span>";
-					break;
-				case "Reserved":
-					value = "<span style='color:blue'>" + value + "</span>";
-					break;
-				case "Partially Delivered":
-					value = "<span style='color:purple'>" + value + "</span>";
-					break;
-				case "Delivered":
-					value = "<span style='color:green'>" + value + "</span>";
-					break;
+		if (data) {
+			if (column.fieldname == "status") {
+				switch (data.status) {
+					case "Partially Reserved":
+						value = "<span style='color:orange'>" + value + "</span>";
+						break;
+					case "Reserved":
+						value = "<span style='color:blue'>" + value + "</span>";
+						break;
+					case "Partially Delivered":
+						value = "<span style='color:purple'>" + value + "</span>";
+						break;
+					case "Delivered":
+						value = "<span style='color:green'>" + value + "</span>";
+						break;
+				}
 			}
-		}
-		else if (column.fieldname == "delivered_qty") {
-			if (data.delivered_qty > 0) {
-				if (data.reserved_qty > data.delivered_qty) {
-					value = "<span style='color:blue'>" + value + "</span>";
+			else if (column.fieldname == "delivered_qty") {
+				if (data.delivered_qty > 0) {
+					if (data.reserved_qty > data.delivered_qty) {
+						value = "<span style='color:blue'>" + value + "</span>";
+					}
+					else {
+						value = "<span style='color:green'>" + value + "</span>";
+					}
 				}
 				else {
-					value = "<span style='color:green'>" + value + "</span>";
+					value = "<span style='color:red'>" + value + "</span>";
 				}
 			}
-			else {
-				value = "<span style='color:red'>" + value + "</span>";
-			}
 		}
 
 		return value;
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 9203f45..a6206ac 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -25,6 +25,7 @@
 )
 from erpnext.stock.utils import (
 	get_incoming_outgoing_rate_for_cancel,
+	get_incoming_rate,
 	get_or_make_bin,
 	get_stock_balance,
 	get_valuation_method,
@@ -841,14 +842,33 @@
 					get_rate_for_return,  # don't move this import to top
 				)
 
-				rate = get_rate_for_return(
-					sle.voucher_type,
-					sle.voucher_no,
-					sle.item_code,
-					voucher_detail_no=sle.voucher_detail_no,
-					sle=sle,
-				)
+				if self.valuation_method == "Moving Average":
+					rate = get_incoming_rate(
+						{
+							"item_code": sle.item_code,
+							"warehouse": sle.warehouse,
+							"posting_date": sle.posting_date,
+							"posting_time": sle.posting_time,
+							"qty": sle.actual_qty,
+							"serial_no": sle.get("serial_no"),
+							"batch_no": sle.get("batch_no"),
+							"serial_and_batch_bundle": sle.get("serial_and_batch_bundle"),
+							"company": sle.company,
+							"voucher_type": sle.voucher_type,
+							"voucher_no": sle.voucher_no,
+							"allow_zero_valuation": self.allow_zero_rate,
+							"sle": sle.name,
+						}
+					)
 
+				else:
+					rate = get_rate_for_return(
+						sle.voucher_type,
+						sle.voucher_no,
+						sle.item_code,
+						voucher_detail_no=sle.voucher_detail_no,
+						sle=sle,
+					)
 			elif (
 				sle.voucher_type in ["Purchase Receipt", "Purchase Invoice"]
 				and sle.voucher_detail_no
diff --git a/erpnext/tests/test_perf.py b/erpnext/tests/test_perf.py
new file mode 100644
index 0000000..fc17b1d
--- /dev/null
+++ b/erpnext/tests/test_perf.py
@@ -0,0 +1,24 @@
+import frappe
+from frappe.tests.utils import FrappeTestCase
+
+INDEXED_FIELDS = {
+	"Bin": ["item_code"],
+	"GL Entry": ["voucher_type", "against_voucher_type"],
+	"Purchase Order Item": ["item_code"],
+	"Stock Ledger Entry": ["warehouse"],
+}
+
+
+class TestPerformance(FrappeTestCase):
+	def test_ensure_indexes(self):
+		# These fields are not explicitly indexed BUT they are prefix in some
+		# other composite index. If those are removed this test should be
+		# updated accordingly.
+		for doctype, fields in INDEXED_FIELDS.items():
+			for field in fields:
+				self.assertTrue(
+					frappe.db.sql(
+						f"""SHOW INDEX FROM `tab{doctype}`
+						WHERE Column_name = "{field}" AND Seq_in_index = 1"""
+					)
+				)
diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv
index 2745d4d..d05d0d9 100644
--- a/erpnext/translations/de.csv
+++ b/erpnext/translations/de.csv
@@ -103,6 +103,7 @@
 Actual Qty {0} / Waiting Qty {1},Tatsächliche Menge {0} / Wartezeit {1},
 Actual Qty: Quantity available in the warehouse.,Tatsächliche Menge: Menge verfügbar im Lager.,
 Actual qty in stock,Tatsächliche Menge auf Lager,
+Actual Time (in Hours via Time Sheet), IST Zeit (in Stunden aus Zeiterfassung),
 Actual type tax cannot be included in Item rate in row {0},Tatsächliche Steuerart kann nicht im Artikelpreis in Zeile {0} beinhaltet sein,
 Add,Hinzufügen,
 Add / Edit Prices,Preise hinzufügen / bearbeiten,