77
88from flask import current_app
99from sqlalchemy import and_ , func
10- from sqlalchemy .orm import selectinload
10+ from sqlalchemy .orm import aliased , selectinload
1111
1212from compliance_api .models import db
1313from compliance_api .models .administrative_penalty import AdministrativePenalty , DecisionEnum
1414from compliance_api .models .charge_recommendation import ChargeRecommendation
1515from compliance_api .models .compliance_finding import ComplianceFindingOption
16- from compliance_api .models .enforcement_action import EnforcementActionOption
16+ from compliance_api .models .enforcement_action import EnforcementActionOption , EnforcementActionOptionEnum
1717from compliance_api .models .inspection .inspection import Inspection
1818from compliance_api .models .inspection .inspection_option import InspectionInitiationOption , InspectionTypeOption
1919from compliance_api .models .inspection .inspection_req_enforcement_map import InspectionReqEnforcementMap
@@ -124,6 +124,14 @@ def _to_excel(
124124 def _build_inspection_requirements_query (self , project_id : int ):
125125 """Build base query for Project Compliance History Report."""
126126
127+ # Alias all enforcement types to join on ALL linked enforcement actions.
128+ order_alias = aliased (Order )
129+ warning_letter_alias = aliased (WarningLetter )
130+ violation_ticket_alias = aliased (ViolationTicket )
131+ admin_penalty_alias = aliased (AdministrativePenalty )
132+ restorative_justice_alias = aliased (RestorativeJustice )
133+ charge_rec_alias = aliased (ChargeRecommendation )
134+
127135 requirement_order_subquery = get_requirement_order_sub_query ()
128136 requirement_warning_letter_subquery = get_requirement_warning_letter_sub_query ()
129137 requirement_violation_ticket_subquery = get_requirement_violation_ticket_sub_query ()
@@ -148,26 +156,30 @@ def _build_inspection_requirements_query(self, project_id: int):
148156 InspectionReqEnforcementMap .enforcement_action_id .label ("enforcement_action_id" ),
149157 EnforcementActionOption .name .label ("enforcement_action" ),
150158 # Enforcement statuses
151- Order .order_status .label ("order_status" ),
152- WarningLetter .status .label ("warning_letter_status" ),
153- ViolationTicket .status .label ("violation_ticket_status" ),
154- AdministrativePenalty .referral_status .label ("admin_penalty_status" ),
155- ChargeRecommendation .status .label ("charge_rec_status" ),
156- RestorativeJustice .status .label ("restorative_justice_status" ),
159+ order_alias .order_status .label ("order_status" ),
160+ warning_letter_alias .status .label ("warning_letter_status" ),
161+ violation_ticket_alias .status .label ("violation_ticket_status" ),
162+ admin_penalty_alias .referral_status .label ("admin_penalty_status" ),
163+ charge_rec_alias .status .label ("charge_rec_status" ),
164+ restorative_justice_alias .status .label ("restorative_justice_status" ),
157165 # Enforcement document numbers
158- Order .order_number .label ("order_number" ),
159- WarningLetter .warning_letter_number .label ("warning_letter_number" ),
160- ViolationTicket .ticket_number .label ("violation_ticket_number" ),
161- AdministrativePenalty .administrative_penalty_number .label ("admin_penalty_number" ),
162- ChargeRecommendation .charge_recommendation_number .label ("charge_rec_number" ),
163- RestorativeJustice .restorative_justice_number .label ("restorative_justice_number" ),
164- AdministrativePenalty .decision .label ("ap_dm_decision" ),
165- AdministrativePenalty .penalty_amount .label ("ap_penalty_amount" ),
166+ order_alias .order_number .label ("order_number" ),
167+ warning_letter_alias .warning_letter_number .label ("warning_letter_number" ),
168+ violation_ticket_alias .ticket_number .label ("violation_ticket_number" ),
169+ admin_penalty_alias .administrative_penalty_number .label ("admin_penalty_number" ),
170+ charge_rec_alias .charge_recommendation_number .label ("charge_rec_number" ),
171+ restorative_justice_alias .restorative_justice_number .label ("restorative_justice_number" ),
172+ admin_penalty_alias .decision .label ("ap_dm_decision" ),
173+ admin_penalty_alias .penalty_amount .label ("ap_penalty_amount" ),
166174 InspectionRecord .date_issued .label ("ir_date_issued" ),
167175 StaffUser ,
168176 Inspection .inspection_status .label ("inspection_status" ),
169177 )
170- .join (Inspection , InspectionRequirement .inspection_id == Inspection .id )
178+ .join (Inspection , and_ (
179+ InspectionRequirement .inspection_id == Inspection .id ,
180+ Inspection .is_active .is_ (True ),
181+ Inspection .is_deleted .is_ (False )
182+ ))
171183 .outerjoin (
172184 inspection_type_subquery ,
173185 inspection_type_subquery .c .inspection_id == Inspection .id
@@ -184,7 +196,11 @@ def _build_inspection_requirements_query(self, project_id: int):
184196 InspectionReqEnforcementMap .is_active .is_ (True ),
185197 InspectionReqEnforcementMap .is_deleted .is_ (False )
186198 ))
187- .join (InspectionRecord , InspectionRecord .inspection_id == Inspection .id )
199+ .join (InspectionRecord , and_ (
200+ InspectionRecord .inspection_id == Inspection .id ,
201+ InspectionRecord .is_active .is_ (True ),
202+ InspectionRecord .is_deleted .is_ (False )
203+ ))
188204 .outerjoin (
189205 EnforcementActionOption ,
190206 InspectionReqEnforcementMap .enforcement_action_id == EnforcementActionOption .id
@@ -195,56 +211,52 @@ def _build_inspection_requirements_query(self, project_id: int):
195211 requirement_order_subquery .c .inspection_requirement_id == InspectionRequirement .id
196212 )
197213 .outerjoin (
198- Order ,
199- Order .id == requirement_order_subquery .c .order_id
214+ order_alias ,
215+ order_alias .id == requirement_order_subquery .c .order_id
200216 )
201217 .outerjoin (
202218 requirement_warning_letter_subquery ,
203219 requirement_warning_letter_subquery .c .inspection_requirement_id == InspectionRequirement .id
204220 )
205221 .outerjoin (
206- WarningLetter ,
207- WarningLetter .id == requirement_warning_letter_subquery .c .warning_letter_id
222+ warning_letter_alias ,
223+ warning_letter_alias .id == requirement_warning_letter_subquery .c .warning_letter_id
208224 )
209225 .outerjoin (
210226 requirement_violation_ticket_subquery ,
211227 requirement_violation_ticket_subquery .c .inspection_requirement_id == InspectionRequirement .id
212228 )
213229 .outerjoin (
214- ViolationTicket ,
215- ViolationTicket .id == requirement_violation_ticket_subquery .c .violation_ticket_id
230+ violation_ticket_alias ,
231+ violation_ticket_alias .id == requirement_violation_ticket_subquery .c .violation_ticket_id
216232 )
217233 .outerjoin (
218234 requirement_admin_penalty_subquery ,
219235 requirement_admin_penalty_subquery .c .inspection_requirement_id == InspectionRequirement .id
220236 )
221237 .outerjoin (
222- AdministrativePenalty ,
223- AdministrativePenalty .id == requirement_admin_penalty_subquery .c .administrative_penalty_id
238+ admin_penalty_alias ,
239+ admin_penalty_alias .id == requirement_admin_penalty_subquery .c .administrative_penalty_id
224240 )
225241 .outerjoin (
226242 requirement_charge_rec_subquery ,
227243 requirement_charge_rec_subquery .c .inspection_requirement_id == InspectionRequirement .id
228244 )
229245 .outerjoin (
230- ChargeRecommendation ,
231- ChargeRecommendation .id == requirement_charge_rec_subquery .c .charge_recommendation_id
246+ charge_rec_alias ,
247+ charge_rec_alias .id == requirement_charge_rec_subquery .c .charge_recommendation_id
232248 )
233249 .outerjoin (
234250 requirement_restorative_justice_subquery ,
235251 requirement_restorative_justice_subquery .c .inspection_requirement_id == InspectionRequirement .id
236252 )
237253 .outerjoin (
238- RestorativeJustice ,
239- RestorativeJustice .id == requirement_restorative_justice_subquery .c .restorative_justice_id
254+ restorative_justice_alias ,
255+ restorative_justice_alias .id == requirement_restorative_justice_subquery .c .restorative_justice_id
240256 )
241257 .filter (
242258 InspectionRequirement .is_active .is_ (True ),
243259 InspectionRequirement .is_deleted .is_ (False ),
244- InspectionRecord .is_active .is_ (True ),
245- InspectionRecord .is_deleted .is_ (False ),
246- Inspection .is_active .is_ (True ),
247- Inspection .is_deleted .is_ (False ),
248260 Inspection .project_id == project_id ,
249261 Inspection .start_date >= self .start_date if self .start_date else True ,
250262 Inspection .start_date <= self .end_date if self .end_date else True ,
@@ -265,6 +277,8 @@ def _format_inspection_requirements_data(data):
265277 raw_enforcement_status = ServiceUtils .get_enforcement_status_by_type (row )
266278 primary_officer = row .StaffUser
267279 req_source_details = inspection_requirement .requirement_source_details
280+ is_ap_penalty = row .enforcement_action_id \
281+ and row .enforcement_action_id == EnforcementActionOptionEnum .ADMINISTRATIVE_PENALTY_RECOMMENDATION .value
268282
269283 condition_num_string = ""
270284 source_string = ""
@@ -288,9 +302,9 @@ def _format_inspection_requirements_data(data):
288302 "compliance_finding" : row .compliance_finding ,
289303 "enforcement_action" : row .enforcement_action ,
290304 "enforcement_status" : raw_enforcement_status .value if raw_enforcement_status else None ,
291- "ap_dm_decision" : row .ap_dm_decision .value if row .ap_dm_decision else None ,
305+ "ap_dm_decision" : row .ap_dm_decision .value if is_ap_penalty and row .ap_dm_decision else None ,
292306 "ap_penalty_amount" : row .ap_penalty_amount
293- if row . ap_penalty_amount and row .ap_dm_decision == DecisionEnum .AP_ISSUED else None ,
307+ if is_ap_penalty and row .ap_dm_decision == DecisionEnum .AP_ISSUED else None ,
294308 "enforcement_document_number" : ServiceUtils .get_enforcement_number_by_type (row ),
295309 "condition_number" : condition_num_string ,
296310 "requirement_source" : source_string ,
0 commit comments