fix: don't allow to make reposting entry for closing stock balance period
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
index d5fc710..27066b8 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
@@ -13,6 +13,7 @@
from rq.timeouts import JobTimeoutException
import erpnext
+from erpnext.accounts.general_ledger import validate_accounting_period
from erpnext.accounts.utils import get_future_stock_vouchers, repost_gle_for_stock_vouchers
from erpnext.stock.stock_ledger import (
get_affected_transactions,
@@ -44,11 +45,49 @@
self.validate_accounts_freeze()
def validate_period_closing_voucher(self):
+ # Period Closing Voucher
year_end_date = self.get_max_year_end_date(self.company)
if year_end_date and getdate(self.posting_date) <= getdate(year_end_date):
- msg = f"Due to period closing, you cannot repost item valuation before {year_end_date}"
+ date = frappe.format(year_end_date, "Date")
+ msg = f"Due to period closing, you cannot repost item valuation before {date}"
frappe.throw(_(msg))
+ # Accounting Period
+ if self.voucher_type:
+ validate_accounting_period(
+ [
+ frappe._dict(
+ {
+ "posting_date": self.posting_date,
+ "company": self.company,
+ "voucher_type": self.voucher_type,
+ }
+ )
+ ]
+ )
+
+ # Closing Stock Balance
+ closing_stock = self.get_closing_stock_balance()
+ if closing_stock and closing_stock[0].name:
+ name = get_link_to_form("Closing Stock Balance", closing_stock[0].name)
+ to_date = frappe.format(closing_stock[0].to_date, "Date")
+ msg = f"Due to closing stock balance {name}, you cannot repost item valuation before {to_date}"
+ frappe.throw(_(msg))
+
+ def get_closing_stock_balance(self):
+ filters = {
+ "company": self.company,
+ "status": "Completed",
+ "docstatus": 1,
+ "to_date": (">=", self.posting_date),
+ }
+
+ for field in ["warehouse", "item_code"]:
+ if self.get(field):
+ filters.update({field: ("in", ["", self.get(field)])})
+
+ return frappe.get_all("Closing Stock Balance", fields=["name", "to_date"], filters=filters)
+
@staticmethod
def get_max_year_end_date(company):
data = frappe.get_all(
diff --git a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
index 9c4d997..1853f45 100644
--- a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
@@ -392,3 +392,33 @@
pr.cancel()
self.assertTrue(pr.docstatus == 2)
self.assertTrue(frappe.db.exists("Repost Item Valuation", {"voucher_no": pr.name}))
+
+ def test_repost_item_valuation_for_closing_stock_balance(self):
+ from erpnext.stock.doctype.closing_stock_balance.closing_stock_balance import (
+ prepare_closing_stock_balance,
+ )
+
+ doc = frappe.new_doc("Closing Stock Balance")
+ doc.company = "_Test Company"
+ doc.from_date = today()
+ doc.to_date = today()
+ doc.submit()
+
+ prepare_closing_stock_balance(doc.name)
+ doc.load_from_db()
+ self.assertEqual(doc.docstatus, 1)
+ self.assertEqual(doc.status, "Completed")
+
+ riv = frappe.new_doc("Repost Item Valuation")
+ riv.update(
+ {
+ "item_code": "_Test Item",
+ "warehouse": "_Test Warehouse - _TC",
+ "based_on": "Item and Warehouse",
+ "posting_date": today(),
+ "posting_time": "00:01:00",
+ }
+ )
+
+ self.assertRaises(frappe.ValidationError, riv.save)
+ doc.cancel()