1414import yaml
1515from django .views .decorators .http import require_http_methods
1616
17+ from ..utils .config_loader import config_loader
18+
1719from .base import APIResponseMixin
1820
1921logger = logging .getLogger (__name__ )
2224class CaseFormAPIViews (APIResponseMixin ):
2325 """API views for dynamic case form configuration"""
2426
25- @staticmethod
26- @lru_cache (maxsize = 32 )
27- def _load_base_configuration ():
28- """Load base case type configuration from base-case-types.yaml"""
29- try :
30- config_path = os .path .join (
31- os .path .dirname (os .path .dirname (__file__ )), "static" , "config" , "base-case-types.yaml"
32- )
33-
34- with open (config_path , encoding = "utf-8" ) as file :
35- return yaml .safe_load (file ) or {}
36- except Exception as e :
37- logger .exception (f"Error loading base-case-types.yaml: { e } " )
38- return {}
39-
40- @staticmethod
41- @lru_cache (maxsize = 32 )
42- def _load_jurisdiction_configuration (jurisdiction = "illinois" ):
43- """Load jurisdiction-specific configuration and merge with base"""
44- try :
45- # Load base configuration first
46- base_config = CaseFormAPIViews ._load_base_configuration ()
47-
48- # Load jurisdiction-specific configuration
49- config_path = os .path .join (
50- os .path .dirname (os .path .dirname (__file__ )), "static" , "config" , "states" , f"{ jurisdiction } .yaml"
51- )
52-
53- jurisdiction_config = {}
54- if os .path .exists (config_path ):
55- with open (config_path , encoding = "utf-8" ) as file :
56- jurisdiction_config = yaml .safe_load (file ) or {}
57-
58- # Merge configurations - jurisdiction overrides base
59- return CaseFormAPIViews ._deep_merge_configs (base_config , jurisdiction_config )
60-
61- except Exception as e :
62- logger .exception (f"Error loading jurisdiction configuration for { jurisdiction } : { e } " )
63- return CaseFormAPIViews ._load_base_configuration ()
64-
65- @staticmethod
66- def _deep_merge_configs (base , overlay ):
67- """Deep merge two configuration dictionaries"""
68- merged = base .copy ()
69-
70- for key , value in overlay .items ():
71- if key in merged and isinstance (merged [key ], dict ) and isinstance (value , dict ):
72- merged [key ] = CaseFormAPIViews ._deep_merge_configs (merged [key ], value )
73- else :
74- merged [key ] = value
75-
76- return merged
77-
78- @staticmethod
79- def _find_case_type_config (case_type_name , jurisdiction = "illinois" ):
80- """Find case type configuration by matching keywords in merged config"""
81- config = CaseFormAPIViews ._load_jurisdiction_configuration (jurisdiction )
82-
83- # Check both case_types and base_case_types sections
84- case_types_sources = [config .get ("case_types" , {}), config .get ("base_case_types" , {})]
85-
86- case_type_name_lower = case_type_name .lower ()
87- found_config = None
88-
89- print (f"� Looking for case type: '{ case_type_name } ' (lower: '{ case_type_name_lower } ')" )
90-
91- for case_types in case_types_sources :
92- # Try exact match first
93- if case_type_name_lower in case_types :
94- found_config = case_types [case_type_name_lower ]
95- break
96-
97- # Try keyword matching
98- for _case_type_key , case_type_config in case_types .items ():
99- if "keywords" in case_type_config :
100- for keyword in case_type_config ["keywords" ]:
101- # Check both substring matching and exact matching
102- keyword_lower = keyword .lower ()
103- if (
104- keyword_lower in case_type_name_lower
105- or case_type_name_lower in keyword_lower
106- or keyword_lower == case_type_name_lower
107- ):
108- found_config = case_type_config
109- break
110- if found_config :
111- break
112- if found_config :
113- break
114-
115- if not found_config :
116- return None
117-
118- # Resolve inheritance if extends is present
119- if "extends" in found_config :
120- extends_ref = found_config ["extends" ]
121- base_config = None
122-
123- # Parse the extends reference (e.g., "base_case_types.name_change")
124- if "." in extends_ref :
125- section , key = extends_ref .split ("." , 1 )
126- if section in config and key in config [section ]:
127- base_config = config [section ][key ]
128-
129- if base_config :
130- # Deep merge base config with the current config
131- merged_config = CaseFormAPIViews ._deep_merge_configs (base_config .copy (), found_config )
132- return merged_config
133-
134- return found_config
135-
13627 @staticmethod
13728 @require_http_methods (["GET" ])
13829 def get_case_form_config (request ):
@@ -159,7 +50,7 @@ def get_case_form_config(request):
15950 # Try to find case type configuration using jurisdiction-aware lookup
16051 case_config = None
16152 if case_type_id :
162- case_config = CaseFormAPIViews . _find_case_type_config ( case_type_id , jurisdiction )
53+ case_config = config_loader . get_case_type_config ( jurisdiction , case_type_id , court_code )
16354
16455 # If no specific configuration found, return minimal structure
16556 if not case_config :
@@ -178,13 +69,6 @@ def get_case_form_config(request):
17869 }
17970 )
18071
181- # Apply court-specific customizations if they exist
182- sections = case_config .get ("sections" , {})
183- if court_code :
184- sections = CaseFormAPIViews ._apply_court_specific_config (
185- sections , court_code , case_type_id , jurisdiction
186- )
187-
18872 # Structure the response based on the new configuration format
18973 form_config = {
19074 "case_info" : {
@@ -205,68 +89,3 @@ def get_case_form_config(request):
20589
20690 except Exception as e :
20791 return CaseFormAPIViews .error_response (f"Error retrieving case form configuration: { str (e )} " )
208-
209- @staticmethod
210- def _apply_court_specific_config (sections , court_code , case_type_id , jurisdiction ):
211- """Apply court-specific configurations and conditional requirements"""
212- try :
213- config = CaseFormAPIViews ._load_jurisdiction_configuration (jurisdiction )
214- court_requirements = config .get ("court_specific_requirements" , {}).get (court_code , {})
215-
216- if not court_requirements :
217- return sections
218-
219- case_specific = court_requirements .get ("case_types" , {}).get (case_type_id , {})
220- if not case_specific :
221- return sections
222-
223- # Apply field modifications first
224- field_modifications = case_specific .get ("field_modifications" , [])
225- for modification in field_modifications :
226- field_group_name = modification .get ("field_group" )
227- modifications = modification .get ("modifications" , {})
228-
229- # Apply modifications to the matching field group
230- if "parties" in sections and "fields" in sections ["parties" ]:
231- # Use a copy of the list to avoid modification during iteration
232- fields_list = sections ["parties" ]["fields" ][:]
233- for field_group in fields_list :
234- if field_group .get ("section_title" ) == field_group_name :
235- # Apply modifications to this field group
236- for key , value in modifications .items ():
237- if key == "hidden" and value :
238- # Remove this field group entirely if hidden
239- if field_group in sections ["parties" ]["fields" ]:
240- sections ["parties" ]["fields" ].remove (field_group )
241- break
242- elif key == "required" :
243- field_group ["required" ] = value
244- elif key == "conditional_requirements" :
245- field_group ["conditional_requirements" ] = value
246- break
247-
248- # Apply additional fields
249- additional_fields = case_specific .get ("additional_fields" , [])
250- if additional_fields and "parties" in sections and "fields" in sections ["parties" ]:
251- # Add additional fields to the first section of parties
252- if sections ["parties" ]["fields" ]:
253- first_section = sections ["parties" ]["fields" ][0 ]
254- if "fields" in first_section :
255- # Check for existing fields to prevent duplicates
256- existing_field_names = {field .get ("name" ) for field in first_section ["fields" ]}
257-
258- # Only add fields that don't already exist
259- new_fields = []
260- for field in additional_fields :
261- field_name = field .get ("name" )
262- if field_name and field_name not in existing_field_names :
263- new_fields .append (field )
264-
265- if new_fields :
266- first_section ["fields" ].extend (new_fields )
267-
268- return sections
269-
270- except Exception as e :
271- logger .exception (f"Error applying court-specific config: { e } " )
272- return sections
0 commit comments