diff --git a/application/controllers/SupplyChainController.php b/application/controllers/SupplyChainController.php index 1546a90..dc56062 100644 --- a/application/controllers/SupplyChainController.php +++ b/application/controllers/SupplyChainController.php @@ -261,13 +261,25 @@ class SupplyChainController extends BaseController $score = $maxScore > 0 ? (int) round($earned / $maxScore * 100) : 0; $riskLevel = $score >= 80 ? 'low' : ($score >= 60 ? 'medium' : ($score >= 40 ? 'high' : 'critical')); - Database::query( - 'UPDATE supplier_questionnaires SET status=?, answers=?, score=?, risk_level=?, completed_at=NOW() WHERE id=?', - ['completed', json_encode($clean, JSON_UNESCAPED_UNICODE), $score, $riskLevel, $q['id']] + // Completamento ATOMICO: vincola lo UPDATE a status='sent' così due submit + // concorrenti con lo stesso token non possono completare due volte (la seconda + // tocca 0 righe -> 409). Previene il doppio-submit senza transazione esplicita. + $upd = Database::query( + 'UPDATE supplier_questionnaires SET status=?, answers=?, score=?, risk_level=?, completed_at=NOW() + WHERE id=? AND status=?', + ['completed', json_encode($clean, JSON_UNESCAPED_UNICODE), $score, $riskLevel, $q['id'], 'sent'] ); + if ($upd->rowCount() === 0) { + $this->jsonError('Questionario gia compilato', 409, 'ALREADY_COMPLETED'); + } + + // Coerenza con assessSupplier: suppliers.risk_score = punteggio di COMPLIANCE + // (alto = buono), e security_requirements_met soglia 70. NON sovrascriviamo + // suppliers.criticality (è la criticità del fornitore, non l'esito del questionario). Database::query( - 'UPDATE suppliers SET risk_score=?, criticality=?, last_assessment_date=CURDATE() WHERE id=? AND organization_id=?', - [100 - $score, $riskLevel, $q['supplier_id'], $q['organization_id']] + 'UPDATE suppliers SET risk_score=?, security_requirements_met=?, last_assessment_date=CURDATE() + WHERE id=? AND organization_id=?', + [$score, $score >= 70 ? 1 : 0, $q['supplier_id'], $q['organization_id']] ); $this->jsonSuccess(['score' => $score, 'risk_level' => $riskLevel], 'Questionario inviato. Grazie.', 201);