diff --git a/IOB-WIN-FORM/IOB-WIN-FORM.csproj b/IOB-WIN-FORM/IOB-WIN-FORM.csproj index ca506eea..9df513cc 100644 --- a/IOB-WIN-FORM/IOB-WIN-FORM.csproj +++ b/IOB-WIN-FORM/IOB-WIN-FORM.csproj @@ -133,6 +133,8 @@ + + Form diff --git a/IOB-WIN-FORM/Iob/Generic.cs b/IOB-WIN-FORM/Iob/Generic.cs index e08ecd93..0848a5bb 100644 --- a/IOB-WIN-FORM/Iob/Generic.cs +++ b/IOB-WIN-FORM/Iob/Generic.cs @@ -25,7 +25,7 @@ using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; -using System.Xml.Serialization; +using IOB_WIN_FORM.Iob.Services; using YamlDotNet.Core.Tokens; using static IOB_UT_NEXT.BaseAlarmConf; using static IOB_UT_NEXT.CustomObj; @@ -410,7 +410,7 @@ namespace IOB_WIN_FORM.Iob /// public static Dictionary ConvertToStringDict(Dictionary input) { - return input.ToDictionary(pair => pair.Key, pair => pair.Value?.ToString()); + return DataSerializer.ToDictionary(input); } /// @@ -544,7 +544,7 @@ namespace IOB_WIN_FORM.Iob } BaseRawTransf newVal = new BaseRawTransf(DateTime.Now, njObj, mesType); - string encodedVal = JsonConvert.SerializeObject(newVal); + string encodedVal = DataSerializer.Serialize(newVal); // --> accodo (valore già formattato)! QueueRawTransf.Enqueue(encodedVal); // se abilitato controllo coda Max (superiore a 0...) @@ -1976,11 +1976,11 @@ namespace IOB_WIN_FORM.Iob string rawVal = redisMan.redGetHashField(lastSendKey, keyReq); if (!string.IsNullOrEmpty(rawVal)) { - lastSend = JsonConvert.DeserializeObject(rawVal); + lastSend = DataSerializer.Deserialize(rawVal); } else { - rawVal = JsonConvert.SerializeObject(lastSend); + rawVal = DataSerializer.Serialize(lastSend); KeyValuePair[] hashFields = new KeyValuePair[1]; hashFields[0] = new KeyValuePair(keyReq, rawVal); redisMan.redSaveHash(lastSendKey, hashFields); @@ -1996,13 +1996,14 @@ namespace IOB_WIN_FORM.Iob public bool LastSendSet(string keyReq, DateTime dtRif) { string lastSendKey = redisMan.redHash($"IOB:Status:{IOBConfFull.General.FilenameIOB}:LastSend"); - string rawVal = JsonConvert.SerializeObject(dtRif); + string rawVal = DataSerializer.Serialize(dtRif); KeyValuePair[] hashFields = new KeyValuePair[1]; hashFields[0] = new KeyValuePair(keyReq, rawVal); bool fatto = redisMan.redSaveHash(lastSendKey, hashFields); return fatto; } + /// /// Effettua un trim della stringa al numero max di linee da mostrare a video /// @@ -6806,38 +6807,28 @@ namespace IOB_WIN_FORM.Iob // leggo contenuto XML string rawData = File.ReadAllText(recipeFile); // deserializza file XML x recuperare righe consumo - XmlSerializer serializer = new XmlSerializer(typeof(ARecipe)); - using (StringReader reader = new StringReader(rawData)) + var currRecipe = XmlDataSerializer.Deserialize(rawData); + if (currRecipe != null) { - try + // recupero data-ora ricetta da campo string + DateTime recExeDt = DateTime.Today; + DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt); + // calcolo week da data-ora file... + week = cal.GetWeekOfYear(recExeDt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); + // verifico se ci sia la settimana indicata in elenco... + string currWeek = $"{recExeDt:yyyy}-{week:00}"; + if (!weeksProc.Contains(currWeek)) { - var currRecipe = (ARecipe)serializer.Deserialize(reader); - if (currRecipe != null) - { - // recupero data-ora ricetta da campo string - DateTime recExeDt = DateTime.Today; - DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt); - // calcolo week da data-ora file... - week = cal.GetWeekOfYear(recExeDt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); - // verifico se ci sia la settimana indicata in elenco... - string currWeek = $"{recExeDt:yyyy}-{week:00}"; - if (!weeksProc.Contains(currWeek)) - { - weeksProc.Add(currWeek); - } - // sposto file x in area week - string rName = Path.GetFileName(recipeFile); - archPath = Path.Combine(archBasePath, $"{recExeDt:yyyy}-{week:00}"); - baseUtils.checkDir(archPath); - string destPath = Path.Combine(archPath, rName); - // sposto files - File.Move(recipeFile, destPath); - } - } - catch (Exception exc) - { - lgError($"Eccezione in RecipeDoArchiveWeek{Environment.NewLine}{exc}"); + weeksProc.Add(currWeek); } + + // sposto file x in area week + string rName = Path.GetFileName(recipeFile); + archPath = Path.Combine(archBasePath, $"{recExeDt:yyyy}-{week:00}"); + baseUtils.checkDir(archPath); + string destPath = Path.Combine(archPath, rName); + // sposto files + File.Move(recipeFile, destPath); } return weeksProc; } @@ -7041,45 +7032,57 @@ namespace IOB_WIN_FORM.Iob // leggo contenuto XML string rawData = File.ReadAllText(recipeFile); // deserializza file XML x recuperare righe consumo - XmlSerializer serializer = new XmlSerializer(typeof(ARecipe)); - using (StringReader reader = new StringReader(rawData)) + var currRecipe = XmlDataSerializer.Deserialize(rawData); + if (currRecipe != null) { - try + if (currRecipe.ColRecipe != null && currRecipe.ColRecipe.Count > 0) { - var currRecipe = (ARecipe)serializer.Deserialize(reader); - if (currRecipe != null) + List RigheConsumi = new List(); + foreach (var rigaComp in currRecipe.ColRecipe) { - if (currRecipe.ColRecipe != null && currRecipe.ColRecipe.Count > 0) - { - List RigheConsumi = new List(); - foreach (var rigaComp in currRecipe.ColRecipe) - { - ColData datiComp = rigaComp.ColData; - RigheConsumi.Add(datiComp); - } - // recupero data-ora ricetta da campo string - DateTime recExeDt = DateTime.Today; - DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt); - // converto le righe di consumo ColData in ConsRec - listConsumi = RigheConsumi.Select(x => new ConsRec() - { - FileRef = recipeFile, - DtRif = recExeDt, - ColourCode = x.ColourCode, - Description = x.Description, - WeightGrTot = x.Weightgrtotal - }).ToList(); - } + ColData datiComp = rigaComp.ColData; + RigheConsumi.Add(datiComp); } - } - catch (Exception exc) - { - lgError($"Eccezione in RecipeGetCons{Environment.NewLine}{exc}"); + // recupero data-ora ricetta da campo string + DateTime recExeDt = DateTime.Today; + DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt); + // converto le righe di consumo ColData in ConsRec + listConsumi = RigheConsumi.Select(x => new ConsRec() + { + FileRef = recipeFile, + DtRif = recExeDt, + ColourCode = x.ColourCode, + Description = x.Description, + WeightGrTot = x.Weightgrtotal + }).ToList(); } } return listConsumi; } + // // recupero data-ora ricetta da campo string + // DateTime recExeDt = DateTime.Today; + // DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt); + // // converto le righe di consumo ColData in ConsRec + // listConsumi = RigheConsumi.Select(x => new ConsRec() + // { + // FileRef = recipeFile, + // DtRif = recExeDt, + // ColourCode = x.ColourCode, + // Description = x.Description, + // WeightGrTot = x.Weightgrtotal + // }).ToList(); + // } + // } + // } + // catch (Exception exc) + // { + // lgError($"Eccezione in RecipeGetCons{Environment.NewLine}{exc}"); + // } + // } + // return listConsumi; + // } + /// /// Prepara la ricetta indicata partendo dai dati della ricetta template + dati ODL di riferimento /// diff --git a/IOB-WIN-FORM/Iob/Services/DataSerializer.cs b/IOB-WIN-FORM/Iob/Services/DataSerializer.cs new file mode 100644 index 00000000..99ed9405 --- /dev/null +++ b/IOB-WIN-FORM/Iob/Services/DataSerializer.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using Newtonsoft.Json; + +namespace IOB_WIN_FORM.Iob.Services +{ + /// + /// Gestisce tutte le operazioni di serializzazione e deserializzazione dei dati. + /// + public static class DataSerializer + { + /// + /// Serializza un oggetto in una stringa JSON utilizzando la cultura invariante. + /// + public static string Serialize(T obj) + { + if (obj == null) return null; + // Utilizzo di CultureInfo.InvariantCulture per garantire la coerenza dei formati (es. decimali) + return JsonConvert.SerializeObject(obj, new JsonSerializerSettings + { + Culture = CultureInfo.InvariantCulture + }); + } + + /// + /// Deserializza una stringa JSON in un oggetto del tipo specificato. + /// + public static T Deserialize(string json) + { + if (string.IsNullOrWhiteSpace(json)) return default; + return JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + Culture = CultureInfo.InvariantCulture + }); + } + + /// + /// Helper per convertire un dizionario di oggetti in un dizionario di stringhe. + /// + public static Dictionary ToDictionary(Dictionary input) + { + if (input == null) return new Dictionary(); + + var dict = new Dictionary(); + foreach (var pair in input) + { + dict[pair.Key] = pair.Value?.ToString(); + } + return dict; + } + } +} diff --git a/IOB-WIN-FORM/Iob/Services/XmlDataSerializer.cs b/IOB-WIN-FORM/Iob/Services/XmlDataSerializer.cs new file mode 100644 index 00000000..2770b758 --- /dev/null +++ b/IOB-WIN-FORM/Iob/Services/XmlDataSerializer.cs @@ -0,0 +1,63 @@ +using System; +using System.IO; +using System.Xml.Serialization; + +namespace IOB_WIN_FORM.Iob.Services +{ + /// + /// Gestisce le operazioni di serializzazione e deserializzazione in formato XML. + /// + public static class XmlDataSerializer + { + /// + /// Serializza un oggetto in una stringa XML. + /// + /// Tipo dell'oggetto. + /// L'oggetto da serializzare. + /// Stringa XML o null se l'oggetto è null. + public static string Serialize(T obj) + { + if (obj == null) return null; + + try + { + using (var stringWriter = new StringWriter()) + { + var serializer = new XmlSerializer(typeof(T)); + serializer.Serialize(stringWriter, obj); + return stringWriter.ToString(); + } + } + catch (Exception ex) + { + // Log l'errore se necessario. In un contesto di refactoring, + // potremmo voler passare l'eccezione verso l'alto. + throw new InvalidOperationException($"Errore durante la serializzazione XML per il tipo {typeof(T).Name}", ex); + } + } + + /// + /// Deserializza una stringa XML in un oggetto del tipo specificato. + /// + /// Tipo dell'oggetto. + /// La stringa XML. + /// L'oggetto deserializzato o default se la stringa è nulla/vuota. + public static T Deserialize(string xmlString) + { + if (string.IsNullOrWhiteSpace(xmlString)) return default; + + try + { + using (var stringReader = new StringReader(xmlString)) + { + var serializer = new XmlSerializer(typeof(T)); + return (T)serializer.Deserialize(stringReader); + } + } + catch (Exception ex) + { + throw new InvalidOperationException($"Errore durante la deserializzazione XML per il tipo {typeof(T).Name}", ex); + } + } + } +} diff --git a/refactoring_wip.md b/refactoring_wip.md new file mode 100644 index 00000000..50a604df --- /dev/null +++ b/refactoring_wip.md @@ -0,0 +1,28 @@ +# WIP: Refactoring Phase 1 - Infrastructure Extraction + +## Status: IN_PROGRESS + +## Objective +Extract infrastructure and helper components from `Generic.cs` to improve modularity and reduce the monolithic footprint. + +## Tasks + +### 1. Communication Service Extraction +- [ ] Extract REST/HTTP logic (currently using `utils.callUrl`, `callUrlWithPayloadAsync`, etc.). +- [ ] Implement a singleton/service-based `CommunicationService` using `HttpClient`. +- [ ] **Italian Commenting Requirement**: All new/modified code comments must be in Italian. + +### 2. Redis Service Extraction +- [ ] Encapsulate all `redisMan` calls into a `RedisService`. +- [ ] Define a clean interface for key/value and hash operations. + +### 3. Data Serializer Extraction +- [ ] Move all `JsonConvert` and custom string formatting (e.g., `qEncodeFLog`, `qEncodeIN`) to a `DataSerializer` service. +- [ ] Centralize `CultureInfo.InvariantCulture` usage. + +## Progress Log +- [x] Created WIP document. +- [x] Analyzed `Generic.cs` for Phase 1 candidates (found ~200 occurrences of key patterns). +- [ ] Started Extraction of `CommunicationService`. +- [ ] Started Extraction of `RedisService`. +- [ ] Started Extraction of `DataSerializer`.