using GPW.CORE.Api.Data; using GPW.CORE.Data.DbModels; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using NLog; using System.Diagnostics; using System.Text; namespace GPW.CORE.Api.Controllers { [Route("api/[controller]")] [ApiController] public class TimbraCheckController : ControllerBase { #region Public Constructors /// /// Avvio controller x CheckProgetti /// /// /// /// /// public TimbraCheckController(ILogger logger, IConfiguration configuration, IEmailSender emailSender, ApiDataService DataService) { _configuration = configuration; _emailSender = emailSender; ADService = DataService; Log.Info("Avviata classe TimbraCheck"); } #endregion Public Constructors #region Public Methods /// /// Effettua verifiche DailyDuties sulle timbrature /// /// [HttpGet("DailyCheck")] public async Task Get() { string answ = "ND"; // verifico se ci siano record check odierni... DateTime inizio = DateTime.Today; DateTime fine = inizio.AddDays(1); var dailyChecks = await ADService.RegEventiGetFilt(inizio, fine, "checkAnomalie"); // cerco se sia già stato fatto altrimenti ripeto... if (dailyChecks != null && dailyChecks.Count > 0) { // loggo solo che è stato richeisto di nuovo... var currCheck = dailyChecks[0]; answ = $"Already Done | {currCheck.DataOra} | {currCheck.Evento} | {currCheck.Commento}"; Log.Info("DailyCheck non eseguito: già registrato per la giornata"); } else { Log.Info("Richiesto controllo anomalie!"); // registro evento check effettuato... RegistroEventiModel newRec = new RegistroEventiModel() { DataOra = DateTime.Now, Evento = "dailyDuties", Commento = "-" }; bool fatto = await ADService.RegEventiUpdate(newRec); /******************************************************* * controllo le varie anomalie delle timbrature: * * (A) mancate approvazioni --> admin * (B) entrate <> uscite --> admin, user * (C) mancata copertura orario --> admin * (D) mancata copertura commesse --> admin * (E) anomalia orario continuato --> admin * (F) ricalcolo perm mese prec --> admin * (G) ricalcolo perm mese corr --> admin * * recupero elenco dip interessati x le varie anomalie con stp_DipendentiAndAnomalie * e poi da timbrExpl recupero le singole istanze di record errori * *******************************************************/ // oggetti base StringBuilder sbMain = new StringBuilder(); DateTime oggi = DateTime.Today; DateTime oggiFine = oggi.AddDays(1).AddSeconds(-1); string adminDestEmail = _configuration.GetValue("MailDest:TimbCheck") ?? "samuele@steamware.net"; string baseUrl = _configuration.GetValue("ServerConv:baseUrl") ?? "https://office.egalware.com/GPW/ADMIN/"; bool checkAnomAppr = _configuration.GetValue("TimbraCheck:checkAnomAppr"); bool checkAnomTimb = _configuration.GetValue("TimbraCheck:checkAnomTimb"); bool checkAnomOreLav = _configuration.GetValue("TimbraCheck:checkAnomOreLav"); bool checkAnomOreLavComm = _configuration.GetValue("TimbraCheck:checkAnomOreLavComm"); bool checkAnomContinuato = _configuration.GetValue("TimbraCheck:checkAnomContinuato"); bool checkPermMesePrev = _configuration.GetValue("TimbraCheck:checkPermMesePrev"); bool checkPermMeseCurr = _configuration.GetValue("TimbraCheck:checkPermMeseCurr"); bool sendEmailToUser = _configuration.GetValue("TimbraCheck:sendEmailToUser"); bool includeDirectUrl = _configuration.GetValue("TimbraCheck:includeDirectUrl"); int gg2Chk = _configuration.GetValue("TimbraCheck:gg2Chk"); int gg2ChkCont = _configuration.GetValue("TimbraCheck:gg2ChkCont"); int gg2ChkOreCaricate = _configuration.GetValue("TimbraCheck:gg2ChkOreCaricate"); int maxErrMin = _configuration.GetValue("TimbraCheck:maxErrMin"); int maxErrPlus = _configuration.GetValue("TimbraCheck:maxErrPlus"); int maxDaycheckPermMesePrev = _configuration.GetValue("TimbraCheck:maxDaycheckPermMesePrev"); string msgTopic = ""; string msgBody = ""; int numChk = 0; int numErr = 0; string headRow = "style=\"background-color: #232323; color: #DEDEDE\""; string stripeRow = "style=\"background-color: #DEDEDE;\""; Dictionary anomCount = new Dictionary(); int lastCount = 0; ///elenco dipendenti (per tutti i casi ove necessario) var tabElencoDip = await ADService.DipendentiGetAll(); // (A) recupero mancate approvazioni, mando solo ad admin if (checkAnomAppr) { numChk++; sbMain = new StringBuilder(); var tabTimbExpl = await ADService.TimbExplGetAnomalie(0, oggi.AddDays(-gg2Chk), oggiFine, true, false, false); // se ho trovato record... if (tabTimbExpl != null && tabTimbExpl.Count > 0) { doLog("Trovate anomalie mancate approvazioni, invio email ad admin", logType.info, ref sbMain); msgTopic = "Anomalie GPW: Approvazione Timbrature"; if (includeDirectUrl) { doLog($"Risultano a sistema le seguenti anomalie:{Environment.NewLine}timbrature da approvare{Environment.NewLine}", logType.info, ref sbMain); } else { doLog($"Risultano a sistema le seguenti anomalie: timbrature da approvare{Environment.NewLine}", logType.info, ref sbMain); } // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); int nRow = 0; foreach (var riga in tabTimbExpl) { string sfondo = nRow % 2 == 0 ? "" : stripeRow; doLog($"", logType.none, ref sbMain); numErr++; nRow++; } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{riga.DataLav:yyyy.MM.dd ddd}{riga.CognomeNome}
", logType.none, ref sbMain); msgBody = sbMain.ToString(); await sendEmail(adminDestEmail, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); // salvo anomCount.Add("Check A: Mancate approvazioni", numErr - lastCount); lastCount = numErr; } } // (B1) recupero errori entrate/uscite, mando ad admin + utenti if (checkAnomTimb) { numChk++; sbMain = new StringBuilder(); var tabDipAndAnom = await ADService.DipAndAnomGetAll(oggi.AddDays(-gg2Chk), oggi.AddHours(1), false, true, false); var tabTimbExpl = await ADService.TimbExplGetAnomalie(0, oggi.AddDays(-gg2Chk), oggiFine, false, true, false); // se ho trovato record... if (tabTimbExpl != null && tabTimbExpl.Count > 0) { doLog("Trovate anomalie timbrature IN/OUT non corrispondenti, invio email!", logType.info, ref sbMain); // mando email ad admin! msgTopic = "Anomalie GPW: Timbrature mancanti"; if (includeDirectUrl) { doLog($"Risultano a sistema le seguenti anomalie:{Environment.NewLine}timbrature mancanti{Environment.NewLine}", logType.info, ref sbMain); } else { doLog($"Risultano a sistema le seguenti anomalie: timbrature mancanti{Environment.NewLine}", logType.info, ref sbMain); } // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); int nRow = 0; foreach (var riga in tabTimbExpl) { string sfondo = nRow % 2 == 0 ? "" : stripeRow; doLog($"", logType.none, ref sbMain); numErr++; nRow++; } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{riga.DataLav:yyyy.MM.dd ddd}{riga.CognomeNome}
", logType.none, ref sbMain); msgBody = sbMain.ToString(); await sendEmail(adminDestEmail, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); // re richiesto invio email utenti x warning entrate/uscrite if (sendEmailToUser) { // mando singole email ai dipendenti SE C'è EMAIL!!!! foreach (var rigaDip in tabDipAndAnom) { sbMain = new StringBuilder(); if (!string.IsNullOrEmpty(rigaDip.email)) { var tabTimbExplDip = tabTimbExpl.Where(x => x.IdxDipendente == rigaDip.IdxDipendente); // reimposto testo doLog($"Risultano a sistema le seguenti anomalie: timbrature mancanti{Environment.NewLine}", logType.info, ref sbMain); // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); nRow = 0; foreach (var riga in tabTimbExplDip) { string sfondo = nRow % 2 == 0 ? "" : stripeRow; doLog($"", logType.none, ref sbMain); nRow++; } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{riga.DataLav:yyyy.MM.dd ddd}{riga.CognomeNome}
", logType.none, ref sbMain); msgBody = sbMain.ToString(); await sendEmail(rigaDip.email, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); } } } // salvo anomCount.Add("Check B1: Entrate/Uscite", numErr - lastCount); lastCount = numErr; } } // (B2) recupero errori timbrature FUTURE, mando ad admin + utenti if (checkAnomTimb) { List ElencoDip2Send = new List(); numChk++; sbMain = new StringBuilder(); var tabTimbFuture = await ADService.TimbratureAnomalieFuture(); // se ho trovato record... if (tabTimbFuture != null && tabTimbFuture.Count > 0) { doLog("Trovate anomalie timbrature FUTURE, invio email!", logType.info, ref sbMain); // mando email ad admin! msgTopic = "Anomalie GPW: Timbrature FUTURE"; if (includeDirectUrl) { doLog($"Risultano a sistema le seguenti anomalie:{Environment.NewLine}timbrature FUTURE{Environment.NewLine}", logType.info, ref sbMain); } else { doLog($"Risultano a sistema le seguenti anomalie: timbrature FUTURE{Environment.NewLine}", logType.info, ref sbMain); } // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); int nRow = 0; foreach (var riga in tabTimbFuture) { string sfondo = nRow % 2 == 0 ? "" : stripeRow; var rigaDip = tabElencoDip.Find(x => x.IdxDipendente == riga.IdxDipendente); if (rigaDip != null) { ElencoDip2Send.Add(rigaDip); } string cognomeNome = rigaDip != null ? $"{rigaDip.Cognome} {rigaDip.Nome}" : $"idxDip: {riga.IdxDipendente}"; doLog($"", logType.none, ref sbMain); numErr++; nRow++; } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{riga.DataOra:yyyy.MM.dd ddd}{cognomeNome}
", logType.none, ref sbMain); msgBody = sbMain.ToString(); await sendEmail(adminDestEmail, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); // re richiesto invio email utenti x warning entrate/uscrite if (sendEmailToUser) { // mando singole email ai dipendenti SE C'è EMAIL!!!! foreach (var rigaDip in ElencoDip2Send) { sbMain = new StringBuilder(); if (!string.IsNullOrEmpty(rigaDip.Email)) { var tabTimbExplDip = tabTimbFuture.Where(x => x.IdxDipendente == rigaDip.IdxDipendente); // reimposto testo doLog($"Risultano a sistema le seguenti anomalie: timbrature FUTURE{Environment.NewLine}", logType.info, ref sbMain); // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); nRow = 0; foreach (var riga in tabTimbExplDip) { string sfondo = nRow % 2 == 0 ? "" : stripeRow; doLog($"", logType.none, ref sbMain); nRow++; } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{riga.DataOra:yyyy.MM.dd ddd}{rigaDip.Cognome} {rigaDip.Nome}
", logType.none, ref sbMain); msgBody = sbMain.ToString(); await sendEmail(rigaDip.Email, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); } } } // salvo anomCount.Add("Check B2: Timbrature Future", numErr - lastCount); lastCount = numErr; } } // (C) recupero errori mancata copertura orario, mando ad admin if (checkAnomOreLav) { numChk++; sbMain = new StringBuilder(); var tabTimbExpl = await ADService.TimbExplGetAnomalie(0, oggi.AddDays(-gg2Chk), oggi.AddMinutes(-1), false, false, true); // se ho trovato record... if (tabTimbExpl != null && tabTimbExpl.Count > 0) { doLog("Trovate anomalie copertura orario, invio email!", logType.info, ref sbMain); // mando email ad admin! msgTopic = "Anomalie GPW: Ore timbrate"; if (includeDirectUrl) { doLog($"Risultano a sistema le seguenti anomalie:{Environment.NewLine}Orario timbrato non suff a copertura standard{Environment.NewLine}", logType.info, ref sbMain); } else { doLog($"Risultano a sistema le seguenti anomalie: Orario timbrato non suff a copertura standard{Environment.NewLine}", logType.info, ref sbMain); } // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); int nRow = 0; foreach (var riga in tabTimbExpl) { string sfondo = nRow % 2 == 0 ? "" : stripeRow; doLog($"", logType.none, ref sbMain); numErr++; nRow++; } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{riga.DataLav:yyyy.MM.dd ddd}{riga.CognomeNome}
", logType.none, ref sbMain); msgBody = sbMain.ToString(); await sendEmail(adminDestEmail, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); // salvo anomCount.Add("Check C: Copertura Orario", numErr - lastCount); lastCount = numErr; } } // (D) recupero errori copertura ore lavorate / ore caricate a commessa... if (checkAnomOreLavComm) { numChk++; sbMain = new StringBuilder(); var tabTimbRegAtt = await ADService.TeRaExplGetFilt(0, oggi.AddDays(-gg2ChkOreCaricate), oggi.AddHours(1), false, true, maxErrMin, maxErrPlus); // sulla tabella seleziono SE NON E' OK colonna okLavCom var listErrCopertura = tabTimbRegAtt.Where(x => x.okLAvCom == 0).ToList(); if (listErrCopertura != null && listErrCopertura.Count() > 0) { doLog("Trovate anomalie ore lavorate / commesse caricate, invio email!", logType.info, ref sbMain); // mando email ad admin! msgTopic = "Anomalie GPW: Ore Caricate a commessa"; if (includeDirectUrl) { doLog($"Risultano a sistema le seguenti anomalie:{Environment.NewLine}Ore caricate a commessa non corrispondenti ad ore lavorate secondo standard{Environment.NewLine}", logType.info, ref sbMain); } else { doLog($"Risultano a sistema le seguenti anomalie: Ore caricate a commessa non corrispondenti ad ore lavorate secondo standard{Environment.NewLine}", logType.info, ref sbMain); } // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); int nRow = 0; foreach (var riga in listErrCopertura) { string sfondo = nRow % 2 == 0 ? "" : stripeRow; doLog($"", logType.none, ref sbMain); numErr++; nRow++; } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{riga.DataLav:yyyy.MM.dd ddd}{riga.CognomeNome}
", logType.none, ref sbMain); msgBody = sbMain.ToString(); await sendEmail(adminDestEmail, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); // salvo anomCount.Add("Check D: Ore lavorate / Caricate", numErr - lastCount); lastCount = numErr; } } // (E) cerco anomalie x orario continuato (no Pausa Pranzo, solo 1 IN, 1 OUT) if (checkAnomContinuato) { numChk++; sbMain = new StringBuilder(); var tabTimbExpl = await ADService.TimbExplGetContinuato(0, oggi.AddDays(-gg2ChkCont), oggi.AddHours(1)); // se ho trovato record... if (tabTimbExpl != null && tabTimbExpl.Count > 0) { doLog("Trovate anomalie orario continuato, invio email!", logType.info, ref sbMain); // mando email ad admin! msgTopic = "Anomalie GPW: Orario Continuato"; if (includeDirectUrl) { doLog($"Risultano a sistema le seguenti anomalie:{Environment.NewLine}Orari continuati da approvare{Environment.NewLine}", logType.info, ref sbMain); } else { doLog($"Risultano a sistema le seguenti anomalie: Orari continuati da approvare{Environment.NewLine}", logType.info, ref sbMain); } // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); int nRow = 0; foreach (var riga in tabTimbExpl) { string sfondo = nRow % 2 == 0 ? "" : stripeRow; doLog($"", logType.none, ref sbMain); numErr++; nRow++; } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{riga.DataLav:yyyy.MM.dd ddd}{riga.CognomeNome}
", logType.none, ref sbMain); msgBody = sbMain.ToString(); await sendEmail(adminDestEmail, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); // salvo anomCount.Add("Check E: Anomalia Continuato", numErr - lastCount); lastCount = numErr; } } // (F) Effettuo ricalcolo permessi giornalieri mese precedente se richiesto e sono // entro limite gg if (checkPermMesePrev && DateTime.Today.Day <= maxDaycheckPermMesePrev) { numChk++; // mando email ad admin! msgTopic = "Verifica GPW: Permessi e Giustificativi (mese precedente)"; // chiamo ricalcolo iniziale... DateTime dtStart = new DateTime(oggi.Year, oggi.Month, 1).AddMonths(-1); DateTime dtEnd = new DateTime(oggi.Year, oggi.Month, 1).AddDays(-1); sbMain = new StringBuilder(); Stopwatch sw = new Stopwatch(); sw.Start(); doLog("Analisi e ricalcolo Permessi / Giustificativi", logType.info, ref sbMain); await ADService.TimbExplRicalcola(0, dtStart, dtEnd); // cerco anomalie var list2fix = await ADService.TimbExplGetAnomalie(0, dtStart, dtEnd, false, false, true); if (list2fix != null && list2fix.Count > 0) { // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); var updTask2 = Task.Run(async () => { int nRow = 0; foreach (var item in list2fix) { // escludo date da oggi in poi... if (item.DataLav < DateTime.Today) { GiustificativiModel rec2del = new GiustificativiModel() { IdxDipendente = item.IdxDipendente, DataLav = item.DataLav, CodGiust = "PERM" }; try { // elimino eventuali vecchi permessi await ADService.GiustificativiDelete(rec2del); // inserisco permessi... await ADService.GiustificativiInsByDate(item.IdxDipendente, item.DataLav, "PERM"); string sfondo = nRow % 2 == 0 ? "" : stripeRow; doLog($"", logType.none, ref sbMain); numErr++; nRow++; } catch (Exception exc) { doLog($"Eccezione in ricalcolo:{Environment.NewLine}{exc}", logType.error, ref sbMain); } } } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{item.DataLav:yyyy.MM.dd ddd}{item.CognomeNome}
", logType.none, ref sbMain); // ricalcolo! await ADService.TimbExplRicalcola(0, dtStart, dtEnd); }); await updTask2; sw.Stop(); doLog($"Effettuato ricalcolo | {dtStart:yyyy.MM.dd} --> {dtEnd:yyyy.MM.dd} | {sw.ElapsedMilliseconds:N0} ms", logType.info, ref sbMain); } // invio email con i tempi msgBody = sbMain.ToString(); await sendEmail(adminDestEmail, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); // salvo anomCount.Add($"Check F: {msgTopic}", numErr - lastCount); lastCount = numErr; } // (G) Effettuo ricalcolo permessi giornalieri mese corrente se richiesto if (checkPermMeseCurr) { numChk++; // mando email ad admin! msgTopic = "Verifica GPW: Permessi e Giustificativi (mese corrente)"; // chiamo ricalcolo iniziale... DateTime dtStart = new DateTime(oggi.Year, oggi.Month, 1); DateTime dtEnd = oggi; sbMain = new StringBuilder(); Stopwatch sw = new Stopwatch(); sw.Start(); doLog("Analisi e ricalcolo Permessi / Giustificativi", logType.info, ref sbMain); await ADService.TimbExplRicalcola(0, dtStart, dtEnd); // cerco anomalie var list2fix = await ADService.TimbExplGetAnomalie(0, dtStart, dtEnd, false, false, true); if (list2fix != null && list2fix.Count > 0) { // tabella! doLog("", logType.none, ref sbMain); doLog($"", logType.none, ref sbMain); doLog("", logType.none, ref sbMain); var updTask2 = Task.Run(async () => { int nRow = 0; foreach (var item in list2fix) { // escludo date da oggi in poi... if (item.DataLav < DateTime.Today) { GiustificativiModel rec2del = new GiustificativiModel() { IdxDipendente = item.IdxDipendente, DataLav = item.DataLav, CodGiust = "PERM" }; try { // elimino eventuali vecchi permessi await ADService.GiustificativiDelete(rec2del); // inserisco permessi... await ADService.GiustificativiInsByDate(item.IdxDipendente, item.DataLav, "PERM"); string sfondo = nRow % 2 == 0 ? "" : stripeRow; doLog($"", logType.none, ref sbMain); numErr++; nRow++; } catch (Exception exc) { doLog($"Eccezione in ricalcolo:{Environment.NewLine}{exc}", logType.error, ref sbMain); } } } doLog("", logType.none, ref sbMain); doLog("
DATADipendente
{item.DataLav:yyyy.MM.dd ddd}{item.CognomeNome}
", logType.none, ref sbMain); // ricalcolo! await ADService.TimbExplRicalcola(0, dtStart, dtEnd); }); await updTask2; sw.Stop(); doLog($"Effettuato ricalcolo | {dtStart:yyyy.MM.dd} --> {dtEnd:yyyy.MM.dd} | {sw.ElapsedMilliseconds:N0} ms", logType.info, ref sbMain); } // invio email con i tempi msgBody = sbMain.ToString(); await sendEmail(adminDestEmail, msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); // salvo anomCount.Add($"Check G: {msgTopic}", numErr - lastCount); lastCount = numErr; } string resErrori = ""; foreach (var item in anomCount) { resErrori += $"{item.Key}: {item.Value} | "; } // Summary di cosa fatto answ = numErr == 0 ? $"Check Anomalie Timbr ALL OK | effettuati {numChk} check" : $"Check Anomalie Timbr KO | effettuati {numChk} check | trovate {numErr} anomalie | {resErrori}"; // registro evento check effettuato... newRec = new RegistroEventiModel() { DataOra = DateTime.Now, Evento = "checkAnomalie", Commento = answ }; fatto = await ADService.RegEventiUpdate(newRec); } // restituisco esito return answ; } /// /// Pagina di prova x validità chiamate API /// /// [HttpGet("Test")] public async Task Test() { await Task.Delay(1); return "OK"; } #endregion Public Methods #region Protected Enums protected enum logType { none, local, trace, info, warn, error } #endregion Protected Enums #region Protected Properties /// /// Dataservice x accesso DB /// protected ApiDataService ADService { get; set; } #endregion Protected Properties #region Protected Methods /// /// Effettua log del tipo richiesto aggiungendo riga anche allo stringbuilder indicato /// /// /// /// protected void doLog(string message, logType tipoLog, ref StringBuilder currSB) { bool doLine = true; switch (tipoLog) { case logType.error: Log.Error(message); break; case logType.info: Log.Info(message); break; case logType.trace: Log.Trace(message); break; case logType.warn: Log.Warn(message); break; case logType.local: break; default: case logType.none: doLine = false; break; } if (doLine) { currSB.AppendLine(message); } else { currSB.Append(message); } } protected async Task sendEmail(string destList, string subject, string message) { List emailDestList = destList.Split(",").ToList(); foreach (var dest in emailDestList) { try { await _emailSender.SendEmailAsync(dest, subject, message); } catch (Exception exc) { Log.Error($"Eccezione durante invio email:{Environment.NewLine}dest: {dest} | subject {subject}{Environment.NewLine}{exc}"); } } } #endregion Protected Methods #region Private Fields private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); private readonly IEmailSender _emailSender; private IConfiguration _configuration; #endregion Private Fields } }