fix: validate docs in closed accounting period on save (#36157)
fix: validate docs in closed accounting period on save (#36157) (cherry picked from commit 5985e02574e387ef92a2bf0a9d2d1b49ad57cdd3) Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
This commit is contained in:
parent
fbea61bbc6
commit
b4db5e9561
@ -20,5 +20,11 @@ frappe.ui.form.on('Accounting Period', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm.set_query("document_type", "closed_documents", () => {
|
||||||
|
return {
|
||||||
|
query: "erpnext.controllers.queries.get_doctypes_for_closing",
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -11,6 +11,10 @@ class OverlapError(frappe.ValidationError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClosedAccountingPeriod(frappe.ValidationError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AccountingPeriod(Document):
|
class AccountingPeriod(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_overlap()
|
self.validate_overlap()
|
||||||
@ -65,3 +69,42 @@ class AccountingPeriod(Document):
|
|||||||
"closed_documents",
|
"closed_documents",
|
||||||
{"document_type": doctype_for_closing.document_type, "closed": doctype_for_closing.closed},
|
{"document_type": doctype_for_closing.document_type, "closed": doctype_for_closing.closed},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_accounting_period_on_doc_save(doc, method=None):
|
||||||
|
if doc.doctype == "Bank Clearance":
|
||||||
|
return
|
||||||
|
elif doc.doctype == "Asset":
|
||||||
|
if doc.is_existing_asset:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
date = doc.available_for_use_date
|
||||||
|
elif doc.doctype == "Asset Repair":
|
||||||
|
date = doc.completion_date
|
||||||
|
else:
|
||||||
|
date = doc.posting_date
|
||||||
|
|
||||||
|
ap = frappe.qb.DocType("Accounting Period")
|
||||||
|
cd = frappe.qb.DocType("Closed Document")
|
||||||
|
|
||||||
|
accounting_period = (
|
||||||
|
frappe.qb.from_(ap)
|
||||||
|
.from_(cd)
|
||||||
|
.select(ap.name)
|
||||||
|
.where(
|
||||||
|
(ap.name == cd.parent)
|
||||||
|
& (ap.company == doc.company)
|
||||||
|
& (cd.closed == 1)
|
||||||
|
& (cd.document_type == doc.doctype)
|
||||||
|
& (date >= ap.start_date)
|
||||||
|
& (date <= ap.end_date)
|
||||||
|
)
|
||||||
|
).run(as_dict=1)
|
||||||
|
|
||||||
|
if accounting_period:
|
||||||
|
frappe.throw(
|
||||||
|
_("You cannot create a {0} within the closed Accounting Period {1}").format(
|
||||||
|
doc.doctype, frappe.bold(accounting_period[0]["name"])
|
||||||
|
),
|
||||||
|
ClosedAccountingPeriod,
|
||||||
|
)
|
||||||
|
@ -6,9 +6,11 @@ import unittest
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import add_months, nowdate
|
from frappe.utils import add_months, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_period.accounting_period import OverlapError
|
from erpnext.accounts.doctype.accounting_period.accounting_period import (
|
||||||
|
ClosedAccountingPeriod,
|
||||||
|
OverlapError,
|
||||||
|
)
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.accounts.general_ledger import ClosedAccountingPeriod
|
|
||||||
|
|
||||||
test_dependencies = ["Item"]
|
test_dependencies = ["Item"]
|
||||||
|
|
||||||
@ -33,9 +35,9 @@ class TestAccountingPeriod(unittest.TestCase):
|
|||||||
ap1.save()
|
ap1.save()
|
||||||
|
|
||||||
doc = create_sales_invoice(
|
doc = create_sales_invoice(
|
||||||
do_not_submit=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC"
|
do_not_save=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC"
|
||||||
)
|
)
|
||||||
self.assertRaises(ClosedAccountingPeriod, doc.submit)
|
self.assertRaises(ClosedAccountingPeriod, doc.save)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
for d in frappe.get_all("Accounting Period"):
|
for d in frappe.get_all("Accounting Period"):
|
||||||
|
@ -13,14 +13,11 @@ import erpnext
|
|||||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||||
get_accounting_dimensions,
|
get_accounting_dimensions,
|
||||||
)
|
)
|
||||||
|
from erpnext.accounts.doctype.accounting_period.accounting_period import ClosedAccountingPeriod
|
||||||
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
|
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
|
||||||
from erpnext.accounts.utils import create_payment_ledger_entry
|
from erpnext.accounts.utils import create_payment_ledger_entry
|
||||||
|
|
||||||
|
|
||||||
class ClosedAccountingPeriod(frappe.ValidationError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def make_gl_entries(
|
def make_gl_entries(
|
||||||
gl_map,
|
gl_map,
|
||||||
cancel=False,
|
cancel=False,
|
||||||
|
@ -822,6 +822,15 @@ def get_purchase_invoices(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
return frappe.db.sql(query, filters)
|
return frappe.db.sql(query, filters)
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
|
def get_doctypes_for_closing(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
doctypes = frappe.get_hooks("period_closing_doctypes")
|
||||||
|
if txt:
|
||||||
|
doctypes = [d for d in doctypes if txt.lower() in d.lower()]
|
||||||
|
return [(d,) for d in set(doctypes)]
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@frappe.validate_and_sanitize_search_inputs
|
@frappe.validate_and_sanitize_search_inputs
|
||||||
def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
|
def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
@ -285,10 +285,34 @@ standard_queries = {
|
|||||||
"Customer": "erpnext.controllers.queries.customer_query",
|
"Customer": "erpnext.controllers.queries.customer_query",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
period_closing_doctypes = [
|
||||||
|
"Sales Invoice",
|
||||||
|
"Purchase Invoice",
|
||||||
|
"Journal Entry",
|
||||||
|
"Bank Clearance",
|
||||||
|
"Stock Entry",
|
||||||
|
"Dunning",
|
||||||
|
"Invoice Discounting",
|
||||||
|
"Payment Entry",
|
||||||
|
"Period Closing Voucher",
|
||||||
|
"Process Deferred Accounting",
|
||||||
|
"Asset",
|
||||||
|
"Asset Capitalization",
|
||||||
|
"Asset Repair",
|
||||||
|
"Delivery Note",
|
||||||
|
"Landed Cost Voucher",
|
||||||
|
"Purchase Receipt",
|
||||||
|
"Stock Reconciliation",
|
||||||
|
"Subcontracting Receipt",
|
||||||
|
]
|
||||||
|
|
||||||
doc_events = {
|
doc_events = {
|
||||||
"*": {
|
"*": {
|
||||||
"validate": "erpnext.support.doctype.service_level_agreement.service_level_agreement.apply",
|
"validate": "erpnext.support.doctype.service_level_agreement.service_level_agreement.apply",
|
||||||
},
|
},
|
||||||
|
tuple(period_closing_doctypes): {
|
||||||
|
"validate": "erpnext.accounts.doctype.accounting_period.accounting_period.validate_accounting_period_on_doc_save",
|
||||||
|
},
|
||||||
"Stock Entry": {
|
"Stock Entry": {
|
||||||
"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
|
"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
|
||||||
"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
|
"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
|
||||||
@ -464,15 +488,6 @@ advance_payment_doctypes = ["Sales Order", "Purchase Order"]
|
|||||||
|
|
||||||
invoice_doctypes = ["Sales Invoice", "Purchase Invoice"]
|
invoice_doctypes = ["Sales Invoice", "Purchase Invoice"]
|
||||||
|
|
||||||
period_closing_doctypes = [
|
|
||||||
"Sales Invoice",
|
|
||||||
"Purchase Invoice",
|
|
||||||
"Journal Entry",
|
|
||||||
"Bank Clearance",
|
|
||||||
"Asset",
|
|
||||||
"Stock Entry",
|
|
||||||
]
|
|
||||||
|
|
||||||
bank_reconciliation_doctypes = [
|
bank_reconciliation_doctypes = [
|
||||||
"Payment Entry",
|
"Payment Entry",
|
||||||
"Journal Entry",
|
"Journal Entry",
|
||||||
|
Loading…
Reference in New Issue
Block a user