@@ -464,6 +464,38 @@ def process_findings(
464464
465465 return self .new_items , self .reactivated_items , self .to_mitigate , self .untouched
466466
467+ def _sync_close_old_finding_status_fields (self , findings : list [Finding ]) -> None :
468+ """
469+ Refresh false_p, risk_accepted, and out_of_scope from the DB for each finding.
470+
471+ These can change during reimport (e.g. false positive) while the in-memory instances
472+ are stale. A naive refresh_from_db per finding issues one SELECT each; we batch one
473+ query for all primary keys and fall back to refresh_from_db only when needed.
474+ """
475+ ids = [f .pk for f in findings if f .pk is not None ]
476+ if not ids :
477+ for finding in findings :
478+ finding .refresh_from_db (fields = ["false_p" , "risk_accepted" , "out_of_scope" ])
479+ return
480+
481+ fresh_by_id = {
482+ row ["id" ]: row
483+ for row in Finding .objects .filter (pk__in = ids ).values (
484+ "id" ,
485+ "false_p" ,
486+ "risk_accepted" ,
487+ "out_of_scope" ,
488+ )
489+ }
490+ for finding in findings :
491+ row = fresh_by_id .get (finding .pk )
492+ if row is not None :
493+ finding .false_p = row ["false_p" ]
494+ finding .risk_accepted = row ["risk_accepted" ]
495+ finding .out_of_scope = row ["out_of_scope" ]
496+ else :
497+ finding .refresh_from_db (fields = ["false_p" , "risk_accepted" , "out_of_scope" ])
498+
467499 def close_old_findings (
468500 self ,
469501 findings : list [Finding ],
@@ -477,17 +509,17 @@ def close_old_findings(
477509 if self .close_old_findings_toggle is False :
478510 return []
479511 logger .debug ("REIMPORT_SCAN: Closing findings no longer present in scan report" )
512+ # Get any status changes that could have occurred earlier in the process
513+ # for special statuses only.
514+ # An example of such is a finding being reported as false positive, and
515+ # reimport makes this change in the database. However, the findings here
516+ # are calculated based from the original values before the reimport, so
517+ # any updates made during reimport are discarded without first getting the
518+ # state of the finding as it stands at this moment
519+ self ._sync_close_old_finding_status_fields (findings )
480520 # Determine if pushing to jira or if the finding groups are enabled
481521 mitigated_findings = []
482522 for finding in findings :
483- # Get any status changes that could have occurred earlier in the process
484- # for special statuses only.
485- # An example of such is a finding being reported as false positive, and
486- # reimport makes this change in the database. However, the findings here
487- # are calculated based from the original values before the reimport, so
488- # any updates made during reimport are discarded without first getting the
489- # state of the finding as it stands at this moment
490- finding .refresh_from_db (fields = ["false_p" , "risk_accepted" , "out_of_scope" ])
491523 # Ensure the finding is not already closed
492524 if not finding .mitigated or not finding .is_mitigated :
493525 logger .debug ("mitigating finding: %i:%s" , finding .id , finding )
0 commit comments