From 717f9ac396d126559304f55e79011df8268f18b3 Mon Sep 17 00:00:00 2001 From: DevEnv nis2-agile Date: Mon, 15 Jun 2026 17:17:34 +0200 Subject: [PATCH] [FEAT] A2 UI: wizard onboarding esteso (bilancio, autonomia/gruppo, categorie size-independent art.3 c.5, mission GV.OC, codice etico facoltativo, 3 criteri sotto-soglia c.9 b/c/d) + classificazione v2 lato server + disclaimer ACN 'autovalutazione preliminare'. Markup Bootstrap Italia/AGID Co-Authored-By: Claude Opus 4.8 (1M context) --- public/onboarding.html | 126 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 119 insertions(+), 7 deletions(-) diff --git a/public/onboarding.html b/public/onboarding.html index c43629b..b0f3dc2 100644 --- a/public/onboarding.html +++ b/public/onboarding.html @@ -303,6 +303,48 @@ +
+ + + Terzo criterio dimensionale (Racc. 2003/361/CE): grande impresa se > 43M€ di totale di bilancio. +
+
+ + + Se parte di un gruppo, le soglie vanno calcolate in modo consolidato (art. 6 Racc. 2003/361/CE). +
+
+ + + Questi soggetti rientrano nell'ambito a prescindere dalle soglie (art. 3, comma 5, D.Lgs. 138/2024). +
+
+ + + Alimenta il contesto organizzativo e il registro dei sistemi rilevanti (misura GV.OC). +
+
+
+ + +
+ Facoltativo — buona prassi di governance, non richiesto dalla NIS2. +
@@ -384,6 +426,21 @@
+ + +
+

Sei sotto le soglie dimensionali? — criteri qualitativi (art. 3, comma 9, D.Lgs. 138/2024)

+
+

Compila solo se la tua organizzazione non supera le soglie dimensionali: anche un soggetto sotto-soglia può essere individuato dall'Autorità (ACN) se ricorre uno di questi criteri.

+
+
+
+ +
+
+ + +
@@ -472,7 +529,10 @@ visuraFile: null, company: { name: '', vat_number: '', fiscal_code: '', address: '', city: '', - website: '', email: '', phone: '', sector: '', employee_count: '', annual_turnover: '' + website: '', email: '', phone: '', sector: '', employee_count: '', annual_turnover: '', + total_balance: '', is_autonomous: 1, size_independent_category: 'none', + crit_sole_supplier: 0, crit_public_impact: 0, crit_systemic_risk: 0, + mission: '', has_code_of_ethics: 0 }, profile: { full_name: '', role: '', phone: '' }, classification: null, @@ -714,6 +774,11 @@ wizardState.company.sector = sector; wizardState.company.employee_count = parseInt(employees); wizardState.company.annual_turnover = parseInt(turnover); + wizardState.company.total_balance = parseInt(document.getElementById('total-balance').value) || 0; + wizardState.company.is_autonomous = parseInt(document.getElementById('is-autonomous').value); + wizardState.company.size_independent_category = document.getElementById('size-independent-category').value; + wizardState.company.mission = document.getElementById('mission').value.trim(); + wizardState.company.has_code_of_ethics = document.getElementById('has-code-of-ethics').checked ? 1 : 0; goToStep(3); } @@ -774,20 +839,43 @@ } } - function runClassificationAndSummary() { + async function runClassificationAndSummary() { const c = wizardState.company; - const sector = c.sector; const employees = parseInt(c.employee_count) || 0; const turnover = parseInt(c.annual_turnover) || 0; - const result = classifyLocally(sector, employees, turnover); + // criteri qualitativi sotto-soglia (art. 3 c. 9) letti dai checkbox dello step 4 + c.crit_sole_supplier = (document.getElementById('crit-sole') || {}).checked ? 1 : 0; + c.crit_public_impact = (document.getElementById('crit-impact') || {}).checked ? 1 : 0; + c.crit_systemic_risk = (document.getElementById('crit-systemic') || {}).checked ? 1 : 0; + + // Classificazione v2 lato server (single source of truth: Nis2ClassificationService) + let result = null; + try { + const resp = await api.post('/organizations/classify', { + sector: c.sector, employee_count: employees, annual_turnover_eur: turnover, + total_balance_eur: parseInt(c.total_balance) || 0, + is_autonomous: c.is_autonomous, size_independent_category: c.size_independent_category, + crit_sole_supplier: c.crit_sole_supplier, crit_public_impact: c.crit_public_impact, crit_systemic_risk: c.crit_systemic_risk + }); + if (resp && resp.success && resp.data) { + const d = resp.data; + result = { classification: d.entity_type, label: d.label, description: d.explanation, + designation_basis: d.designation_basis, sub_threshold_candidate: !!d.sub_threshold_candidate, + disclaimer: d.disclaimer || '', obligations: d.obligations || [] }; + } + } catch (e) { /* fallback locale sotto */ } + if (!result) { + const r = classifyLocally(c.sector, employees, turnover); + result = { classification: r.classification, label: r.label, description: r.description, obligations: [], disclaimer: '', sub_threshold_candidate: false }; + } wizardState.classification = result; + // Adesione volontaria: visibile solo per soggetti non in ambito wizardState.voluntaryCompliance = false; const voluntaryCheckbox = document.getElementById('voluntary-checkbox'); if (voluntaryCheckbox) voluntaryCheckbox.checked = false; const voluntaryCard = document.getElementById('voluntary-card'); if (voluntaryCard) voluntaryCard.classList.remove('checked'); - const voluntarySection = document.getElementById('voluntary-section'); if (result.classification === 'not_applicable') voluntarySection.classList.add('visible'); else voluntarySection.classList.remove('visible'); @@ -809,8 +897,24 @@ iconEl.innerHTML = ''; } - labelEl.textContent = result.label; - descEl.textContent = result.description; + // Etichetta + badge "autovalutazione preliminare" + labelEl.textContent = (result.label || '') + ' — autovalutazione preliminare'; + descEl.textContent = result.description || ''; + + // Obblighi (dal server, citano il D.Lgs. 138/2024) + const obEl = document.getElementById('classification-obligations'); + if (obEl) { + if (result.obligations && result.obligations.length) { + obEl.innerHTML = result.obligations.map(o => '
  • ' + String(o).replace(/[<>]/g, '') + '
  • ').join(''); + obEl.style.display = ''; + } else { obEl.style.display = 'none'; obEl.innerHTML = ''; } + } + // Disclaimer ACN (non vincolante) + const disEl = document.getElementById('classification-disclaimer'); + if (disEl) { + if (result.disclaimer) { disEl.textContent = result.disclaimer; disEl.style.display = ''; } + else { disEl.style.display = 'none'; } + } const sectorSelect = document.getElementById('sector'); const sectorOption = sectorSelect.querySelector('option[value="' + c.sector + '"]'); @@ -860,6 +964,14 @@ contact_email: c.email, contact_phone: c.phone, sector: c.sector, employee_count: parseInt(c.employee_count) || 0, annual_turnover_eur: parseInt(c.annual_turnover) || 0, + total_balance_eur: parseInt(c.total_balance) || 0, + is_autonomous: c.is_autonomous, + size_independent_category: c.size_independent_category, + crit_sole_supplier: c.crit_sole_supplier, + crit_public_impact: c.crit_public_impact, + crit_systemic_risk: c.crit_systemic_risk, + mission: c.mission, + has_code_of_ethics: c.has_code_of_ethics, voluntary_compliance: wizardState.voluntaryCompliance ? 1 : 0, full_name: p.full_name, phone: p.phone, country: 'IT', };