From 62015933eecad072f8e0de77e8e09a484edf0e88 Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 28 Apr 2026 20:20:45 +0200 Subject: [PATCH] Auto-sync: 20260428_202037 --- .DS_Store | Bin 26628 -> 26628 bytes lib/comp_6-7.dart | 34 ++++++++++++++--- lib/comp_9.dart | 59 +++++++++++++++++++++--------- lib/global_data.dart | 24 ++++++------ lib/pdf_engine.dart | 20 ++++++++-- lib/services/profilo_service.dart | 18 ++++++--- memory-bank/change-log.md | 3 ++ memory-bank/current-state.md | 4 +- memory-bank/identity.md | 3 +- 9 files changed, 117 insertions(+), 48 deletions(-) diff --git a/.DS_Store b/.DS_Store index 4a581b46df48d4d3bd9575a9fd2e0f32801ade2c..7ad62e394a641057066edcb66b1d98dbb91f9866 100644 GIT binary patch delta 575 zcmaLTPe{{Y9LMqJ{bc(?g0s@OpXiJgRxarjgwh{!7Gx%F>Xys4+%Me0S=%Tm$x1H~ z(cD8F%DiT*Aecp9B?}Vi4=k__MMjq>s16m~f_`n@f}YFg`SQJdKd-SoV|ng$`PrsE zY_*%Zd;EdYURCZom9AK2^+)@MV&3RUT}`=am+fimP}iy&rSz(7!wfk!i^uDx14RW;0Drii_NQI?j?402s0j!T { - 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 { _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 { _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 { 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 { 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 { 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 { ] ), - _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 { _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(); diff --git a/lib/comp_9.dart b/lib/comp_9.dart index 5cb32fd..987c704 100644 --- a/lib/comp_9.dart +++ b/lib/comp_9.dart @@ -29,7 +29,7 @@ class Comp9Screen extends StatefulWidget { } class _Comp9ScreenState extends State { - 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 { _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 { _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 { _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 { _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 { 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 { 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 { 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 { _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 { @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(); } } \ No newline at end of file diff --git a/lib/global_data.dart b/lib/global_data.dart index c77b2a8..28acf01 100644 --- a/lib/global_data.dart +++ b/lib/global_data.dart @@ -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 puntiUrtoA_List = []; static String danni_visibili_A = ""; static String osservazioni_A = ""; static Map circostanzeA = {}; static int totaleCrocetteA = 0; static List 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 puntiUrtoB_List = []; static String danni_visibili_B = ""; static String osservazioni_B = ""; static Map circostanzeB = {}; static int totaleCrocetteB = 0; static List 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)]; diff --git a/lib/pdf_engine.dart b/lib/pdf_engine.dart index 180210e..3612e54 100644 --- a/lib/pdf_engine.dart +++ b/lib/pdf_engine.dart @@ -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 ""; diff --git a/lib/services/profilo_service.dart b/lib/services/profilo_service.dart index e5b257f..c2989b7 100644 --- a/lib/services/profilo_service.dart +++ b/lib/services/profilo_service.dart @@ -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'); } diff --git a/memory-bank/change-log.md b/memory-bank/change-log.md index a9b4b39..43e847b 100644 --- a/memory-bank/change-log.md +++ b/memory-bank/change-log.md @@ -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. diff --git a/memory-bank/current-state.md b/memory-bank/current-state.md index 141b6a5..12dd667 100644 --- a/memory-bank/current-state.md +++ b/memory-bank/current-state.md @@ -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 diff --git a/memory-bank/identity.md b/memory-bank/identity.md index 52b0d49..6847825 100644 --- a/memory-bank/identity.md +++ b/memory-bank/identity.md @@ -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.