using GPW.CORE.Api.Data; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc; using NLog; using System.Text; namespace GPW.CORE.Api.Controllers { [Route("api/[controller]")] [ApiController] public class ProjCheckController : ControllerBase { #region Private Fields private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); private readonly IEmailSender _emailSender; private IConfiguration _configuration; #endregion Private Fields #region Public Constructors /// /// Avvio controller x CheckProgetti /// /// /// /// /// public ProjCheckController(ILogger logger, IConfiguration configuration, IEmailSender emailSender, ApiDataService DataService) { _configuration = configuration; _emailSender = emailSender; dataService = DataService; Log.Info("Avviata classe ProjCheck"); } #endregion Public Constructors #region Protected Enums protected enum logType { none, local, trace, info, warn } #endregion Protected Enums #region Protected Properties /// /// Dataservice x accesso DB /// protected ApiDataService dataService { 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.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 subject, string message) { string emailRaw = _configuration["MailDest:ProjCheck"] ?? ""; List emailDestList = emailRaw.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 Public Methods [HttpGet("ResAlloc")] public async Task Get() { // oggetti base string answ = "ND"; StringBuilder sbMain = new StringBuilder(); StringBuilder sbActions = new StringBuilder(); StringBuilder sbAllProj = new StringBuilder(); int numFix = 0; int numProj = 0; int numFasi = 0; string enableChiudiRaw = _configuration["EnableChiudiFasi"]??"false"; bool enableChiudi = false; if (!string.IsNullOrEmpty(enableChiudiRaw)) { bool.TryParse(enableChiudiRaw, out enableChiudi); } // recupero progetti attivi... doLog("Esito della verifica stato ore progetto (allocate/consumate)", logType.info, ref sbMain); doLog("
", logType.none, ref sbMain); var currProj = await dataService.AnagProjActiv(); numProj = currProj.Count; doLog($"Progetti Attivi: {numProj}", logType.info, ref sbMain); doLog("
", logType.none, ref sbMain); // leggo fasi attive var currFasiAct = await dataService.AnagFasiActiv(); numFasi = currFasiAct.Count; doLog("
", logType.none, ref sbMain); doLog($"Fasi Attive: {numFasi}", logType.info, ref sbMain); doLog("
", logType.none, ref sbMain); // ciclo elenco fasi ancestor di ognuno... doLog("Elenco Progetti valutati
", logType.none, ref sbAllProj); foreach (var itemProj in currProj) { // cerco le sue fasi PARENT... var subsetFasi = currFasiAct .Where(x => x.IdxProgetto == itemProj.IdxProgetto && x.IdxFaseAncest == 0) .ToList(); string projData = $"[P.{itemProj.IdxProgetto}] {itemProj.Gruppo} | {itemProj.ClienteNav.RagSociale} | {itemProj.NomeProj} | {subsetFasi.Count} Fasi"; doLog(projData, logType.trace, ref sbAllProj); // ciclo x ogni fase Parent foreach (var parentFase in subsetFasi) { // se ne trovo valuto le ore impiegate... var statoFase = await dataService.CalcOreFase(parentFase.IdxFase, false); // se ore usate > (ore budget x %) --> CHIUDO! if (statoFase != null && statoFase.totOre >= (statoFase.budgetTime * (decimal)statoFase.percOpen)) { // segno che ho +1 fix numFix++; // x ora LOG... poi chiudo... string currAction = $" [F.{parentFase.IdxFase}] Budget esaurito in Fase {parentFase.NomeFase} {statoFase.totOre:N2}h consumate, budgt {statoFase.budgetTime:N0} al {statoFase.percOpen:P1}"; doLog(projData, logType.local, ref sbActions); doLog(currAction, logType.warn, ref sbActions); doLog("------------------", logType.local, ref sbActions); // se abilitato CHIUDO fase master e sottofasi! if (enableChiudi) { await dataService.FasiSetActive(parentFase.IdxFase, false); } } } } if (numFix > 0) { doLog("
", logType.none, ref sbMain); doLog("
", logType.none, ref sbMain); doLog($"Fasi critiche: {numFix}", logType.info, ref sbMain); doLog("
", logType.none, ref sbMain); } else { doLog("
", logType.none, ref sbMain); doLog("
", logType.none, ref sbMain); doLog($"Tutti i progetti sono OK", logType.info, ref sbMain); doLog("
", logType.none, ref sbMain); } // predispongo email string msgTopic = "GPW: effettuata verifica progetti"; string msgBody = sbMain.ToString(); // se ho errori loggo... if (numFix > 0) { msgBody += sbActions.ToString(); } msgBody += "
"; msgBody += "
"; msgBody += "
"; msgBody += sbAllProj.ToString(); //{ HtmlEncoder.Default.Encode(callbackUrl)} // invio email await sendEmail(msgTopic, msgBody.Replace($"{Environment.NewLine}", "
")); // ritorno solo LOG azioni answ = numFix == 0 ? $"ALL {numProj} Proj OK" : $"Proj: {numProj} | Fasi: {numFasi} | Fixed/Closed: {numFix}"; return answ; } #endregion Public Methods } }