Auto-sync: 20260428_202037

This commit is contained in:
Paolo 2026-04-28 20:20:45 +02:00
parent adb1b2ac82
commit 62015933ee
9 changed files with 117 additions and 48 deletions

BIN
.DS_Store vendored

Binary file not shown.

View file

@ -25,7 +25,7 @@ class Comp6_7Screen extends StatefulWidget {
}
class _Comp6_7ScreenState extends State<Comp6_7Screen> {
late TextEditingController _cognome, _nome, _cf, _indirizzo, _cap, _stato, _tel;
late TextEditingController _cognome, _nome, _cf, _indirizzo, _cap, _stato, _tel, _email;
late TextEditingController _marca, _rimorchio, _targa, _statoImm, _statoImm2;
// Il tuo FocusNode originale
@ -127,6 +127,7 @@ class _Comp6_7ScreenState extends State<Comp6_7Screen> {
_cap = TextEditingController(text: GlobalData.CAP_contraente_B);
_stato = TextEditingController(text: GlobalData.Stato_contraente_B.isEmpty ? "ITALIA" : GlobalData.Stato_contraente_B);
_tel = TextEditingController(text: GlobalData.N_telefono_mail_contraente_B);
_email = TextEditingController(text: GlobalData.Email_contraente_B);
_marca = TextEditingController(text: GlobalData.Marca_e_Tipo_B);
_targa = TextEditingController(text: GlobalData.Targa_B);
@ -142,6 +143,7 @@ class _Comp6_7ScreenState extends State<Comp6_7Screen> {
_cap = TextEditingController(text: GlobalData.CAP_contraente_A);
_stato = TextEditingController(text: GlobalData.Stato_contraente_A.isEmpty ? "ITALIA" : GlobalData.Stato_contraente_A);
_tel = TextEditingController(text: GlobalData.N_telefono_mail_contraente_A);
_email = TextEditingController(text: GlobalData.Email_contraente_A);
_marca = TextEditingController(text: GlobalData.Marca_e_Tipo_A);
_targa = TextEditingController(text: GlobalData.Targa_A);
@ -340,6 +342,20 @@ class _Comp6_7ScreenState extends State<Comp6_7Screen> {
return;
}
// Validazione Telefono
String telefono = _tel.text.trim();
if (!RegExp(r'^\+?[0-9\s\-\.]+$').hasMatch(telefono)) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Numero di telefono non valido. Usa solo numeri e il prefisso +."), backgroundColor: Colors.orange));
return;
}
// Validazione Email (se inserita)
String email = _email.text.trim();
if (email.isNotEmpty && !RegExp(r'^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+').hasMatch(email)) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Formato email non valido!"), backgroundColor: Colors.orange));
return;
}
String cfInserito = _cf.text.trim().toUpperCase();
// Controlliamo la validità SOLO se il campo non è vuoto
@ -403,7 +419,8 @@ class _Comp6_7ScreenState extends State<Comp6_7Screen> {
GlobalData.Indirizzo_contraente_B = _indirizzo.text.trim().toUpperCase();
GlobalData.CAP_contraente_B = _cap.text.trim();
GlobalData.Stato_contraente_B = _stato.text.trim().toUpperCase();
GlobalData.N_telefono_mail_contraente_B = _tel.text.trim().toUpperCase();
GlobalData.N_telefono_mail_contraente_B = telefono;
GlobalData.Email_contraente_B = email.toLowerCase();
GlobalData.Marca_e_Tipo_B = _marca.text.trim().toUpperCase();
GlobalData.Targa_B = _targa.text.trim().toUpperCase();
GlobalData.Stato_immatricolazione_B = _statoImm.text.trim().toUpperCase();
@ -416,7 +433,8 @@ class _Comp6_7ScreenState extends State<Comp6_7Screen> {
GlobalData.Indirizzo_contraente_A = _indirizzo.text.trim().toUpperCase();
GlobalData.CAP_contraente_A = _cap.text.trim();
GlobalData.Stato_contraente_A = _stato.text.trim().toUpperCase();
GlobalData.N_telefono_mail_contraente_A = _tel.text.trim().toUpperCase();
GlobalData.N_telefono_mail_contraente_A = telefono;
GlobalData.Email_contraente_A = email.toLowerCase();
GlobalData.Marca_e_Tipo_A = _marca.text.trim().toUpperCase();
GlobalData.Targa_A = _targa.text.trim().toUpperCase();
GlobalData.Stato_immatricolazione_A = _statoImm.text.trim().toUpperCase();
@ -503,8 +521,12 @@ class _Comp6_7ScreenState extends State<Comp6_7Screen> {
]
),
_buildField(_tel, "Tel / Email *", Icons.email,
autofillHints: const [AutofillHints.telephoneNumber, AutofillHints.email],
_buildField(_tel, "Telefono *", Icons.phone,
autofillHints: const [AutofillHints.telephoneNumber],
keyboardType: TextInputType.phone),
_buildField(_email, "Email (Opzionale)", Icons.email,
autofillHints: const [AutofillHints.email],
keyboardType: TextInputType.emailAddress),
],
),
@ -661,7 +683,7 @@ class _Comp6_7ScreenState extends State<Comp6_7Screen> {
_cfFocusNode.dispose();
_cognome.dispose(); _nome.dispose(); _cf.dispose(); _indirizzo.dispose();
_cap.dispose(); _stato.dispose(); _tel.dispose();
_cap.dispose(); _stato.dispose(); _tel.dispose(); _email.dispose();
_marca.dispose(); _targa.dispose(); _rimorchio.dispose();
_statoImm.dispose(); _statoImm2.dispose();
super.dispose();

View file

@ -29,7 +29,7 @@ class Comp9Screen extends StatefulWidget {
}
class _Comp9ScreenState extends State<Comp9Screen> {
late TextEditingController _cognome, _nome, _cf, _nascita, _indirizzo, _stato, _tel, _patente, _categoriaAltro, _scadenza;
late TextEditingController _cognome, _nome, _cf, _nascita, _indirizzo, _stato, _tel, _email, _patente, _categoriaAltro, _scadenza;
String _selectedCat = "B";
@ -63,6 +63,7 @@ class _Comp9ScreenState extends State<Comp9Screen> {
_indirizzo = TextEditingController(text: GlobalData.Indirizzo_cond_B);
_stato = TextEditingController(text: GlobalData.Stato_cond_B.isEmpty ? "ITALIA" : GlobalData.Stato_cond_B);
_tel = TextEditingController(text: GlobalData.N_tel_mail_cond_B);
_email = TextEditingController(text: GlobalData.Email_cond_B);
_patente = TextEditingController(text: GlobalData.N_Patente_cond_B);
_scadenza = TextEditingController(text: GlobalData.Scadenza_cond_B);
_setupCategoria(GlobalData.Categoria_cond_B);
@ -74,6 +75,7 @@ class _Comp9ScreenState extends State<Comp9Screen> {
_indirizzo = TextEditingController(text: GlobalData.Indirizzo_cond_A);
_stato = TextEditingController(text: GlobalData.Stato_cond_A.isEmpty ? "ITALIA" : GlobalData.Stato_cond_A);
_tel = TextEditingController(text: GlobalData.N_tel_mail_cond_A);
_email = TextEditingController(text: GlobalData.Email_cond_A);
_patente = TextEditingController(text: GlobalData.N_Patente_cond_A);
_scadenza = TextEditingController(text: GlobalData.Scadenza_cond_A);
_setupCategoria(GlobalData.Categoria_cond_A);
@ -226,6 +228,7 @@ class _Comp9ScreenState extends State<Comp9Screen> {
_stato.text = GlobalData.Stato_contraente_B.isNotEmpty ? GlobalData.Stato_contraente_B : "ITALIA";
_tel.text = GlobalData.N_telefono_mail_contraente_B;
_email.text = GlobalData.Email_contraente_B;
} else {
_cognome.text = GlobalData.Cognome_contraente_A;
_nome.text = GlobalData.Nome_contraente_A;
@ -237,6 +240,7 @@ class _Comp9ScreenState extends State<Comp9Screen> {
_stato.text = GlobalData.Stato_contraente_A.isNotEmpty ? GlobalData.Stato_contraente_A : "ITALIA";
_tel.text = GlobalData.N_telefono_mail_contraente_A;
_email.text = GlobalData.Email_contraente_A;
}
});
}
@ -327,10 +331,26 @@ class _Comp9ScreenState extends State<Comp9Screen> {
String catFinale = (_selectedCat == "Altro") ? _categoriaAltro.text.toUpperCase() : _selectedCat;
bool categoriaMancante = (_selectedCat == "Altro" && _categoriaAltro.text.trim().isEmpty);
if (_cognome.text.trim().isEmpty || _nome.text.trim().isEmpty || _cf.text.trim().isEmpty ||
_nascita.text.trim().isEmpty || _indirizzo.text.trim().isEmpty || _stato.text.trim().isEmpty ||
_patente.text.trim().isEmpty || _scadenza.text.trim().isEmpty || categoriaMancante) {
_mostraErrore("Tutti i dati del conducente sono obbligatori!", Colors.red);
if (_cognome.text.trim().isEmpty || _nome.text.trim().isEmpty ||
_nascita.text.trim().isEmpty || _indirizzo.text.trim().isEmpty ||
_stato.text.trim().isEmpty || _tel.text.trim().isEmpty ||
_patente.text.trim().isEmpty || _scadenza.text.trim().isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Compila tutti i campi obbligatori!"), backgroundColor: Colors.red));
return;
}
// Validazione Telefono
String telefono = _tel.text.trim();
if (!RegExp(r'^\+?[0-9\s\-\.]+$').hasMatch(telefono)) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Numero di telefono non valido. Usa solo numeri e il prefisso +."), backgroundColor: Colors.orange));
return;
}
// Validazione Email (se inserita)
String email = _email.text.trim();
if (email.isNotEmpty && !RegExp(r'^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+').hasMatch(email)) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Formato email non valido!"), backgroundColor: Colors.orange));
return;
}
@ -349,10 +369,11 @@ class _Comp9ScreenState extends State<Comp9Screen> {
GlobalData.Nome_cond_B = _nome.text.toUpperCase();
GlobalData.Cod_fiscale_cond_B = _cf.text.toUpperCase();
GlobalData.Data_nascita_cond_B = _nascita.text;
GlobalData.Indirizzo_cond_B = _indirizzo.text.toUpperCase();
GlobalData.Stato_cond_B = _stato.text.toUpperCase();
GlobalData.N_tel_mail_cond_B = _tel.text.toUpperCase();
GlobalData.N_Patente_cond_B = _patente.text.toUpperCase();
GlobalData.Indirizzo_cond_B = _indirizzo.text.trim().toUpperCase();
GlobalData.Stato_cond_B = _stato.text.trim().toUpperCase();
GlobalData.N_tel_mail_cond_B = telefono;
GlobalData.Email_cond_B = email.toLowerCase();
GlobalData.N_Patente_cond_B = _patente.text.trim().toUpperCase();
GlobalData.Categoria_cond_B = catFinale;
GlobalData.Scadenza_cond_B = _scadenza.text;
} else {
@ -360,10 +381,11 @@ class _Comp9ScreenState extends State<Comp9Screen> {
GlobalData.Nome_cond_A = _nome.text.toUpperCase();
GlobalData.Cod_fiscale_cond_A = _cf.text.toUpperCase();
GlobalData.Data_nascita_cond_A = _nascita.text;
GlobalData.Indirizzo_cond_A = _indirizzo.text.toUpperCase();
GlobalData.Stato_cond_A = _stato.text.toUpperCase();
GlobalData.N_tel_mail_cond_A = _tel.text.toUpperCase();
GlobalData.N_Patente_cond_A = _patente.text.toUpperCase();
GlobalData.Indirizzo_cond_A = _indirizzo.text.trim().toUpperCase();
GlobalData.Stato_cond_A = _stato.text.trim().toUpperCase();
GlobalData.N_tel_mail_cond_A = telefono;
GlobalData.Email_cond_A = email.toLowerCase();
GlobalData.N_Patente_cond_A = _patente.text.trim().toUpperCase();
GlobalData.Categoria_cond_A = catFinale;
GlobalData.Scadenza_cond_A = _scadenza.text;
}
@ -424,8 +446,9 @@ class _Comp9ScreenState extends State<Comp9Screen> {
_buildTextField(_cf, "Codice Fiscale *", Icons.badge, accentColor, isUpper: true),
_buildTextField(_indirizzo, "Indirizzo (Via, Cap, Città) *", Icons.home, accentColor),
_buildTextField(_stato, "Stato *", Icons.flag, accentColor),
_buildTextField(_tel, "Tel/Email *", Icons.contact_mail, accentColor),
_buildTextField(_stato, "Stato di Residenza *", Icons.public, accentColor, isUpper: true),
_buildTextField(_tel, "Telefono *", Icons.phone, accentColor),
_buildTextField(_email, "Email (Opzionale)", Icons.email, accentColor),
],
),
_buildSectionCard(
@ -525,9 +548,9 @@ class _Comp9ScreenState extends State<Comp9Screen> {
@override
void dispose() {
_cognome.dispose(); _nome.dispose(); _cf.dispose(); _nascita.dispose();
_indirizzo.dispose(); _stato.dispose(); _tel.dispose();
_patente.dispose(); _categoriaAltro.dispose(); _scadenza.dispose();
_cognome.dispose(); _nome.dispose(); _cf.dispose();
_nascita.dispose(); _indirizzo.dispose(); _stato.dispose();
_tel.dispose(); _email.dispose(); _patente.dispose(); _categoriaAltro.dispose(); _scadenza.dispose();
super.dispose();
}
}

View file

@ -19,17 +19,17 @@ class GlobalData {
static bool Oggetti_diversi_danni_materiali = false;
// --- DATI LATO A (BLU) ---
static String Cognome_contraente_A = ""; static String Nome_contraente_A = ""; static String Codice_Fiscale_contraente_A = ""; static String Indirizzo_contraente_A = ""; static String CAP_contraente_A = ""; static String Stato_contraente_A = ""; static String N_telefono_mail_contraente_A = "";
static String Cognome_contraente_A = ""; static String Nome_contraente_A = ""; static String Codice_Fiscale_contraente_A = ""; static String Indirizzo_contraente_A = ""; static String CAP_contraente_A = ""; static String Stato_contraente_A = ""; static String N_telefono_mail_contraente_A = ""; static String Email_contraente_A = "";
static String Marca_e_Tipo_A = ""; static String Targa_A = ""; static String Stato_immatricolazione_A = ""; static String Rimorchio_A = ""; static String Stato_immatricolazione2_A = "";
static String Denominazione_A = ""; static String Numero_Polizza_A = ""; static String N_carta_verde_A = ""; static String Data_Inizio_Dal_A = ""; static String Data_Scadenza_Al_A = ""; static String Agenzia_A = ""; static String Denominazione_agenzia_A = ""; static String Indirizzo_agenzia_A = ""; static String Stato_agenzia_A = ""; static String N_tel_mail_agenzia_A = ""; static bool FLAG_danni_mat_assicurati_A = false;
static String Cognome_cond_A = ""; static String Nome_cond_A = ""; static String Data_nascita_cond_A = ""; static String Cod_fiscale_cond_A = ""; static String Indirizzo_cond_A = ""; static String Stato_cond_A = ""; static String N_tel_mail_cond_A = ""; static String N_Patente_cond_A = ""; static String Scadenza_cond_A = ""; static String Categoria_cond_A = "";
static String Cognome_cond_A = ""; static String Nome_cond_A = ""; static String Data_nascita_cond_A = ""; static String Cod_fiscale_cond_A = ""; static String Indirizzo_cond_A = ""; static String Stato_cond_A = ""; static String N_tel_mail_cond_A = ""; static String Email_cond_A = ""; static String N_Patente_cond_A = ""; static String Scadenza_cond_A = ""; static String Categoria_cond_A = "";
static List<String> puntiUrtoA_List = []; static String danni_visibili_A = ""; static String osservazioni_A = ""; static Map<int, bool> circostanzeA = {}; static int totaleCrocetteA = 0; static List<Offset?> puntiFirmaA = [];
// --- DATI LATO B (GIALLO) ---
static String Cognome_contraente_B = ""; static String Nome_contraente_B = ""; static String Codice_Fiscale_contraente_B = ""; static String Indirizzo_contraente_B = ""; static String CAP_contraente_B = ""; static String Stato_contraente_B = ""; static String N_telefono_mail_contraente_B = "";
static String Cognome_contraente_B = ""; static String Nome_contraente_B = ""; static String Codice_Fiscale_contraente_B = ""; static String Indirizzo_contraente_B = ""; static String CAP_contraente_B = ""; static String Stato_contraente_B = ""; static String N_telefono_mail_contraente_B = ""; static String Email_contraente_B = "";
static String Marca_e_Tipo_B = ""; static String Targa_B = ""; static String Stato_immatricolazione_B = ""; static String Rimorchio_B = ""; static String Stato_immatricolazione2_B = "";
static String Denominazione_B = ""; static String Numero_Polizza_B = ""; static String N_carta_verde_B = ""; static String Data_Inizio_Dal_B = ""; static String Data_Scadenza_Al_B = ""; static String Agenzia_B = ""; static String Denominazione_agenzia_B = ""; static String Indirizzo_agenzia_B = ""; static String Stato_agenzia_B = ""; static String N_tel_mail_agenzia_B = ""; static bool FLAG_danni_mat_assicurati_B = false;
static String Cognome_cond_B = ""; static String Nome_cond_B = ""; static String Data_nascita_cond_B = ""; static String Cod_fiscale_cond_B = ""; static String Indirizzo_cond_B = ""; static String Stato_cond_B = ""; static String N_tel_mail_cond_B = ""; static String N_Patente_cond_B = ""; static String Scadenza_cond_B = ""; static String Categoria_cond_B = "";
static String Cognome_cond_B = ""; static String Nome_cond_B = ""; static String Data_nascita_cond_B = ""; static String Cod_fiscale_cond_B = ""; static String Indirizzo_cond_B = ""; static String Stato_cond_B = ""; static String N_tel_mail_cond_B = ""; static String Email_cond_B = ""; static String N_Patente_cond_B = ""; static String Scadenza_cond_B = ""; static String Categoria_cond_B = "";
static List<String> puntiUrtoB_List = []; static String danni_visibili_B = ""; static String osservazioni_B = ""; static Map<int, bool> circostanzeB = {}; static int totaleCrocetteB = 0; static List<Offset?> puntiFirmaB = [];
// --- DATI FEA (Firma Elettronica Avanzata) ---
@ -145,19 +145,19 @@ class GlobalData {
}
static void resetA() {
Cognome_contraente_A = ""; Nome_contraente_A = ""; Codice_Fiscale_contraente_A = ""; Indirizzo_contraente_A = ""; CAP_contraente_A = ""; Stato_contraente_A = ""; N_telefono_mail_contraente_A = "";
Cognome_contraente_A = ""; Nome_contraente_A = ""; Codice_Fiscale_contraente_A = ""; Indirizzo_contraente_A = ""; CAP_contraente_A = ""; Stato_contraente_A = ""; N_telefono_mail_contraente_A = ""; Email_contraente_A = "";
Marca_e_Tipo_A = ""; Targa_A = ""; Stato_immatricolazione_A = ""; Rimorchio_A = ""; Stato_immatricolazione2_A = "";
Denominazione_A = ""; Numero_Polizza_A = ""; N_carta_verde_A = ""; Data_Inizio_Dal_A = ""; Data_Scadenza_Al_A = ""; Agenzia_A = ""; Denominazione_agenzia_A = ""; Indirizzo_agenzia_A = ""; Stato_agenzia_A = ""; N_tel_mail_agenzia_A = ""; FLAG_danni_mat_assicurati_A = false;
Cognome_cond_A = ""; Nome_cond_A = ""; Data_nascita_cond_A = ""; Cod_fiscale_cond_A = ""; Indirizzo_cond_A = ""; Stato_cond_A = ""; N_tel_mail_cond_A = ""; N_Patente_cond_A = ""; Scadenza_cond_A = ""; Categoria_cond_A = "";
Cognome_cond_A = ""; Nome_cond_A = ""; Data_nascita_cond_A = ""; Cod_fiscale_cond_A = ""; Indirizzo_cond_A = ""; Stato_cond_A = ""; N_tel_mail_cond_A = ""; Email_cond_A = ""; N_Patente_cond_A = ""; Scadenza_cond_A = ""; Categoria_cond_A = "";
puntiUrtoA_List = []; danni_visibili_A = ""; osservazioni_A = ""; circostanzeA = {}; totaleCrocetteA = 0; puntiFirmaA = [];
feaVerifiedA = false; otpDataOraA = ""; otpIdA = "";
}
static void resetB() {
Cognome_contraente_B = ""; Nome_contraente_B = ""; Codice_Fiscale_contraente_B = ""; Indirizzo_contraente_B = ""; CAP_contraente_B = ""; Stato_contraente_B = ""; N_telefono_mail_contraente_B = "";
Cognome_contraente_B = ""; Nome_contraente_B = ""; Codice_Fiscale_contraente_B = ""; Indirizzo_contraente_B = ""; CAP_contraente_B = ""; Stato_contraente_B = ""; N_telefono_mail_contraente_B = ""; Email_contraente_B = "";
Marca_e_Tipo_B = ""; Targa_B = ""; Stato_immatricolazione_B = ""; Rimorchio_B = ""; Stato_immatricolazione2_B = "";
Denominazione_B = ""; Numero_Polizza_B = ""; N_carta_verde_B = ""; Data_Inizio_Dal_B = ""; Data_Scadenza_Al_B = ""; Agenzia_B = ""; Denominazione_agenzia_B = ""; Indirizzo_agenzia_B = ""; Stato_agenzia_B = ""; N_tel_mail_agenzia_B = ""; FLAG_danni_mat_assicurati_B = false;
Cognome_cond_B = ""; Nome_cond_B = ""; Data_nascita_cond_B = ""; Cod_fiscale_cond_B = ""; Indirizzo_cond_B = ""; Stato_cond_B = ""; N_tel_mail_cond_B = ""; N_Patente_cond_B = ""; Scadenza_cond_B = ""; Categoria_cond_B = "";
Cognome_cond_B = ""; Nome_cond_B = ""; Data_nascita_cond_B = ""; Cod_fiscale_cond_B = ""; Indirizzo_cond_B = ""; Stato_cond_B = ""; N_tel_mail_cond_B = ""; Email_cond_B = ""; N_Patente_cond_B = ""; Scadenza_cond_B = ""; Categoria_cond_B = "";
puntiUrtoB_List = []; danni_visibili_B = ""; osservazioni_B = ""; circostanzeB = {}; totaleCrocetteB = 0; puntiFirmaB = [];
feaVerifiedB = false; otpDataOraB = ""; otpIdB = "";
}
@ -172,11 +172,11 @@ class GlobalData {
if (latoCorrente == 'A') {
// Dati A
Cognome_contraente_A = "ROSSI"; Nome_contraente_A = "MARIO"; Codice_Fiscale_contraente_A = "RSSMRA80A01H501U"; Indirizzo_contraente_A = "VIA ROMA 1"; CAP_contraente_A = "00100"; Stato_contraente_A = "ITALIA"; N_telefono_mail_contraente_A = "333.1234567";
Cognome_contraente_A = "ROSSI"; Nome_contraente_A = "MARIO"; Codice_Fiscale_contraente_A = "RSSMRA80A01H501U"; Indirizzo_contraente_A = "VIA ROMA 1"; CAP_contraente_A = "00100"; Stato_contraente_A = "ITALIA"; N_telefono_mail_contraente_A = "333.1234567"; Email_contraente_A = "mario.rossi@email.it";
Marca_e_Tipo_A = "FIAT PANDA"; Targa_A = "AA123AA"; Stato_immatricolazione_A = "IT"; Rimorchio_A = ""; Stato_immatricolazione2_A = "";
Denominazione_A = "GENERALI"; Numero_Polizza_A = "123456"; N_carta_verde_A = "CV-001"; Data_Inizio_Dal_A = "01/01/2023"; Data_Scadenza_Al_A = "01/01/2024";
Agenzia_A = "ROMA"; Denominazione_agenzia_A = "AG. CENTRALE"; Indirizzo_agenzia_A = "VIA PO 20"; Stato_agenzia_A = "IT"; N_tel_mail_agenzia_A = "ag@mail.it"; FLAG_danni_mat_assicurati_A = true;
Cognome_cond_A = "ROSSI"; Nome_cond_A = "MARIO"; Data_nascita_cond_A = "01/01/1980"; Cod_fiscale_cond_A = "RSSMRA80"; Indirizzo_cond_A = "VIA ROMA 1"; Stato_cond_A = "IT"; N_tel_mail_cond_A = "333.1234567";
Cognome_cond_A = "ROSSI"; Nome_cond_A = "MARIO"; Data_nascita_cond_A = "01/01/1980"; Cod_fiscale_cond_A = "RSSMRA80"; Indirizzo_cond_A = "VIA ROMA 1"; Stato_cond_A = "IT"; N_tel_mail_cond_A = "333.1234567"; Email_cond_A = "mario.rossi@email.it";
N_Patente_cond_A = "PAT-001"; Scadenza_cond_A = "01/01/2030"; Categoria_cond_A = "B";
puntiUrtoA_List = ["Anteriore"]; danni_visibili_A = "PARAURTI ROTTO"; osservazioni_A = "RAGIONE PIENA"; circostanzeA = {1:true};
puntiFirmaA = [const Offset(0,0), const Offset(10,10)];
@ -184,11 +184,11 @@ class GlobalData {
resetB();
} else {
// Dati B
Cognome_contraente_B = "VERDI"; Nome_contraente_B = "LUIGI"; Codice_Fiscale_contraente_B = "VRDLGU90B02F205Z"; Indirizzo_contraente_B = "MILANO"; CAP_contraente_B = "20100"; Stato_contraente_B = "ITALIA"; N_telefono_mail_contraente_B = "340.9876543";
Cognome_contraente_B = "VERDI"; Nome_contraente_B = "LUIGI"; Codice_Fiscale_contraente_B = "VRDLGU90B02F205Z"; Indirizzo_contraente_B = "MILANO"; CAP_contraente_B = "20100"; Stato_contraente_B = "ITALIA"; N_telefono_mail_contraente_B = "340.9876543"; Email_contraente_B = "luigi.verdi@email.it";
Marca_e_Tipo_B = "FORD FIESTA"; Targa_B = "BB987BB"; Stato_immatricolazione_B = "IT"; Rimorchio_B = ""; Stato_immatricolazione2_B = "";
Denominazione_B = "ALLIANZ"; Numero_Polizza_B = "987654"; N_carta_verde_B = "CV-002"; Data_Inizio_Dal_B = "01/01/2023"; Data_Scadenza_Al_B = "01/01/2024";
Agenzia_B = "MILANO"; Denominazione_agenzia_B = "AG. NORD"; Indirizzo_agenzia_B = "VIA DANTE 1"; Stato_agenzia_B = "IT"; N_tel_mail_agenzia_B = "mi@mail.it"; FLAG_danni_mat_assicurati_B = false;
Cognome_cond_B = "VERDI"; Nome_cond_B = "LUIGI"; Data_nascita_cond_B = "02/02/1990"; Cod_fiscale_cond_B = "VRDLGU90"; Indirizzo_cond_B = "MILANO"; Stato_cond_B = "IT"; N_tel_mail_cond_B = "340.9876543";
Cognome_cond_B = "VERDI"; Nome_cond_B = "LUIGI"; Data_nascita_cond_B = "02/02/1990"; Cod_fiscale_cond_B = "VRDLGU90"; Indirizzo_cond_B = "MILANO"; Stato_cond_B = "IT"; N_tel_mail_cond_B = "340.9876543"; Email_cond_B = "luigi.verdi@email.it";
N_Patente_cond_B = "PAT-002"; Scadenza_cond_B = "02/02/2030"; Categoria_cond_B = "B";
puntiUrtoB_List = ["Posteriore"]; danni_visibili_B = "PARAURTI POST ROTTO"; osservazioni_B = "NON HO VISTO"; circostanzeB = {12:true};
puntiFirmaB = [const Offset(0,0), const Offset(10,10)];

View file

@ -448,7 +448,10 @@ class PdfEngine {
case 'Indirizzo_contraente_A': return GlobalData.Indirizzo_contraente_A;
case 'CAP_contraente_A': return GlobalData.CAP_contraente_A;
case 'Stato_contraente_A': return GlobalData.Stato_contraente_A;
case 'N_telefono_mail_contraente_A': return GlobalData.N_telefono_mail_contraente_A;
case 'N_telefono_mail_contraente_A':
return GlobalData.Email_contraente_A.isNotEmpty
? "${GlobalData.N_telefono_mail_contraente_A} - ${GlobalData.Email_contraente_A}"
: GlobalData.N_telefono_mail_contraente_A;
case 'Marca_e_Tipo_A': return GlobalData.Marca_e_Tipo_A;
case 'Targa_A': return GlobalData.Targa_A;
case 'Stato_immatricolazione_A': return GlobalData.Stato_immatricolazione_A;
@ -470,7 +473,10 @@ class PdfEngine {
case 'Cod_fiscale_cond_A': return GlobalData.Cod_fiscale_cond_A;
case 'Indirizzo_cond_A': return GlobalData.Indirizzo_cond_A;
case 'Stato_cond_A': return GlobalData.Stato_cond_A;
case 'N_tel_mail_cond_A': return GlobalData.N_tel_mail_cond_A;
case 'N_tel_mail_cond_A':
return GlobalData.Email_cond_A.isNotEmpty
? "${GlobalData.N_tel_mail_cond_A} - ${GlobalData.Email_cond_A}"
: GlobalData.N_tel_mail_cond_A;
case 'N_Patente_cond_A': return GlobalData.N_Patente_cond_A;
case 'Scadenza_cond_A': return GlobalData.Scadenza_cond_A;
case 'Cognome_contraente_B': return GlobalData.Cognome_contraente_B;
@ -479,7 +485,10 @@ class PdfEngine {
case 'Indirizzo_contraente_B': return GlobalData.Indirizzo_contraente_B;
case 'CAP_contraente_B': return GlobalData.CAP_contraente_B;
case 'Stato_contraente_B': return GlobalData.Stato_contraente_B;
case 'N_telefono_mail_contraente_B': return GlobalData.N_telefono_mail_contraente_B;
case 'N_telefono_mail_contraente_B':
return GlobalData.Email_contraente_B.isNotEmpty
? "${GlobalData.N_telefono_mail_contraente_B} - ${GlobalData.Email_contraente_B}"
: GlobalData.N_telefono_mail_contraente_B;
case 'Marca_e_Tipo_B': return GlobalData.Marca_e_Tipo_B;
case 'Targa_B': return GlobalData.Targa_B;
case 'Stato_immatricolazione_B': return GlobalData.Stato_immatricolazione_B;
@ -501,7 +510,10 @@ class PdfEngine {
case 'Cod_fiscale_cond_B': return GlobalData.Cod_fiscale_cond_B;
case 'Indirizzo_cond_B': return GlobalData.Indirizzo_cond_B;
case 'Stato_cond_B': return GlobalData.Stato_cond_B;
case 'N_tel_mail_cond_B': return GlobalData.N_tel_mail_cond_B;
case 'N_tel_mail_cond_B':
return GlobalData.Email_cond_B.isNotEmpty
? "${GlobalData.N_tel_mail_cond_B} - ${GlobalData.Email_cond_B}"
: GlobalData.N_tel_mail_cond_B;
case 'N_Patente_cond_B': return GlobalData.N_Patente_cond_B;
case 'Scadenza_cond_B': return GlobalData.Scadenza_cond_B;
default: return "";

View file

@ -16,7 +16,8 @@ class ProfiloService {
await prefs.setString('${_prefix}indirizzo_contraente', isA ? GlobalData.Indirizzo_contraente_A : GlobalData.Indirizzo_contraente_B);
await prefs.setString('${_prefix}cap_contraente', isA ? GlobalData.CAP_contraente_A : GlobalData.CAP_contraente_B);
await prefs.setString('${_prefix}stato_contraente', isA ? GlobalData.Stato_contraente_A : GlobalData.Stato_contraente_B);
await prefs.setString('${_prefix}tel_contraente', isA ? GlobalData.N_telefono_mail_contraente_A : GlobalData.N_telefono_mail_contraente_B);
await prefs.setString('user_tel', lato == 'A' ? GlobalData.N_telefono_mail_contraente_A : GlobalData.N_telefono_mail_contraente_B);
await prefs.setString('user_email', lato == 'A' ? GlobalData.Email_contraente_A : GlobalData.Email_contraente_B);
await prefs.setString('${_prefix}marca_tipo', isA ? GlobalData.Marca_e_Tipo_A : GlobalData.Marca_e_Tipo_B);
await prefs.setString('${_prefix}targa', isA ? GlobalData.Targa_A : GlobalData.Targa_B);
@ -33,7 +34,8 @@ class ProfiloService {
await prefs.setString('${_prefix}data_nascita_cond', isA ? GlobalData.Data_nascita_cond_A : GlobalData.Data_nascita_cond_B);
await prefs.setString('${_prefix}cf_cond', isA ? GlobalData.Cod_fiscale_cond_A : GlobalData.Cod_fiscale_cond_B);
await prefs.setString('${_prefix}indirizzo_cond', isA ? GlobalData.Indirizzo_cond_A : GlobalData.Indirizzo_cond_B);
await prefs.setString('${_prefix}tel_cond', isA ? GlobalData.N_tel_mail_cond_A : GlobalData.N_tel_mail_cond_B);
await prefs.setString('user_cond_tel', lato == 'A' ? GlobalData.N_tel_mail_cond_A : GlobalData.N_tel_mail_cond_B);
await prefs.setString('user_cond_email', lato == 'A' ? GlobalData.Email_cond_A : GlobalData.Email_cond_B);
await prefs.setString('${_prefix}patente_cond', isA ? GlobalData.N_Patente_cond_A : GlobalData.N_Patente_cond_B);
await prefs.setString('${_prefix}scadenza_cond', isA ? GlobalData.Scadenza_cond_A : GlobalData.Scadenza_cond_B);
}
@ -59,7 +61,8 @@ class ProfiloService {
GlobalData.Indirizzo_contraente_A = getStr('indirizzo_contraente');
GlobalData.CAP_contraente_A = getStr('cap_contraente');
GlobalData.Stato_contraente_A = getStr('stato_contraente');
GlobalData.N_telefono_mail_contraente_A = getStr('tel_contraente');
GlobalData.N_telefono_mail_contraente_A = prefs.getString('user_tel') ?? "";
GlobalData.Email_contraente_A = prefs.getString('user_email') ?? "";
GlobalData.Marca_e_Tipo_A = getStr('marca_tipo');
GlobalData.Targa_A = getStr('targa');
@ -74,7 +77,8 @@ class ProfiloService {
GlobalData.Data_nascita_cond_A = getStr('data_nascita_cond');
GlobalData.Cod_fiscale_cond_A = getStr('cf_cond');
GlobalData.Indirizzo_cond_A = getStr('indirizzo_cond');
GlobalData.N_tel_mail_cond_A = getStr('tel_cond');
GlobalData.N_tel_mail_cond_A = prefs.getString('user_cond_tel') ?? "";
GlobalData.Email_cond_A = prefs.getString('user_cond_email') ?? "";
GlobalData.N_Patente_cond_A = getStr('patente_cond');
GlobalData.Scadenza_cond_A = getStr('scadenza_cond');
} else {
@ -84,7 +88,8 @@ class ProfiloService {
GlobalData.Indirizzo_contraente_B = getStr('indirizzo_contraente');
GlobalData.CAP_contraente_B = getStr('cap_contraente');
GlobalData.Stato_contraente_B = getStr('stato_contraente');
GlobalData.N_telefono_mail_contraente_B = getStr('tel_contraente');
GlobalData.N_telefono_mail_contraente_B = prefs.getString('user_tel') ?? "";
GlobalData.Email_contraente_B = prefs.getString('user_email') ?? "";
GlobalData.Marca_e_Tipo_B = getStr('marca_tipo');
GlobalData.Targa_B = getStr('targa');
@ -99,7 +104,8 @@ class ProfiloService {
GlobalData.Data_nascita_cond_B = getStr('data_nascita_cond');
GlobalData.Cod_fiscale_cond_B = getStr('cf_cond');
GlobalData.Indirizzo_cond_B = getStr('indirizzo_cond');
GlobalData.N_tel_mail_cond_B = getStr('tel_cond');
GlobalData.N_tel_mail_cond_B = prefs.getString('user_cond_tel') ?? "";
GlobalData.Email_cond_B = prefs.getString('user_cond_email') ?? "";
GlobalData.N_Patente_cond_B = getStr('patente_cond');
GlobalData.Scadenza_cond_B = getStr('scadenza_cond');
}

View file

@ -1,5 +1,8 @@
# Change Log
- **2026-04-28**: Modificato il campo "Telefono / Email" in due campi separati in `comp_6-7.dart` (Contraente) e `comp_9.dart` (Conducente) con implementazione Regex per formati internazionali ed email. Aggiornata logica `pdf_engine.dart` per stampare la stringa concatenata nel PDF e aggiornato il salvataggio locale `profilo_service.dart`.
- **2026-04-28**: Aggiornata la versione di Kotlin a 2.1.0 in `android/build.gradle` per conformità alle nuove specifiche di Flutter, superando la dipendenza obsoleta rimossa da `pdf_render`.
- **2026-04-28**: Implementata Autocompilazione (Ricorda i miei dati). Creato `ProfiloService` con persistenza locale via `shared_preferences`. Aggiunto popup "Vuoi usare i dati salvati?" su `comp_6-7.dart` e workflow "silenzioso" su `comp_9.dart`.
- **2026-04-24**: Implementazione In-App Purchases (RevenueCat) con aggiunta del plugin `purchases_flutter`. Creato `SubscriptionService`, aggiunto campo `isPro` in `GlobalData`, e costruito il Paywall Custom (Glassmorphism) per bloccare la funzionalità "Scambio Dati" agli utenti non paganti.
- **2026-04-24**: Sostituiti tutti i metodi deprecati `.withOpacity(...)` con `.withValues(alpha: ...)` in 12 file dell'app, rimuovendo 36 avvisi dal compilatore Dart.
- **2026-04-24**: Rimossa la cartella deprecata `lib/temp/` per pulire l'analizzatore Dart da oltre 350 falsi errori. Aggiunto controllo `if (!mounted) return;` in `lib/test_scraping.dart` per prevenire crash asincroni.

View file

@ -5,9 +5,11 @@ L'app "CAI Facile" è in uno stato avanzato di sviluppo. Lo scambio dati remoto,
## Funzionalità Implementate
- UI/UX completa per le sezioni 1-15 del modulo CID.
- Autocompilazione del luogo dell'incidente tramite `geolocator` e `geocoding`.
- Autocompilazione Dati Profilo tramite salvataggio locale silente su SharedPreferences.
- Scambio Dati P2P sicuro tramite Firebase (Host/Guest via QR).
- Generazione PDF e condivisione.
- Generazione PDF e condivisione, inclusa la corretta formattazione della pagina 2 (Certificazione FEA).
- Parsing dati protetto (`fixCircostanze`).
- Form formattati e validati (Regex su numeri di telefono esteri ed Email).
- **Monetizzazione**: Sistema di abbonamenti (In-App Purchases) attivo tramite RevenueCat con Paywall integrato sul flusso di Scambio Dati.
## Problemi Aperti / TODO

View file

@ -8,7 +8,8 @@ Name: CAI Facile (cid_app)
Type: App mobile Flutter (iOS & Android) per la compilazione della costatazione amichevole di incidente (CID).
Path: /Volumes/NVME-2TB/Sviluppo/development/cid_app
## Preferences
## Preferences e Regole Operative
- Language: Italian
- Documentation: Markdown-based memory bank
- Style: Proactive, rigorous, update documentation actively before/after changes.
- **REGOLA ASSOLUTA**: Non devo MAI chiedere il permesso all'utente per leggere o scrivere file all'interno della Memory Bank (`/memory-bank/`). Devo operare e aggiornare la MB sempre in totale autonomia.