using GPW.CORE.Data.DbModels; using GPW.CORE.Data.Services; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using NLog; using System.Diagnostics; namespace GPW.CORE.WRKLOG.Components.Compo { public partial class RegAttEditor { #region Public Properties [Parameter] public RegAttivitaModel? CurrRecord { get => _currRecord; set => _currRecord = value; } protected RegAttivitaModel? _currRecord { get { return AppMServ.recordRA; } set { AppMServ.recordRA = value; vetoUpd = true; Stopwatch sw = new Stopwatch(); sw.Start(); var updFase = Task.Run(async () => { if (value != null) { if (value.FasiNav != null && value.FasiNav.ProgettoNav != null) { gruppoSel = value.FasiNav.ProgettoNav.Gruppo; idxProj = value.FasiNav.IdxProgetto != null ? (int)value.FasiNav.IdxProgetto : 0; } else { // effettuo selezione manuale... var currFase = await GDataServ.AnagFasiByKey(value.IdxFase); if (currFase != null) { if (currFase.ProgettoNav != null) { gruppoSel = currFase.ProgettoNav.Gruppo; } idxProj = currFase.IdxProgetto != null ? (int)currFase.IdxProgetto : 0; } value.IdxFase = 0; } } await ReloadData(false, false); }); updFase.Wait(); sw.Stop(); Log.Trace($"Sel record fasi in cascata: {sw.ElapsedMilliseconds} ms"); vetoUpd = false; } } public string gruppoSel { get { return _gruppoSel; } set { _gruppoSel = value; if (!vetoUpd) { var pUpd = Task.Run(async () => await ReloadData(true, true)); pUpd.Wait(); } } } public int idxProj { get { return _idxProj; } set { _idxProj = value; if (!vetoUpd) { var pUpd = Task.Run(async () => await ReloadData(false, true)); pUpd.Wait(); } } } [Parameter] public EventCallback ItemReset { get; set; } [Parameter] public EventCallback ItemUpdated { get; set; } #endregion Public Properties #region Protected Fields protected string _gruppoSel = ""; protected int _idxProj = 0; protected bool vetoUpd = false; #endregion Protected Fields #region Protected Properties protected List fasiList { get; set; } = new List(); [Inject] protected GpwDataService GDataServ { get; set; } = null!; protected List gruppiList { get; set; } = new List(); protected int idxFase { get { int answ = 0; if (CurrRecord != null) { answ = CurrRecord.IdxFase; } return answ; } set { if (CurrRecord != null) { CurrRecord.IdxFase = value; } } } protected List projList { get; set; } = new List(); #endregion Protected Properties #region Protected Methods /// /// Salvo in MService record clonato /// protected async void DoClone() { if (CurrRecord != null) { var newData = CurrRecord.Clone(); newData.IdxRa = 0; AppMServ.clonedRA = newData; await ItemReset.InvokeAsync(true); } } /// /// Elimino record /// protected async void DoDelete() { // chiedo verifica if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler eliminare il record selezionato??")) return; if (CurrRecord != null) { // aggiorno await GDataServ.RegAttDelete(CurrRecord); // registro fatto await ItemUpdated.InvokeAsync(true); } } /// /// Indico item selezionato /// protected async void DoReset() { await ItemReset.InvokeAsync(true); } /// /// Aggiorno e riporto update /// protected async void DoUpdate() { bool checkOk = false; checkOk = await arrotondaMinuti(); if (checkOk) { checkOk = await checkDayDiff(); if (checkOk) { checkOk = await checkDurata(); } } // aggiorno if (CurrRecord != null && checkOk) { // controllo IdxDipendente if (CurrRecord.IdxDipendente == 0) { CurrRecord.IdxDipendente = AppMServ.IdxDipendente; } // prearo lista inserimento List data2ins = new List(); // se inizio/fine stesso giorno processo if (CurrRecord.Fine.Date.Equals(CurrRecord.Inizio.Date)) { data2ins.Add(CurrRecord); } // in caso di eventuale supero della mezzanotte --> chiedo se si vuole split su 2 attivit�... else { bool doSplit = await JSRuntime.InvokeAsync("confirm", "L'attivit� si protrae su pi� giorni, vuoi suddividere in record per ogni giornata?"); // chiedo verifica x splittare in N+1 periodi (N = giorni) if (doSplit) { RegAttivitaModel currRA = CurrRecord.Clone() as RegAttivitaModel; // primo record � inizio --> mezzanote DateTime lastInizio = currRA.Inizio; DateTime lastFine = currRA.Inizio.Date.AddDays(1); currRA.Fine = lastFine; data2ins.Add(currRA); // calcolo i gg int numGG = CurrRecord.Fine.Date.Subtract(CurrRecord.Inizio.Date).Days; // ciclo for (int i = 0; i < numGG; i++) { // splitto... inizio = fine + 1 sec... currRA = CurrRecord.Clone() as RegAttivitaModel; currRA.Inizio = lastFine; // porto avanti ultima fine... lastFine = lastFine.AddDays(1); currRA.Fine = currRA.Fine > lastFine ? lastFine : currRA.Fine; data2ins.Add(currRA); } } else { data2ins.Add(CurrRecord); } } // ciclo x inserire foreach (var item in data2ins) { await GDataServ.RegAttUpdate(item); } } // resetto clone e record corrente... AppMServ.clonedRA = null; CurrRecord = null; // registro fatto await ItemUpdated.InvokeAsync(true); } protected override async Task OnInitializedAsync() { await initConf(); } protected async Task ReloadData(bool resetProj, bool resetFase) { gruppiList = await GDataServ.AnagGruppiUser(AppMServ.IdxDipendente); var allProj = await GDataServ.AnagProjAll(); projList = allProj .Where(x => x.Attivo == true && x.Gruppo == gruppoSel) .OrderBy(x => x.ClienteNav.RagSociale) .ThenBy(x => x.NomeProj) .ToList(); if (resetProj) { if (projList.Count > 0) { idxProj = projList[0].IdxProgetto; } } var fasiProj = await GDataServ.AnagFasiByProj(idxProj); if (fasiProj != null) { fasiList = fasiProj; } else { fasiList = new List(); } if (resetFase) { // se ho 2+ risultati --> il primo � titolo faccio il secondo if (fasiList.Count > 1) { var currData = fasiList.Skip(1).FirstOrDefault(); if (currData != null) { idxFase = currData.IdxFase; } } // altrimenti primo... else { var currData = fasiList.FirstOrDefault(); if (currData != null) { idxFase = currData.IdxFase; } } } } #endregion Protected Methods #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); private int lapseMinLimit = 1440; private int lapseMinWarn = 480; private int maxDayDiff = 60; #endregion Private Fields #region Private Properties [Inject] private MessageService AppMServ { get; set; } = null!; [Inject] private IJSRuntime JSRuntime { get; set; } = null!; private bool VetoInsert { get => GDataServ.VetoInsert; } #endregion Private Properties #region Private Methods private async Task arrotondaMinuti() { bool answ = false; if (CurrRecord != null) { // arrotondo ai 5 min... CurrRecord.Inizio = CORE.Data.Utils.DateRounded(CurrRecord.Inizio.AddMinutes(2), 5, true); // arrotondo ai 5 min... CurrRecord.Fine = CORE.Data.Utils.DateRounded(CurrRecord.Fine.AddMinutes(2), 5, true); answ = await checkCoerenzaDate(true); } return answ; } /// Verifico coerenza date (inizio < fine) indica se la data modificata sia l'inizio private async Task checkCoerenzaDate(bool modInizio) { bool inError = false; // verifica presenza errori if (CurrRecord != null) { inError = CurrRecord.Inizio >= CurrRecord.Fine; if (inError) { // chiedo se voglia proseguire... if (!await JSRuntime.InvokeAsync("confirm", $"L'inizio dell'attivit� inserita ({CurrRecord.Inizio:yyyy-MM-dd HH:mm}) � successivo alla fine dell'attivit� ({CurrRecord.Fine:yyyy-MM-dd HH:mm}). Vuoi proseguire correggendo l'inizio attivit�?")) return false; // se ho mod inizio --> tengo ferma fine, inizio 1/2 h prima if (modInizio) { CurrRecord.Inizio = CurrRecord.Fine.AddMinutes(-30); } else { CurrRecord.Fine = CurrRecord.Inizio.AddMinutes(30); } } } return true; } /// /// Verifica coerenza data inserita/data corrente, altrimenti segnala messaggio e ferma... /// private async Task checkDayDiff() { // verifica presenza errori if (CurrRecord != null) { DateTime oggi = DateTime.Today; // controllo coerenza inizio if (Math.Abs(CurrRecord.Inizio.Subtract(oggi).TotalDays) > maxDayDiff) { // chiedo se voglia proseguire... if (!await JSRuntime.InvokeAsync("confirm", $"L'inizio dell'attivit� inserita ({CurrRecord.Inizio:yyyy-MM-dd HH:mm}) supera la soglia di coerenza con la data odierna: Sicuro di voler procedere con la modifica?")) return false; } if (Math.Abs(CurrRecord.Fine.Subtract(oggi).TotalDays) > maxDayDiff) { // chiedo se voglia proseguire... if (!await JSRuntime.InvokeAsync("confirm", $"La fine dell'attivit� inserita ({CurrRecord.Fine:yyyy-MM-dd HH:mm}) supera la soglia di coerenza con la data odierna: Sicuro di voler procedere con la modifica?")) return false; } // verifico non siano date future oltre limite di 1 gg.. if (CurrRecord.Inizio.Date > oggi) { await JSRuntime.InvokeVoidAsync("alert", $"Errore! La data-ora di inizio attivit� � su una data successiva a quella odierna. Impossibile salvare il record."); return false; } if (CurrRecord.Fine.Date > oggi.AddDays(1)) { await JSRuntime.InvokeVoidAsync("alert", $"Errore! La data-ora di fine attivit� � oltre il limite consentito. Impossibile salvare il record."); return false; } } return true; } /// /// Verifica coerenza durata evento: se supera soglia warning segnala messaggio, se supera /// soglia limite ferma e basta... /// private async Task checkDurata() { // verifica presenza errori if (CurrRecord != null) { var durata = CurrRecord.Fine.Subtract(CurrRecord.Inizio).TotalMinutes; // controllo coerenza inizio if (durata > lapseMinLimit) { // BLOCCO prosecuzione... await JSRuntime.InvokeVoidAsync("alert", $"Errore! La durata dell'attivit� inserita supera il limite consentito di {lapseMinLimit} minuti. Impossibile salvare il record."); return false; } else if (durata > lapseMinWarn) { // chiedo se voglia proseguire... if (!await JSRuntime.InvokeAsync("confirm", $"Attenzione! La durata dell'attivit� inserita supera il limite standard di {lapseMinWarn} minuti. Sicuro di voler procedere con la modifica?")) return false; } } return true; } /// /// init valori da config /// /// private async Task initConf() { // leggo conf standard controllo RegAtt var sMaxDayDiff = GDataServ.ConfigGetKey("maxDayDiffRA"); if (sMaxDayDiff != null) { int.TryParse(sMaxDayDiff.valore, out maxDayDiff); } var sLapseMinWarn = GDataServ.ConfigGetKey("lapseMinWarn"); if (sLapseMinWarn != null) { int.TryParse(sLapseMinWarn.valore, out lapseMinWarn); } var sLapseMinLimit = GDataServ.ConfigGetKey("lapseMinLimit"); if (sLapseMinLimit != null) { int.TryParse(sLapseMinLimit.valore, out lapseMinLimit); } } #endregion Private Methods } }