Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions education/education/doctype/fee_category/fee_category.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class FeeCategory(Document):
def validate(self):
self.update_defaults_from_item_group()
self.validate_duplicate_item_defaults()
self.validate_all_companies_covered()

def after_insert(self):
# create an item
Expand Down Expand Up @@ -52,6 +53,30 @@ def validate_duplicate_item_defaults(self):
if len(companies) != len(set(companies)):
frappe.throw(_("Cannot set multiple Item Defaults for a company."))

def validate_all_companies_covered(self):
"""Validate that Item Defaults are set for all active, mandatory companies."""

# 1. Get all active companies (not group companies)
active_companies = frappe.db.get_list("Company", filters={"is_group": 0}, pluck="name")

# 2. Get companies covered in the Fee Category's Item Defaults table
covered_companies = [d.company for d in self.item_defaults]

# If the defaults table is empty, skip the check (defaults will be fetched from Item Group later)
if not self.item_defaults:
return

# Find missing companies
missing_companies = list(set(active_companies) - set(covered_companies))

if missing_companies:
frappe.throw(
_("Please set Accounting Defaults for the following active companies: {0}").format(
", ".join(missing_companies)
),
title=_("Missing Company Defaults")
)


def create_item(doc, use_name_field=True):
name_field = doc.name if use_name_field else doc.fees_category
Expand Down Expand Up @@ -82,6 +107,7 @@ def update_item(fee_category):
)
item_default_companies = [d.company for d in item_defaults]
fee_category_companies = [d.company for d in fee_category.item_defaults]

for fee_category_default in fee_category.item_defaults:
if fee_category_default.company not in item_default_companies:
add_item_defaults(item, fee_category_default)
Expand Down
34 changes: 34 additions & 0 deletions education/education/doctype/fee_category/test_fee_category.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,37 @@ def test_fee_component_duplicate_default(self):
for default in default_array:
fee_component.append("item_defaults", default)
self.assertRaises(frappe.ValidationError, fee_component.save)

def test_missing_company_default(self):
"""
Validation must fail if Fee Category Defaults are missing for an active company.
"""
# Create a second company for the test environment
create_company("Missing Test Co")

fee_category_name = "Test Fee Category Missing Company"
fee_category = create_fee_category(fee_category_name)
defaults = get_defaults()

# Set default for ONLY the primary company (_Test Company)
fee_category.append(
"item_defaults",
{
"company": "_Test Company",
"income_account": defaults.default_income_account,
"selling_cost_center": defaults.cost_center,
},
)

# Expect an error since "Missing Test Co" is not covered
with self.assertRaises(frappe.exceptions.ValidationError) as cm:
fee_category.save()

# Assert the error message is correct
self.assertIn(
"Please set Accounting Defaults for the following active companies",
str(cm.exception),
)

# Clean up the created company
frappe.delete_doc("Company", "Missing Test Co")