@@ -251,10 +251,15 @@ def _get_deterministic_simulation_id(
251251 household_id : UUID | None = None ,
252252 filter_field : str | None = None ,
253253 filter_value : str | None = None ,
254+ filter_strategy : str | None = None ,
254255) -> UUID :
255256 """Generate a deterministic UUID from simulation parameters."""
256257 if simulation_type == SimulationType .ECONOMY :
257258 key = f"economy:{ dataset_id } :{ model_version_id } :{ policy_id } :{ dynamic_id } :{ filter_field } :{ filter_value } "
259+ # Only append filter_strategy when non-null to preserve backward
260+ # compatibility with existing simulation IDs
261+ if filter_strategy is not None :
262+ key += f":{ filter_strategy } "
258263 else :
259264 key = f"household:{ household_id } :{ model_version_id } :{ policy_id } :{ dynamic_id } "
260265 return uuid5 (SIMULATION_NAMESPACE , key )
@@ -279,6 +284,7 @@ def _get_or_create_simulation(
279284 household_id : UUID | None = None ,
280285 filter_field : str | None = None ,
281286 filter_value : str | None = None ,
287+ filter_strategy : str | None = None ,
282288 region_id : UUID | None = None ,
283289 year : int | None = None ,
284290) -> Simulation :
@@ -292,6 +298,7 @@ def _get_or_create_simulation(
292298 household_id = household_id ,
293299 filter_field = filter_field ,
294300 filter_value = filter_value ,
301+ filter_strategy = filter_strategy ,
295302 )
296303
297304 existing = session .get (Simulation , sim_id )
@@ -309,6 +316,7 @@ def _get_or_create_simulation(
309316 status = SimulationStatus .PENDING ,
310317 filter_field = filter_field ,
311318 filter_value = filter_value ,
319+ filter_strategy = filter_strategy ,
312320 region_id = region_id ,
313321 year = year ,
314322 )
@@ -846,12 +854,32 @@ def build_dynamic(dynamic_id):
846854 year = dataset .year ,
847855 )
848856
849- # Run simulations (with optional regional filtering)
857+ # Reconstruct scoping strategy from DB columns (if applicable)
858+ from policyengine_api .utils .strategy_reconstruction import reconstruct_strategy
859+
860+ baseline_region = session .get (Region , baseline_sim .region_id ) if baseline_sim .region_id else None
861+ baseline_strategy = reconstruct_strategy (
862+ filter_strategy = baseline_sim .filter_strategy ,
863+ filter_field = baseline_sim .filter_field ,
864+ filter_value = baseline_sim .filter_value ,
865+ region_type = baseline_region .region_type .value if baseline_region else None ,
866+ )
867+
868+ reform_region = session .get (Region , reform_sim .region_id ) if reform_sim .region_id else None
869+ reform_strategy = reconstruct_strategy (
870+ filter_strategy = reform_sim .filter_strategy ,
871+ filter_field = reform_sim .filter_field ,
872+ filter_value = reform_sim .filter_value ,
873+ region_type = reform_region .region_type .value if reform_region else None ,
874+ )
875+
876+ # Run simulations (with optional regional scoping)
850877 pe_baseline_sim = PESimulation (
851878 dataset = pe_dataset ,
852879 tax_benefit_model_version = pe_model_version ,
853880 policy = baseline_policy ,
854881 dynamic = baseline_dynamic ,
882+ scoping_strategy = baseline_strategy ,
855883 filter_field = baseline_sim .filter_field ,
856884 filter_value = baseline_sim .filter_value ,
857885 )
@@ -862,6 +890,7 @@ def build_dynamic(dynamic_id):
862890 tax_benefit_model_version = pe_model_version ,
863891 policy = reform_policy ,
864892 dynamic = reform_dynamic ,
893+ scoping_strategy = reform_strategy ,
865894 filter_field = reform_sim .filter_field ,
866895 filter_value = reform_sim .filter_value ,
867896 )
@@ -1006,12 +1035,32 @@ def build_dynamic(dynamic_id):
10061035 year = dataset .year ,
10071036 )
10081037
1009- # Run simulations (with optional regional filtering)
1038+ # Reconstruct scoping strategy from DB columns (if applicable)
1039+ from policyengine_api .utils .strategy_reconstruction import reconstruct_strategy
1040+
1041+ baseline_region = session .get (Region , baseline_sim .region_id ) if baseline_sim .region_id else None
1042+ baseline_strategy = reconstruct_strategy (
1043+ filter_strategy = baseline_sim .filter_strategy ,
1044+ filter_field = baseline_sim .filter_field ,
1045+ filter_value = baseline_sim .filter_value ,
1046+ region_type = baseline_region .region_type .value if baseline_region else None ,
1047+ )
1048+
1049+ reform_region = session .get (Region , reform_sim .region_id ) if reform_sim .region_id else None
1050+ reform_strategy = reconstruct_strategy (
1051+ filter_strategy = reform_sim .filter_strategy ,
1052+ filter_field = reform_sim .filter_field ,
1053+ filter_value = reform_sim .filter_value ,
1054+ region_type = reform_region .region_type .value if reform_region else None ,
1055+ )
1056+
1057+ # Run simulations (with optional regional scoping)
10101058 pe_baseline_sim = PESimulation (
10111059 dataset = pe_dataset ,
10121060 tax_benefit_model_version = pe_model_version ,
10131061 policy = baseline_policy ,
10141062 dynamic = baseline_dynamic ,
1063+ scoping_strategy = baseline_strategy ,
10151064 filter_field = baseline_sim .filter_field ,
10161065 filter_value = baseline_sim .filter_value ,
10171066 )
@@ -1022,6 +1071,7 @@ def build_dynamic(dynamic_id):
10221071 tax_benefit_model_version = pe_model_version ,
10231072 policy = reform_policy ,
10241073 dynamic = reform_dynamic ,
1074+ scoping_strategy = reform_strategy ,
10251075 filter_field = reform_sim .filter_field ,
10261076 filter_value = reform_sim .filter_value ,
10271077 )
@@ -1199,6 +1249,7 @@ def economic_impact(
11991249 # Extract filter parameters from region (if present)
12001250 filter_field = region .filter_field if region and region .requires_filter else None
12011251 filter_value = region .filter_value if region and region .requires_filter else None
1252+ filter_strategy = region .filter_strategy if region and region .requires_filter else None
12021253
12031254 # Get model version
12041255 model_version = _get_model_version (request .tax_benefit_model_name , session )
@@ -1213,6 +1264,7 @@ def economic_impact(
12131264 dataset_id = dataset .id ,
12141265 filter_field = filter_field ,
12151266 filter_value = filter_value ,
1267+ filter_strategy = filter_strategy ,
12161268 region_id = region .id if region else None ,
12171269 year = dataset .year ,
12181270 )
@@ -1226,6 +1278,7 @@ def economic_impact(
12261278 dataset_id = dataset .id ,
12271279 filter_field = filter_field ,
12281280 filter_value = filter_value ,
1281+ filter_strategy = filter_strategy ,
12291282 region_id = region .id if region else None ,
12301283 year = dataset .year ,
12311284 )
@@ -1392,6 +1445,9 @@ def economy_custom(
13921445 filter_value = (
13931446 region_obj .filter_value if region_obj and region_obj .requires_filter else None
13941447 )
1448+ filter_strategy = (
1449+ region_obj .filter_strategy if region_obj and region_obj .requires_filter else None
1450+ )
13951451
13961452 model_version = _get_model_version (request .tax_benefit_model_name , session )
13971453
@@ -1404,6 +1460,7 @@ def economy_custom(
14041460 dataset_id = dataset .id ,
14051461 filter_field = filter_field ,
14061462 filter_value = filter_value ,
1463+ filter_strategy = filter_strategy ,
14071464 region_id = region_obj .id if region_obj else None ,
14081465 year = dataset .year ,
14091466 )
@@ -1417,6 +1474,7 @@ def economy_custom(
14171474 dataset_id = dataset .id ,
14181475 filter_field = filter_field ,
14191476 filter_value = filter_value ,
1477+ filter_strategy = filter_strategy ,
14201478 region_id = region_obj .id if region_obj else None ,
14211479 year = dataset .year ,
14221480 )
0 commit comments