Pagine & UI

Analisi dettagliata di ogni schermata del software — layout, campi, validazioni, azioni

1. Login (/accesso/login)

Form Bootstrap centrato. Campi: j_username, j_password. Submit POST a /j_spring_security_check. Link "Recupera Password".

Se autenticazione fallisce → redirect a /accesso/login?error. Success → redirect sempre a / (configurato always-use-default-target).

2. Recupero password (/accesso/recupera)

Form con solo campo username. Submit POST a /accesso/richiestaRecupero.

Se username esiste e ha email → azzeraPassword() genera password random, invia email, reindirizza al login con messaggio "controlla email". Altrimenti messaggio "Username non esistente" o "Email non settata".

3. Analisi — Lista

Una singola JSP analisi/lista.jsp serve 3 contesti:

Colonne tabella

ColonnaValoreNote
FTftlink al dettaglio
Specielotto.varieta.specie.italianoeagerly loaded
Varietàlotto.varieta.nome
Lottolotto.idcodice testuale
Produttorelotto.produttore.nome
Prossima operaz.(1°) o (2°) + datacalcolata da dataInizio + specie.giorniXConta
AzioniCancella, Lotto esaurito

Azione "Lotto esaurito" dalla lista analisi

Click → chiama /analisis/lottoEsaurito/{idLotto} → imposta esaurito=true + dataEsaurito=oggi → redirect a Da Analizzare.

Azione "Cancella"

Apre modal per inserire motivo cancellazione. Submit POST a /analisis/cancella con id + motivo. Il motivo viene salvato in semiorto_analisi.cancella. L'analisi resta in DB ma non appare più nelle liste attive.

4. Analisi — Cerca (/analisis/)

Pagina di ricerca con filtri multipli e tabella risultati. Tutti i campi sono opzionali.

Filtri disponibili

Filtri su analisi
  • FT (match "start with")
  • Tipologia seme (dropdown da DB)
  • Prova (PETRI / TORBA / CONT. ALV)
  • Anni (multi-select, default ultimi 3 anni + "In corso")
  • Chiusa (sì / no / tutte)
Filtri su lotto
  • Specie (dropdown)
  • Varietà (dropdown dipendente da specie — AJAX /varietas/specie/{id}/json)
  • Lotto (match "anywhere")
  • Esaurito (sì / no / tutti)

Logica di esecuzione

Il service analisiService.cerca(bo) crea un oggetto Criteria Hibernate con JOIN su 5 tabelle (analisi, lotto, varieta, specie, produttore, tipologia_seme). Applica solo i filtri valorizzati. Ordina per: specie italiano ASC, varietà nome ASC, data ASC, lotto.id ASC.

Preselezione anni

All'apertura della pagina, i 3 anni più recenti sono pre-selezionati. L'utente può aggiungerne altri. Valore speciale "In corso" → WHERE data IS NULL.

5. Analisi — Nuova (/analisis/analisi/new)

Pagina di selezione lotto prima di creare l'analisi. Mostra:

Click su un lotto → redirect a /analisis/lotto/{idLotto}/new che crea l'entity SemiortoAnalisi con:

Redirect al form di update con la nuova analisi già popolata.

6. Analisi — Form esecuzione (/analisis/analisi/{id})

La pagina più complessa del software (739 righe JSP). Gestisce tutto il ciclo di vita di una prova di germinabilità.

Struttura a 3 sezioni

  1. Dati prova (metadati)
  2. Conte giornaliere (ripetizioni A, B, C, D)
  3. Chiusura analisi (risultato finale, stampe)

Sezione 1 — Dati prova

CampoTipo UIValidazioneNote
ftreadonlyAuto-generato
Lottoreadonly (label)Codice + varietà + specie
Tipologia semedropdownrequired9 valori
ProvadropdownrequiredPETRI / TORBA / CONT. ALV
Calibraturatext
CategoriadropdownrequiredSTANDARD / COMMERCIALE
Replica analisiradiorequired1 / 2 / 3
Data arrivo labdatepickerrequireddefault: oggi
Data iniziodatepickerrequired
UR %number0-100default: specie.ur
Totale giorni provanumberrequireddefault: specie.giorniTConta
Seme puro %number0-100, default 100
Materiale inerte %number0-100, default 0
Altri semi %number0-100
Oss. purezzatextareamax 512
Osservazionitextareamax 512
Analisi esterna rifgruppoNumero + Data + Germ%
Tecnicodropdownrequired alla chiusura

Sezione 2 — Conte giornaliere

Tabella dinamica con una riga per ogni ripetizione (lettera A, B, C, D). Due colonne principali: giorni_1 (prima conta parziale) e giorni_2 (conta finale). Per ciascuna, 5 categorie: germinati, duri, freschi, anormali, morti.

┌─ Conte giornaliere ──────────────────────────────────────────────────────────┐
│                                                                              │
│ Ripetizione A:    ┌─ giorno 5 ─┬─ giorno 10 ─┐ Vigore: [SCARSO|MEDIO|OTTIMO] │
│                   │ Germ: [85] │ Germ: [10 ] │  [ Cancella conta ]          │
│                   │ Duri: [ 2] │ Duri: [ 1 ] │                               │
│                   │ Fres: [ 1] │ Fres: [ 0 ] │                               │
│                   │ Anor: [ 1] │ Anor: [ 0 ] │                               │
│                   │ Mort: [ 0] │ Mort: [ 0 ] │                               │
│                   └────────────┴─────────────┘                               │
│                                                                              │
│ Ripetizione B:    ... stessa struttura ...                                   │
│ Ripetizione C:    ...                                                        │
│ Ripetizione D:    ...                                                        │
│                                                                              │
│ [ + Aggiungi Conta ]    (nuova lettera auto-incrementata)                    │
└──────────────────────────────────────────────────────────────────────────────┘

