487 lines
17 KiB
C#
487 lines
17 KiB
C#
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<bool> ItemReset { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<bool> 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<AnagFasiModel> fasiList { get; set; } = new List<AnagFasiModel>();
|
|
|
|
[Inject]
|
|
protected GpwDataService GDataServ { get; set; } = null!;
|
|
|
|
protected List<AnagGruppiModel> gruppiList { get; set; } = new List<AnagGruppiModel>();
|
|
|
|
protected int idxFase
|
|
{
|
|
get
|
|
{
|
|
int answ = 0;
|
|
if (CurrRecord != null)
|
|
{
|
|
answ = CurrRecord.IdxFase;
|
|
}
|
|
return answ;
|
|
}
|
|
set
|
|
{
|
|
if (CurrRecord != null)
|
|
{
|
|
CurrRecord.IdxFase = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected List<AnagProgettiModel> projList { get; set; } = new List<AnagProgettiModel>();
|
|
|
|
#endregion Protected Properties
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Salvo in MService record clonato
|
|
/// </summary>
|
|
protected async void DoClone()
|
|
{
|
|
if (CurrRecord != null)
|
|
{
|
|
var newData = CurrRecord.Clone();
|
|
newData.IdxRa = 0;
|
|
AppMServ.clonedRA = newData;
|
|
await ItemReset.InvokeAsync(true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elimino record
|
|
/// </summary>
|
|
protected async void DoDelete()
|
|
{
|
|
// chiedo verifica
|
|
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record selezionato??"))
|
|
return;
|
|
|
|
if (CurrRecord != null)
|
|
{
|
|
// aggiorno
|
|
await GDataServ.RegAttDelete(CurrRecord);
|
|
// registro fatto
|
|
await ItemUpdated.InvokeAsync(true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indico item selezionato
|
|
/// </summary>
|
|
protected async void DoReset()
|
|
{
|
|
await ItemReset.InvokeAsync(true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorno e riporto update
|
|
/// </summary>
|
|
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<RegAttivitaModel> data2ins = new List<RegAttivitaModel>();
|
|
|
|
// 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<bool>("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<AnagFasiModel>();
|
|
}
|
|
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<bool> 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;
|
|
}
|
|
|
|
/// <summary> Verifico coerenza date (inizio < fine) </summary> <param
|
|
/// name="modInizio">indica se la data modificata sia l'inizio</param>
|
|
private async Task<bool> 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<bool>("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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica coerenza data inserita/data corrente, altrimenti segnala messaggio e ferma...
|
|
/// </summary>
|
|
private async Task<bool> 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<bool>("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<bool>("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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica coerenza durata evento: se supera soglia warning segnala messaggio, se supera
|
|
/// soglia limite ferma e basta...
|
|
/// </summary>
|
|
private async Task<bool> 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<bool>("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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// init valori da config
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
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
|
|
}
|
|
} |