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.Text; namespace GPW.CORE.Api.Controllers { [Route("api/[controller]")] [ApiController] public class TimbraCheckController : ControllerBase { private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); private readonly IEmailSender _emailSender; private IConfiguration _configuration; /// /// Avvio controller x CheckProgetti /// /// /// /// /// public TimbraCheckController(ILogger logger, IConfiguration configuration, IEmailSender emailSender, ApiDataService DataService) { _configuration = configuration; _emailSender = emailSender; dataService = DataService; Log.Info("Avviata classe TimbraCheck"); } protected enum logType { none, local, trace, info, warn } /// /// Dataservice x accesso DB /// protected ApiDataService dataService { get; set; } /// /// 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.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}"); } } } /// /// Pagina di prova x validità chiamate API /// /// [HttpGet("Test")] public async Task Test() { await Task.Delay(1); return "OK"; } /// /// 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 dataService.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 dataService.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 (2 be done) * * 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 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"); 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 dataService.DipendentiGetAll(); // (A) recupero mancate approvazioni, mando solo ad admin if (checkAnomAppr) { numChk++; sbMain = new StringBuilder(); var tabTimbExpl = await dataService.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 dataService.DipAndAnomGetAll(oggi.AddDays(-gg2Chk), oggi.AddHours(1), false, true, false); var tabTimbExpl = await dataService.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 dataService.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 dataService.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 dataService.TeRaExplGetAll(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 dataService.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; } } 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 dataService.RegEventiUpdate(newRec); } // restituisco esito return answ; } } }