Azioni sul form

Il form supporta 4 azioni distinte tramite campo hidden azione:

Valore azioneEffetto
AGGIUNGI_CONTAAggiunge una nuova riga di conta con lettera sequenziale (A→B→C→D)
CANCELLA_CONTARimuove una conta esistente. Se era già salvata, ID finisce in conteDaCancellare per delete nel service
CHIUDI_ANALISIValida tutti i campi required, imposta data=oggi, apre sezione 3 (chiusura)
(vuoto / default)Save normale: persiste i dati modificati

Sezione 3 — Chiusura (modale o sotto-form)

CampoTipoNote
Data finereadonlyImpostata a oggi automaticamente
Germinabilità calcolatareadonlySomma germinati1 + germinati2 (medie)
ScostamentodropdownREGOLARE / IRREGOLARE — indica se la prova è affidabile
RisultatodropdownPOSITIVO / NEGATIVO (valutazione tecnico)
VigoredropdownAuto-calcolato media vigori, modificabile

Azioni finali

7. Lotto — Lista (/lottos/)

Pagina con 2 funzioni:

  1. Ricerca lotti (filtri: specie, varietà, codice lotto, esaurito)
  2. Checkbox per selezionare lotti e impostarli come esauriti (bulk action)

La POST /lottos/settaEsaurito legge dai request params tutti i campi lotto_{id}=true e imposta esaurito=true + dataEsaurito=oggi a ciascuno.

8. Lotto — Crea / Modifica (/lottos/lotto/new)

Form semplice. Campi:

Specie *dropdown (onChange: carica varietà via AJAX)
Varietà *dropdown dipendente
Fornitore *dropdown. Bottone "+" per aprire modal "Aggiungi Fornitore" inline (POST AJAX a /produttores/produttore/update/json)
Kg/Numero *input numerico (doppio ruolo: quantità in kg o in numero semi)
Data arrivo *datepicker
Lotto *text (codice identificativo lotto, assegnato manualmente)
🧪 "generaLotto" — codice morto?

Nel servizio LottoServiceImpl.generaLotto() esiste una funzione che genera un codice lotto auto-calcolato: lettera anno (A=2025, B=2026) + codice specie + codice varietà + codice produttore. Es. per un lotto di pomodoro ItalikoEx-Genovese classico da Schiavone Fernando nel 2020: F + POM + IT-EGC + SF = FPOMIT-EGCSF.

Ma il controller non lo richiama mai. Il form chiede il lotto come input libero. Forse era feature prevista ma non finita. Da verificare con Diego, o ignorare.

Gestione duplicati

Se il codice lotto esiste già, il service lancia messaggio "Il lotto esiste già, vuoi creare un lotto con lo stesso nome?" + abilita checkbox forza=true. Al secondo submit, procede con duplicato.

9. Specie — Lista (/species/)

Tabella con tutte le specie. Colonne: Italiano, Inglese, Latino, Codice, Giorni 1ᵃ conta, Giorni totali, UR%, Azioni (Modifica / Elimina).

10. Specie — Crea / Modifica (/species/specie/new o /specie/{id})

Form standard + matrice di configurazione mesi × tipologie seme. Campi base:

Matrice ripetizione analisi (unica dell'applicazione)

                    Natura  Selez.  Calibr.  FilmC.  Pillol.  Trattato ...
Gennaio     [ ]      [ ]     [ ]     [ ]      [ ]     [ ]      [ ]
Febbraio    [ ]      [X]     [ ]     [ ]      [ ]     [ ]      [ ]
Marzo       [ ]      [ ]     [X]     [ ]      [ ]     [ ]      [ ]
Aprile      [ ]      [ ]     [ ]     [ ]      [ ]     [ ]      [ ]
Maggio      [X]      [ ]     [ ]     [ ]      [ ]     [ ]      [ ]   ← "ogni Maggio riesegui
Giugno      [ ]      [ ]     [ ]     [ ]      [ ]     [ ]      [ ]      analisi su tipologia Natura"
...

Per ogni cella (mese, tipologia) spuntata, viene creato un record in semiorto_map_specie_analisi_ripetizione_tipologia_seme. Questo alimenta il flusso "Da Analizzare" (vedi Flussi).

11. Varietà — Lista e Update

Lista

Filtrabile per specie (dropdown + link dalla pagina specie). Mostra nome, codice, specie, n° lotti.

Update (/varietas/varieta/{id})

Form semplice con: Specie (dropdown), Nome *, Codice.

12. Produttore — Lista e Update

Lista

Tabella con Nome, Codice, Lotti attivi. Click → edit.

Update

Form: Nome * (uppercase automatico), Codice * (uppercase automatico). Validazione duplicati via DuplicateException.

Endpoint AJAX /produttores/produttore/update/json: usato dal form lotto per aggiungere produttore inline nel modal.

13. Utenti — Lista (/amministrazione/utenti)

Solo Amministrazione. Tabella: Username, Nome, Email, Permessi, [Modifica].

14. Utente — Update (/amministrazione/utente/{id})

Form:

Bottoni: [Invia] + [Resetta password] (solo su utente esistente). Reset → azzeraPassword() → nuova random + email.

15. I miei dati (/utenti/myself)

Lettura dati propri + cambio password. L'utente vede i propri dati (username, nome, email). Submit POST a /utenti/utente/update.

Se l'utente cambia un suo campo → logout forzato + nuovo login.

16. Cambio password (/utente/cambioPassword)

Pagina forzata quando utente.cambiaPassword=true.

Form: Vecchia password, Nuova password, Conferma. Submit POST a /utenti/myself/cambiaPassword. Dopo salvataggio → logout forzato → re-login con nuova.