diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py index 93869ed6c042..07fadc0fac66 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py @@ -178,7 +178,145 @@ def test_period_closing_with_finance_book_entries(self): self.assertEqual(pcv_gle, expected_gle) +<<<<<<< HEAD def make_period_closing_voucher(self, submit=True): +======= + def test_gl_entries_restrictions(self): + frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'") + frappe.db.sql("delete from `tabPeriod Closing Voucher` where company='Test PCV Company'") + + company = create_company() + cost_center = create_cost_center("Test Cost Center 1") + + self.make_period_closing_voucher(posting_date="2021-03-31") + + jv1 = make_journal_entry( + posting_date="2021-03-15", + amount=400, + account1="Cash - TPC", + account2="Sales - TPC", + cost_center=cost_center, + save=False, + ) + jv1.company = company + jv1.save() + + self.assertRaises(frappe.ValidationError, jv1.submit) + + def test_closing_balance_with_dimensions_and_test_reposting_entry(self): + frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'") + frappe.db.sql("delete from `tabPeriod Closing Voucher` where company='Test PCV Company'") + frappe.db.sql("delete from `tabAccount Closing Balance` where company='Test PCV Company'") + + company = create_company() + cost_center1 = create_cost_center("Test Cost Center 1") + cost_center2 = create_cost_center("Test Cost Center 2") + + jv1 = make_journal_entry( + posting_date="2021-03-15", + amount=400, + account1="Cash - TPC", + account2="Sales - TPC", + cost_center=cost_center1, + save=False, + ) + jv1.company = company + jv1.save() + jv1.submit() + + jv2 = make_journal_entry( + posting_date="2021-03-15", + amount=200, + account1="Cash - TPC", + account2="Sales - TPC", + cost_center=cost_center2, + save=False, + ) + jv2.company = company + jv2.save() + jv2.submit() + + pcv1 = self.make_period_closing_voucher(posting_date="2021-03-31") + + closing_balance = frappe.db.get_value( + "Account Closing Balance", + { + "account": "Sales - TPC", + "cost_center": cost_center1, + "period_closing_voucher": pcv1.name, + "is_period_closing_voucher_entry": 0, + }, + ["credit", "credit_in_account_currency"], + as_dict=1, + ) + + self.assertEqual(closing_balance.credit, 400) + self.assertEqual(closing_balance.credit_in_account_currency, 400) + + jv3 = make_journal_entry( + posting_date="2022-03-15", + amount=300, + account1="Cash - TPC", + account2="Sales - TPC", + cost_center=cost_center2, + save=False, + ) + + jv3.company = company + jv3.save() + jv3.submit() + + pcv2 = self.make_period_closing_voucher(posting_date="2022-03-31") + + cc1_closing_balance = frappe.db.get_value( + "Account Closing Balance", + { + "account": "Sales - TPC", + "cost_center": cost_center1, + "period_closing_voucher": pcv2.name, + "is_period_closing_voucher_entry": 0, + }, + ["credit", "credit_in_account_currency"], + as_dict=1, + ) + + cc2_closing_balance = frappe.db.get_value( + "Account Closing Balance", + { + "account": "Sales - TPC", + "cost_center": cost_center2, + "period_closing_voucher": pcv2.name, + "is_period_closing_voucher_entry": 0, + }, + ["credit", "credit_in_account_currency"], + as_dict=1, + ) + + self.assertEqual(cc1_closing_balance.credit, 400) + self.assertEqual(cc1_closing_balance.credit_in_account_currency, 400) + self.assertEqual(cc2_closing_balance.credit, 500) + self.assertEqual(cc2_closing_balance.credit_in_account_currency, 500) + + warehouse = frappe.db.get_value("Warehouse", {"company": company}, "name") + + repost_doc = frappe.get_doc( + { + "doctype": "Repost Item Valuation", + "company": company, + "posting_date": "2020-03-15", + "based_on": "Item and Warehouse", + "item_code": "Test Item 1", + "warehouse": warehouse, + } + ) + + self.assertRaises(frappe.ValidationError, repost_doc.save) + + repost_doc.posting_date = today() + repost_doc.save() + + def make_period_closing_voucher(self, posting_date=None, submit=True): +>>>>>>> f751727149 (fix: don't allow to make reposting for the closed period) surplus_account = create_account() cost_center = create_cost_center("Test Cost Center 1") pcv = frappe.get_doc( 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 10e4ba055a1c..5cb2ce2eb323 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -5,6 +5,11 @@ from frappe import _ from frappe.exceptions import QueryDeadlockError, QueryTimeoutError from frappe.model.document import Document +<<<<<<< HEAD +======= +from frappe.query_builder import DocType, Interval +from frappe.query_builder.functions import Max, Now +>>>>>>> f751727149 (fix: don't allow to make reposting for the closed period) from frappe.utils import cint, get_link_to_form, get_weekday, getdate, now, nowtime from frappe.utils.user import get_users_with_role from rq.timeouts import JobTimeoutException @@ -22,11 +27,38 @@ class RepostItemValuation(Document): def validate(self): + self.validate_period_closing_voucher() self.set_status(write=False) self.reset_field_values() self.set_company() self.validate_accounts_freeze() + def validate_period_closing_voucher(self): + 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}" + frappe.throw(_(msg)) + + @staticmethod + def get_max_year_end_date(company): + data = frappe.get_all( + "Period Closing Voucher", fields=["fiscal_year"], filters={"docstatus": 1, "company": company} + ) + + if not data: + return + + fiscal_years = [d.fiscal_year for d in data] + table = frappe.qb.DocType("Fiscal Year") + + query = ( + frappe.qb.from_(table) + .select(Max(table.year_end_date)) + .where((table.name.isin(fiscal_years)) & (table.disabled == 0)) + ).run() + + return query[0][0] if query else None + def validate_accounts_freeze(self): acc_settings = frappe.db.get_value( "Accounts Settings",