Merge branch 'develop' of https://gitlab.steamware.net/steamware/gpw_next into develop
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Smart.Data;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
@@ -23,6 +24,9 @@ namespace GPW.CORE.Smart.Components
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected LicenseService LicServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageService MService { get; set; } = null!;
|
||||
|
||||
@@ -35,10 +39,88 @@ namespace GPW.CORE.Smart.Components
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Verifica informazioni condivise applicazione
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> checkActivations()
|
||||
{
|
||||
bool allOk = false;
|
||||
if (LicServ.ValidData)
|
||||
{
|
||||
// se non fosse tutto ok
|
||||
if (!LicServ.HasActivData)
|
||||
{
|
||||
// chiamo refresh licenze da remoto
|
||||
allOk = await LicServ.RefreshLicense();
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(1);
|
||||
return allOk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica informazioni condivise applicazione
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> checkSharedInfo()
|
||||
{
|
||||
bool allOk = false;
|
||||
if (!LicServ.ValidData)
|
||||
{
|
||||
// salvo cod app da Conf...
|
||||
LicServ.Applicazione = CDService.CodApp;
|
||||
// effettuo lettura dati preliminari da AKV (eventualmente in cache...)
|
||||
List<AnagKeyValueModel>? rawAkvList = await CDService.AKVList();
|
||||
if (rawAkvList != null)
|
||||
{
|
||||
LicServ.AKVList = rawAkvList;
|
||||
allOk = LicServ.InitAkv();
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(1);
|
||||
return allOk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica info specifiche utente
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> checkUserLicense()
|
||||
{
|
||||
bool answ = false;
|
||||
// verifico utente attivo
|
||||
answ = MService.IsActive;
|
||||
if (answ)
|
||||
{
|
||||
var rawActList = LicServ.ActivList;
|
||||
// recupero hash utente
|
||||
string hashImpiego = MService.HashDip;
|
||||
// confronto con elenco attivazioni dello shared service...
|
||||
var foundRec = rawActList.Where(x => x.CodImpiego == hashImpiego);
|
||||
answ = foundRec.Count() > 0;
|
||||
// salvo status payloadOk
|
||||
MService.PayloadOk = answ;
|
||||
}
|
||||
|
||||
await Task.Delay(1);
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected async Task DoVerifyActiv()
|
||||
{
|
||||
MService.PayloadOk = false;
|
||||
await Task.Delay(250);
|
||||
await VerifyActiv();
|
||||
}
|
||||
|
||||
protected async Task ForceReset()
|
||||
{
|
||||
string nextPage = navManager.ToBaseRelativePath(navManager.Uri);
|
||||
await Task.Delay(1);
|
||||
await DoVerifyActiv();
|
||||
navManager.NavigateTo($"ForceReset?nextPage={nextPage}", true);
|
||||
}
|
||||
|
||||
@@ -50,15 +132,33 @@ namespace GPW.CORE.Smart.Components
|
||||
if (!navManager.Uri.Contains("jumper"))
|
||||
{
|
||||
await checkUser();
|
||||
// verifico attivazione dipendente...
|
||||
await checkUserLicense();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// verifica attivazione
|
||||
await VerifyActiv();
|
||||
}
|
||||
|
||||
protected void ReturnHome()
|
||||
{
|
||||
navManager.NavigateTo("Home", true);
|
||||
}
|
||||
|
||||
protected async Task VerifyActiv()
|
||||
{
|
||||
// preliminarmente verifica shared info
|
||||
await checkSharedInfo();
|
||||
// refresh attivazioni se necessario
|
||||
await checkActivations();
|
||||
// verifico e salvo dati attivazione dipendente...
|
||||
await checkUserLicense();
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Properties
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<ProjectsList ListRA="ListProgetti" EnableAdmin="false" EnableEdit="true" ReqUpdate="DoUpdate" ItemCloned="SaveCloned" ActionPaste="ExecPaste"></ProjectsList>
|
||||
<ProjectsList ListRA="ListProgetti" EnableAdmin="false" EnableEdit="true" ReqUpdate="DoUpdate" ItemCloned="SaveCloned" ItemSelected="EditItem" ActionPaste="ExecPaste"></ProjectsList>
|
||||
|
||||
<div class="toast-container py-2 top-0 start-50 translate-middle-x">
|
||||
<div class="toast bg-warning fade @toastCss" id="LiveToast2" role="alert">
|
||||
@@ -9,10 +9,20 @@
|
||||
<button type="button" class="btn-close" aria-label="Close" @onclick="() => resetClone()"></button>
|
||||
</div>
|
||||
<div class="toast-body text-dark small">
|
||||
@if (currRec != null)
|
||||
@if (ClonedRA != null)
|
||||
{
|
||||
<SingleRaDisplay CurrItem="@currRec" EnableAction="false"></SingleRaDisplay>
|
||||
<SingleRaDisplay CurrItem="@ClonedRA" EnableAction="false"></SingleRaDisplay>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (CurrRA != null)
|
||||
{
|
||||
<dialog class="modal fade show p-0" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<RegAttEditor currRecord="@CurrRA" ItemReset="UpdRegAttData" ItemUpdated="UpdRegAttData"></RegAttEditor>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
}
|
||||
@@ -58,21 +58,21 @@ namespace GPW.CORE.Smart.Components
|
||||
protected async Task ExecPaste(RegAttivitaModel pasteRec)
|
||||
{
|
||||
// usa i dati del record ricevuto x indicare inizio...
|
||||
currRec.Inizio = pasteRec.Inizio;
|
||||
ClonedRA.Inizio = pasteRec.Inizio;
|
||||
// fine e durata calcolate...
|
||||
if (pasteRec.OreTot < currRec.OreTot)
|
||||
if (pasteRec.OreTot < ClonedRA.OreTot)
|
||||
{
|
||||
currRec.Fine = pasteRec.Fine;
|
||||
currRec.OreTot = pasteRec.OreTot;
|
||||
ClonedRA.Fine = pasteRec.Fine;
|
||||
ClonedRA.OreTot = pasteRec.OreTot;
|
||||
}
|
||||
else
|
||||
{
|
||||
currRec.Fine = pasteRec.Inizio.AddHours((double)currRec.OreTot);
|
||||
ClonedRA.Fine = pasteRec.Inizio.AddHours((double)ClonedRA.OreTot);
|
||||
}
|
||||
// chiama insert ed invalida cache...
|
||||
await CDService.RegAttUpdate(currRec);
|
||||
await CDService.RegAttUpdate(ClonedRA);
|
||||
// svuota cache x copy/paste
|
||||
currRec = null;
|
||||
ClonedRA = null;
|
||||
await Task.Delay(1);
|
||||
// richiesta rilettura dati...
|
||||
await ReqReload.InvokeAsync(true);
|
||||
@@ -85,14 +85,46 @@ namespace GPW.CORE.Smart.Components
|
||||
|
||||
protected async Task SaveCloned(RegAttivitaModel clonedRec)
|
||||
{
|
||||
currRec = clonedRec;
|
||||
ClonedRA = clonedRec;
|
||||
textDtAct = $"{DateTime.Now:ddd dd.MM.yyyy}";
|
||||
lastAction = $"Clonato Attività";
|
||||
await Task.Delay(1);
|
||||
}
|
||||
protected async Task EditItem(RegAttivitaModel selRec)
|
||||
{
|
||||
CurrRA = selRec;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected async Task UpdRegAttData()
|
||||
{
|
||||
isLoading = true;
|
||||
CurrRA = null;
|
||||
// richiesta rilettura dati...
|
||||
await ReqReload.InvokeAsync(true);
|
||||
|
||||
#if false
|
||||
ListTimbr = null;
|
||||
await Task.Delay(100);
|
||||
await ReloadData();
|
||||
// ricarico giornata...
|
||||
if (SelDayDTO != null)
|
||||
{
|
||||
DateTime dtRif = SelDayDTO.DtRif;
|
||||
if (ListRecords != null)
|
||||
{
|
||||
SelDayDTO = ListRecords.Where(x => x.DtRif == dtRif).FirstOrDefault();
|
||||
showDay = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
private RegAttivitaModel? CurrRA { get; set; } = null;
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private string lastAction = "";
|
||||
@@ -111,7 +143,7 @@ namespace GPW.CORE.Smart.Components
|
||||
/// </summary>
|
||||
/// <param name="clonedRec"></param>
|
||||
/// <returns></returns>
|
||||
private RegAttivitaModel? currRec
|
||||
private RegAttivitaModel? ClonedRA
|
||||
{
|
||||
get => MService.clonedRA;
|
||||
set => MService.clonedRA = value;
|
||||
@@ -212,7 +244,7 @@ namespace GPW.CORE.Smart.Components
|
||||
|
||||
private async Task resetClone()
|
||||
{
|
||||
currRec = null;
|
||||
ClonedRA = null;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
<EditForm Model="@currRecord">
|
||||
<div class="card">
|
||||
<div class="card-header bg-info">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h4>
|
||||
Modifica #
|
||||
@if (currRecord != null)
|
||||
{
|
||||
<b>@currRecord.IdxRa</b>
|
||||
}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="col-12 text-end">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
<i class="far fa-object-group"></i>
|
||||
</span>
|
||||
<InputSelect @bind-Value="@gruppoSel" class="form-select" title="Gruppo">
|
||||
@foreach (var item in gruppiList)
|
||||
{
|
||||
<option value="@item.Gruppo">@item.DescrGruppo</option>
|
||||
}
|
||||
</InputSelect>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
<div class="row">
|
||||
<div class="col-12 col-xl-6 text-end">
|
||||
<label class="small">Progetto</label>
|
||||
<div class="input-group input-group-sm" title="Progetto">
|
||||
<span class="input-group-text" style="width:3em;">
|
||||
<i class="fas fa-project-diagram"></i>
|
||||
</span>
|
||||
<InputSelect @bind-Value="@idxProj" class="form-select bg-light text-start" title="Progetto">
|
||||
@foreach (var item in projList)
|
||||
{
|
||||
<option value="@item.IdxProgetto">@item.ClienteNav.RagSociale | @item.NomeProj</option>
|
||||
}
|
||||
</InputSelect>
|
||||
</div>
|
||||
<label class="small">Fase</label>
|
||||
<div class="input-group input-group-sm" title="Fase">
|
||||
<span class="input-group-text" style="width:3em;">
|
||||
<i class="fas fa-tasks"></i>
|
||||
</span>
|
||||
<InputSelect @bind-Value="@idxFase" class="form-select bg-light text-start" title="Fase">
|
||||
@foreach (var item in fasiList)
|
||||
{
|
||||
if (@item.EnableTime)
|
||||
{
|
||||
if (item.Attivo)
|
||||
{
|
||||
<option value="@item.IdxFase">@item.NomeFase</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@item.IdxFase" disabled="@VetoInsert" title="Fase Disattivata, non selezionabile">@item.NomeFase / DISATTIVA</option>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item.Attivo)
|
||||
{
|
||||
<option value="@item.IdxFase" disabled="true" class="bg-dark text-warning">[@item.NomeFase]</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@item.IdxFase" disabled="true" class="bg-dark text-warning" title="Fase Disattivata, non selezionabile">[@item.NomeFase / DISATTIVA]</option>
|
||||
}
|
||||
}
|
||||
}
|
||||
</InputSelect>
|
||||
</div>
|
||||
</div>
|
||||
@if (currRecord != null)
|
||||
{
|
||||
<div class="col-12 col-xl-6 text-start">
|
||||
<label class="small">Periodo (arr 5 min)</label>
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="px-0">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
<i class="fas fa-play fa-xs"></i>
|
||||
</span>
|
||||
<input type="datetime-local" @bind="@currRecord.Inizio"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="px-0">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
<i class="fas fa-stop fa-xs"></i>
|
||||
</span>
|
||||
<input type="datetime-local" @bind="@currRecord.Fine"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 text-start">
|
||||
<label class="small">Descrizione</label>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">
|
||||
<i class="far fa-comment-alt"></i>
|
||||
</span>
|
||||
<InputTextArea id="idxRa" @bind-Value="@currRecord.Descrizione" class="form-control" title="Descrizione attività"></InputTextArea>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
@if (AppMServ.PayloadOk)
|
||||
{
|
||||
<button type="button" class="btn w-100 btn-success" @onclick="DoUpdate"><i class="fas fa-check-circle"></i> Save</button>
|
||||
}
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button type="button" class="btn w-100 btn-warning" @onclick="DoReset"><i class="fas fa-ban"></i> Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
@@ -0,0 +1,382 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.AspNetCore.Components.Routing;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components.Web.Virtualization;
|
||||
using Microsoft.JSInterop;
|
||||
using GPW.CORE.Comp;
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using GPW.CORE.Smart;
|
||||
using GPW.CORE.Smart.Components;
|
||||
using GPW.CORE.Smart.Shared;
|
||||
using GPW.CORE.Smart.Data;
|
||||
using NLog;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GPW.CORE.Smart.Components
|
||||
{
|
||||
public partial class RegAttEditor
|
||||
{
|
||||
#region Protected Fields
|
||||
|
||||
protected string _gruppoSel = "";
|
||||
protected int _idxProj = 0;
|
||||
protected bool vetoUpd = false;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
[Inject]
|
||||
private MessageService AppMServ { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
private IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
private bool VetoInsert
|
||||
{
|
||||
get => CDService.VetoInsert;
|
||||
}
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected List<AnagFasiModel> fasiList { get; set; } = new List<AnagFasiModel>();
|
||||
|
||||
[Inject]
|
||||
protected CoreSmartDataService CDService { get; set; } = null!;
|
||||
|
||||
protected List<AnagGruppiModel> gruppiList { get; set; } = new List<AnagGruppiModel>();
|
||||
protected List<AnagProgettiModel> projList { get; set; } = new List<AnagProgettiModel>();
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Public Properties
|
||||
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Parameter]
|
||||
public RegAttivitaModel? currRecord
|
||||
{
|
||||
get
|
||||
{
|
||||
return AppMServ.recordRA;
|
||||
}
|
||||
set
|
||||
{
|
||||
AppMServ.recordRA = value;
|
||||
vetoUpd = true;
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.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 CDService.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();
|
||||
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
|
||||
Log.Trace($"Test esecuzione sel cascata: {ts.TotalMilliseconds} 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int idxFase
|
||||
{
|
||||
get
|
||||
{
|
||||
int answ = 0;
|
||||
if (currRecord != null)
|
||||
{
|
||||
answ = currRecord.IdxFase;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (currRecord != null)
|
||||
{
|
||||
currRecord.IdxFase = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 Private Methods
|
||||
|
||||
private void arrotondaMinuti()
|
||||
{
|
||||
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);
|
||||
checkCoerenzaDate(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifico coerenza date (inizio < fine)
|
||||
/// </summary>
|
||||
/// <param name="modInizio">indica se la data modificata sia l'inizio</param>
|
||||
private void checkCoerenzaDate(bool modInizio)
|
||||
{
|
||||
bool inError = false;
|
||||
// verifica presenza errori
|
||||
if (currRecord != null)
|
||||
{
|
||||
inError = currRecord.Inizio >= currRecord.Fine;
|
||||
if (inError)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
#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 CDService.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()
|
||||
{
|
||||
arrotondaMinuti();
|
||||
// aggiorno
|
||||
if (currRecord != null)
|
||||
{
|
||||
// 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 CDService.RegAttUpdate(item);
|
||||
}
|
||||
}
|
||||
// resetto clone e record corrente...
|
||||
AppMServ.clonedRA = null;
|
||||
currRecord = null;
|
||||
// registro fatto
|
||||
await ItemUpdated.InvokeAsync(true);
|
||||
}
|
||||
|
||||
protected async Task ReloadData(bool resetProj, bool resetFase)
|
||||
{
|
||||
gruppiList = await CDService.AnagGruppiUser(AppMServ.IdxDipendente);
|
||||
var allProj = await CDService.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 CDService.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
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,379 @@ namespace GPW.CORE.Smart.Data
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Elenco AKV
|
||||
/// </summary>
|
||||
public async Task<List<AnagKeyValueModel>?> AKVList()
|
||||
{
|
||||
string source = "DB";
|
||||
|
||||
List<AnagKeyValueModel>? dbResult = new List<AnagKeyValueModel>();
|
||||
// cerco da cache
|
||||
string currKey = rKeyAKV;
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<AnagKeyValueModel>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new List<AnagKeyValueModel>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.AnagKeyValGetAll();
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<AnagKeyValueModel>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"AKVList | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera l'elenco fasi (tutte)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AnagClientiModel>> AnagClientiAll()
|
||||
{
|
||||
string source = "DB";
|
||||
List<AnagClientiModel>? dbResult = new List<AnagClientiModel>();
|
||||
string currKey = $"{rKeyCliAll}";
|
||||
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<AnagClientiModel>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new List<AnagClientiModel>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.AnagClientiAll();
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<AnagClientiModel>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"AnagClientiAll | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera l'elenco fasi (tutte)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AnagFasiModel>> AnagFasiAll()
|
||||
{
|
||||
string source = "DB";
|
||||
List<AnagFasiModel>? dbResult = new List<AnagFasiModel>();
|
||||
string currKey = $"{rKeyFasiAll}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<AnagFasiModel>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new List<AnagFasiModel>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.AnagFasiAll(false);
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<AnagFasiModel>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"AnagFasiAll | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera info x una specifica FASE
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<AnagFasiModel?> AnagFasiByKey(int idxFase)
|
||||
{
|
||||
string source = "DB";
|
||||
AnagFasiModel? dbResult = new AnagFasiModel();
|
||||
// cerco "secca "in redis...
|
||||
string currKey = $"{rKeyFasiSearch}:{idxFase}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<AnagFasiModel>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new AnagFasiModel();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.AnagFasiByKey(idxFase);
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"AnagFasiSearch | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco fasi dato progetto
|
||||
/// </summary>
|
||||
/// <param name="idxProj"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AnagFasiModel>?> AnagFasiByProj(int idxProj)
|
||||
{
|
||||
string source = "DB";
|
||||
List<AnagFasiModel>? dbResult = new List<AnagFasiModel>();
|
||||
// cerco "secca "in redis...
|
||||
string currKey = $"{rKeyFasiByProj}:{idxProj}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<AnagFasiModel>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new List<AnagFasiModel>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.AnagFasiByProj(idxProj);
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<AnagFasiModel>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"AnagFasiByProj | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco Giustificativi
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AnagGiustModel>?> AnagGiust()
|
||||
{
|
||||
string source = "DB";
|
||||
List<AnagGiustModel>? dbResult = new List<AnagGiustModel>();
|
||||
// cerco "secca "in redis...
|
||||
string currKey = $"{rKeyGiust}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<AnagGiustModel>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new List<AnagGiustModel>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.AnagGiust();
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<AnagGiustModel>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"AnagGiust | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera l'elenco gruppi abilitati x il dipendente
|
||||
/// </summary>
|
||||
/// <param name="idxDipendente"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AnagGruppiModel>> AnagGruppiUser(int idxDipendente)
|
||||
{
|
||||
string source = "DB";
|
||||
List<AnagGruppiModel>? dbResult = new List<AnagGruppiModel>();
|
||||
string currKey = $"{rKeyGrpUser}:{idxDipendente}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<AnagGruppiModel>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new List<AnagGruppiModel>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.AnagGruppiUser(idxDipendente);
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<AnagGruppiModel>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"AnagGruppiUser | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dati orario del dipendente indicato
|
||||
/// </summary>
|
||||
/// <param name="idxProj"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<AnagOrariModel> AnagOrarioByDip(int idxDip)
|
||||
{
|
||||
string source = "DB";
|
||||
AnagOrariModel? dbResult = new AnagOrariModel();
|
||||
string currKey = $"{rKeyAnOrDip}:{idxDip}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<AnagOrariModel>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new AnagOrariModel();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.AnagOrarioByDip(idxDip);
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new AnagOrariModel();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"AnagOrarioByDip | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera l'elenco progetti (tutti)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AnagProgettiModel>> AnagProjAll()
|
||||
{
|
||||
string source = "DB";
|
||||
List<AnagProgettiModel>? dbResult = new List<AnagProgettiModel>();
|
||||
string currKey = $"{rKeyProjAll}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<AnagProgettiModel>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new List<AnagProgettiModel>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.AnagProjAll(false);
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<AnagProgettiModel>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"AnagProjAll | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera l'elenco dei controlli VC19 nel periodo indicato x dipendente
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,296 @@
|
||||
using GPW.CORE.Data;
|
||||
using GPW.CORE.Data.DbModels;
|
||||
using Newtonsoft.Json;
|
||||
using RestSharp;
|
||||
using StackExchange.Redis;
|
||||
using System.Web;
|
||||
|
||||
namespace GPW.CORE.Smart.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Servizi e dati condivisi a livello applicazione
|
||||
/// </summary>
|
||||
public class LicenseService
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Init classe
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="distributedCache"></param>
|
||||
public LicenseService(IConfiguration configuration, ILogger<LicenseService> logger, IConnectionMultiplexer redisConnMult)
|
||||
{
|
||||
_logger = logger;
|
||||
_configuration = configuration;
|
||||
// Conf cache
|
||||
redisConn = redisConnMult;// ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
|
||||
redisDb = this.redisConn.GetDatabase();
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Events
|
||||
|
||||
public event Action EA_InfoUpdated = null!;
|
||||
|
||||
#endregion Public Events
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public List<LiManObj.AttivazioneDTO> ActivList { get; set; } = new List<LiManObj.AttivazioneDTO>();
|
||||
public List<AnagKeyValueModel> AKVList { get; set; } = new List<AnagKeyValueModel>();
|
||||
public string Applicazione { get; set; } = "";
|
||||
|
||||
public bool HasActivData
|
||||
{
|
||||
get
|
||||
{
|
||||
bool answ = ValidData;
|
||||
// se ok controllo che ci siano attivazioni
|
||||
if (answ)
|
||||
{
|
||||
// provo classe locale...
|
||||
answ = ActivList != null && ActivList.Count > 0;
|
||||
// se non le avessi carico!
|
||||
if (!answ)
|
||||
{
|
||||
var pUpd = Task.Run(async () =>
|
||||
{
|
||||
ActivList = await ActivListCache();
|
||||
});
|
||||
pUpd.Wait();
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime infoExpiry { get; set; } = DateTime.Today.AddDays(1);
|
||||
public string Installazione { get; set; } = "";
|
||||
public string MasterKey { get; set; } = "";
|
||||
|
||||
public bool ValidData
|
||||
{
|
||||
get
|
||||
{
|
||||
// controllo valori string base
|
||||
bool checkData = !string.IsNullOrEmpty(Installazione) && !string.IsNullOrEmpty(Applicazione) && !string.IsNullOrEmpty(MasterKey);
|
||||
return checkData;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public async Task<List<LiManObj.AttivazioneDTO>> ActivListCache()
|
||||
{
|
||||
List<LiManObj.AttivazioneDTO> dbResult = new List<LiManObj.AttivazioneDTO>();
|
||||
string cacheKey = $"{rKeyAttByLic}:{MasterKey}";
|
||||
string rawData = await getRSV(cacheKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var cacheRes = JsonConvert.DeserializeObject<List<LiManObj.AttivazioneDTO>?>(rawData);
|
||||
if (cacheRes != null)
|
||||
{
|
||||
dbResult = cacheRes;
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult(dbResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init della classe con variabili di base da Redis/DB
|
||||
/// </summary>
|
||||
public bool InitAkv()
|
||||
{
|
||||
bool fatto = false;
|
||||
Installazione = getAVKStr("installazione");
|
||||
MasterKey = getAVKStr(Installazione);
|
||||
fatto = !string.IsNullOrEmpty($"{Installazione}{MasterKey}");
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init della classe con variabili di base da Redis/DB
|
||||
/// </summary>
|
||||
public async Task<bool> RefreshLicense()
|
||||
{
|
||||
bool fatto = false;
|
||||
var onlineAct = await OnlineActivationList();
|
||||
if (onlineAct != null)
|
||||
{
|
||||
if (onlineAct.Count > 0)
|
||||
{
|
||||
// scadenza info a 15 gg...
|
||||
int numDays = 15;
|
||||
infoExpiry = DateTime.Now.AddDays(numDays);
|
||||
ActivList = onlineAct;
|
||||
fatto = await setActivList(onlineAct, numDays);
|
||||
}
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return fatto;
|
||||
}
|
||||
|
||||
public async Task<bool> setActivList(List<LiManObj.AttivazioneDTO> newActList, int numDays)
|
||||
{
|
||||
bool fatto = false;
|
||||
string cacheKey = $"{rKeyAttByLic}:{MasterKey}";
|
||||
var rawData = JsonConvert.SerializeObject(newActList);
|
||||
await setRSV(cacheKey, rawData, numDays * 24);
|
||||
fatto = true;
|
||||
if (EA_InfoUpdated != null)
|
||||
{
|
||||
EA_InfoUpdated?.Invoke();
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Chiave redis x attivazioni della licenza
|
||||
/// </summary>
|
||||
protected const string rKeyAttByLic = "LongCache:AttByLic";
|
||||
|
||||
protected Random rnd = new Random();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Cerca di recuperare valore string da elenco AKV
|
||||
/// </summary>
|
||||
/// <param name="varReq">Chiave AKV richiesta</param>
|
||||
/// <returns></returns>
|
||||
protected string getAVKStr(string varReq)
|
||||
{
|
||||
string answ = "";
|
||||
if (AKVList != null && AKVList.Count > 0)
|
||||
{
|
||||
var currRec = AKVList.Where(x => x.NomeVar == varReq).FirstOrDefault();
|
||||
if (currRec != null)
|
||||
{
|
||||
answ = $"{currRec.ValString}";
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero chiave da redis
|
||||
/// </summary>
|
||||
/// <param name="rKey"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<string> getRSV(string rKey)
|
||||
{
|
||||
string answ = "";
|
||||
string? rawData = await redisDb.StringGetAsync(rKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
answ = rawData;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salvataggio chiave in redis
|
||||
/// </summary>
|
||||
/// <param name="rKey"></param>
|
||||
/// <param name="rVal"></param>
|
||||
/// <param name="cacheMult"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> setRSV(string rKey, string rVal, int cacheMult)
|
||||
{
|
||||
bool fatto = false;
|
||||
fatto = await redisDb.StringSetAsync(rKey, rVal, getCache(cacheMult));
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salvataggio chiave INT in redis
|
||||
/// </summary>
|
||||
/// <param name="rKey"></param>
|
||||
/// <param name="rValInt"></param>
|
||||
/// <param name="cacheMult"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> setRSV(string rKey, int rValInt, int cacheMult)
|
||||
{
|
||||
return await setRSV(rKey, $"{rValInt}", cacheMult);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static IConfiguration? _configuration;
|
||||
private static ILogger<LicenseService>? _logger;
|
||||
|
||||
/// <summary>
|
||||
/// URL dell'API x chiamate gestione licenze
|
||||
/// </summary>
|
||||
private static string apiUrl = "https://liman.egalware.com/ELM.API/";
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto per connessione a REDIS
|
||||
/// </summary>
|
||||
private IConnectionMultiplexer redisConn;
|
||||
|
||||
//ISubscriber sub = redis.GetSubscriber();
|
||||
/// <summary>
|
||||
/// Oggetto DB redis da impiegare x chiamate R/W
|
||||
/// </summary>
|
||||
private IDatabase redisDb = null!;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache da moltiplicatore (orario) + perturbazione percentuale (+/-10%)
|
||||
/// </summary>
|
||||
private TimeSpan getCache(int cacheMult)
|
||||
{
|
||||
return TimeSpan.FromHours((double)cacheMult * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco attivazioni attuali
|
||||
/// </summary>
|
||||
private async Task<List<LiManObj.AttivazioneDTO>?> OnlineActivationList()
|
||||
{
|
||||
List<LiManObj.AttivazioneDTO>? answ = new List<LiManObj.AttivazioneDTO>();
|
||||
// cerco online
|
||||
RestClient client = new RestClient(apiUrl);
|
||||
//client.Authenticator = new HttpBasicAuthenticator("username", "password");
|
||||
string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
|
||||
var request = new RestRequest($"/api/attivazioni/?chiave={MKeyEnc}", Method.Get);
|
||||
var response = await client.GetAsync(request);
|
||||
// controllo risposta
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
// salvo in redis contenuto serializzato
|
||||
string rawData = $"{response.Content}";
|
||||
answ = JsonConvert.DeserializeObject<List<LiManObj.AttivazioneDTO>?>(rawData);
|
||||
}
|
||||
return await Task.FromResult(answ);
|
||||
}
|
||||
|
||||
private void ReportUpdated()
|
||||
{
|
||||
if (EA_InfoUpdated != null)
|
||||
{
|
||||
EA_InfoUpdated?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.2.0" />
|
||||
<PackageReference Include="Blazored.SessionStorage" Version="2.3.0" />
|
||||
<PackageReference Include="RestSharp" Version="108.0.1" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.6.86" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ builder.Services.Configure<MailKitEmailSenderOptions>(options =>
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddServerSideBlazor();
|
||||
builder.Services.AddSingleton<CoreSmartDataService>();
|
||||
builder.Services.AddSingleton<LicenseService>();
|
||||
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
|
||||
builder.Services.AddScoped<MessageService>();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"CodApp": "GPW",
|
||||
"ConnectionStrings": {
|
||||
"Redis": "localhost:6379,DefaultDatabase=15,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false",
|
||||
"GPW.DB": "Server=SQLSTEAM;Database=GPW; User ID=sa;Password=keyhammer; integrated security=False; MultipleActiveResultSets=True; App=GPW.CORE.WRKLOG;"
|
||||
@@ -26,5 +27,6 @@
|
||||
"UrlLinkInt": "https://iis01.egalware.com/GPW/CORE.Smart/",
|
||||
//"LinkInt": "https://iis03.egalware.com/GPW/CORE.Smart/",
|
||||
"UrlLinkExt": "https://iis03.egalware.com/GPW/CORE.Smart/"
|
||||
}
|
||||
},
|
||||
"VetoIns": "true"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user