Update gest AnagFasi

This commit is contained in:
Samuele Locatelli
2024-09-11 12:10:17 +02:00
parent 4ddb77bcaf
commit 4842e8d81f
14 changed files with 881 additions and 344 deletions
+45 -24
View File
@@ -37,8 +37,8 @@
<th>Ore/Budget</th>
<th>% Abil</th>
<th>Attivo</th>
<th>Nuova Fase</th>
<th style="width: 3rem;"></th>
<th class="text-end"><button class="btn btn-success btn-sm" @onclick="() => AddFase(0)"><i class="fa-solid fa-plus"></i> Nuova Fase</button></th>
<th class="text-end" style="width: 3rem;"></th>
</tr>
</thead>
<tbody>
@@ -58,25 +58,37 @@
}
</td>
<td>
<div>
<b>@item.NomeFase</b>
<div class="small">@item.DescrizioneFase</div>
<div class="d-flex">
@if (item.IdxFaseAncest > 0)
{
<div class="px-2"><i class="fa-solid fa-ellipsis-vertical"></i></div>
}
<div class="px-2">
<b>@item.NomeFase</b>
<div class="small">@item.DescrizioneFase</div>
</div>
</div>
</td>
<td>
@if (item.IdxFaseAncest > 0)
{
<i>label?!?</i>
<select @bind="@item.CodTagFase" class="form-select form-select-sm" title="Cliente" disabled style="width: 12rem;">
<option value="0">--- Selezionare ---</option>
@foreach (var iTag in ListTagFasi)
{
<option value="@iTag.CodTagFase">@($"[{iTag.CodTagFase}] {iTag.Descrizione}")</option>
}
</select>
}
</td>
<td>
<td class="fs-4">
@if (item.EnableTime)
{
<i class="fa-solid fa-stopwatch text-primary"></i>
}
else
{
<i class="fa-solid fa-stopwatch text-secondary disabled"></i>
<i class="fa-solid fa-stopwatch text-secondary opacity-50"></i>
}
</td>
<td>
@@ -86,34 +98,43 @@
}
else
{
<i class="fa-solid fa-money-bills text-secondary disabled"></i>
<i class="fa-solid fa-money-bills text-secondary opacity-50"></i>
}
</td>
<td>
colore ore
@* <div class="text-center py-1 @colorByVal(item.totOre, item.budgetTime)">
<b>@($"{item.totOre:N2}")</b> / @($"{item.budgetTime:N0}")
</div> *@
@if (item.BudgetTime > 0)
{
<div class="text-center py-1 @ColorByVal(item.TotOre, item.BudgetTime)">
<b>@($"{item.TotOre:N2}")</b> / @($"{item.BudgetTime:N0}")
</div>
}
</td>
<td>
abil
@if (item.IdxFaseAncest == 0)
{
@($"{item.PercOpen:P0}")
}
</td>
<td>
att
</td>
<td>
add sottofase
<div class="form-check">
<input class="form-check-input" disabled type="checkbox" @bind="@item.Attivo">
</div>
</td>
<td class="text-end">
@* @if (item.ore == 0)
{
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
}
else
@if (item.IdxFaseAncest == 0)
{
<button class="btn btn-primary btn-sm" @onclick="() => AddFase(0)"><i class="fa-solid fa-plus"></i> Nuova Sottofase</button>
}
</td>
<td class="text-end">
@if (DelEnabled(item.TotOre, item.IdxFase, item.IdxFaseAncest))
{
<button class="btn btn-danger btn-sm" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash"></i></button>
}
@* else
{
<button class="btn btn-secondary btn-sm" disabled><i class="fa-solid fa-trash"></i></button>
} *@
btn delete?
</td>
</tr>
}
+141 -22
View File
@@ -7,16 +7,26 @@ namespace GPW.CORE.ADM.Components.Compo
{
public partial class FasiMan
{
#region Public Properties
[Parameter]
public List<AnagFasiModel>? ListRecords { get; set; } = null;
public List<AnagFasiExplModel>? ListRecords { get; set; } = null;
#endregion Public Properties
private bool isLoading { get; set; } = false;
private int totalCount { get; set; } = 0;
#region Protected Properties
[Inject]
protected MessageService AppMServ { get; set; } = null!;
protected string CheckSel(AnagFasiModel curItem)
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected string CheckSel(AnagFasiExplModel curItem)
{
string answ = "";
if (RecordSel != null)
@@ -28,32 +38,26 @@ namespace GPW.CORE.ADM.Components.Compo
return answ;
}
protected override async Task OnParametersSetAsync()
protected async Task DoDelete(AnagFasiExplModel? selItem)
{
await Task.Delay(1);
totalCount = ListRecords.Count;
isLoading = false;
if (selItem != null)
{
}
}
private string gridKey = "FasiMan";
[Inject]
protected GpwDataService GDataServ { get; set; } = null!;
[Inject]
protected MessageService AppMServ { get; set; } = null!;
private AnagFasiModel? RecordSel = null;
private AnagFasiModel? RecordEdit = null;
protected void DoSelect(AnagFasiModel? selItem)
{
RecordSel = selItem;
RecordEdit = null;
}
protected void DoEdit(AnagFasiModel? selItem)
protected void DoEdit(AnagFasiExplModel? selItem)
{
RecordSel = null;
RecordEdit = selItem;
}
protected void DoSelect(AnagFasiExplModel? selItem)
{
RecordSel = selItem;
RecordEdit = null;
}
protected async Task ForceReload()
{
RecordEdit = null;
@@ -61,5 +65,120 @@ namespace GPW.CORE.ADM.Components.Compo
await Task.Delay(1);
isLoading = false;
}
/// <summary>
/// init valori da config
/// </summary>
/// <returns></returns>
protected async Task initConf()
{
// leggo conf standard controllo RegAtt
var sWarningRatioPerc = await GDataServ.ConfigGetKey("WarningRatioPerc");
if (sWarningRatioPerc != null)
{
double.TryParse(sWarningRatioPerc.valore, out warnRatio);
}
}
protected override async Task OnInitializedAsync()
{
await initConf();
await ReloadData();
}
protected override async Task OnParametersSetAsync()
{
await Task.Delay(1);
totalCount = ListRecords.Count;
isLoading = false;
}
#endregion Protected Methods
#region Private Fields
private string gridKey = "FasiMan";
private AnagFasiExplModel? RecordEdit = null;
private AnagFasiExplModel? RecordSel = null;
private double warnRatio = 50;
#endregion Private Fields
#region Private Properties
private bool isLoading { get; set; } = false;
private List<AnagTagFasiModel> ListTagFasi { get; set; } = new List<AnagTagFasiModel>();
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
/// <summary>
/// restituisce una classe css a seconda dei valori passati:
/// green: bdgt &gt; real
/// orange: real &gt; bdgt*warning
/// red: real &gt; bdgt
/// std: errore...
/// </summary>
/// <param name="real"></param>
/// <param name="bdgt"></param>
/// <returns></returns>
private string ColorByVal(object real, object bdgt)
{
string specClass = "default";
try
{
double valoreReal = Convert.ToDouble(real);
double valoreBdget = Convert.ToDouble(bdgt);
double valoreWarn = Convert.ToDouble(bdgt) * warnRatio / 100;
if (valoreReal >= valoreBdget)
{
specClass = "danger";
}
else if (valoreReal >= valoreWarn)
{
specClass = "warning";
}
else
{
specClass = "success";
}
}
catch
{ }
return $" bg-{specClass} bg-opacity-50 bg-gradient border border-{specClass} rounded";
}
private bool DelEnabled(decimal TotOre, int idxFase, int idxFaseAnc)
{
// se ha ore NON è eliminabile...
bool answ = TotOre == 0;
// se zero ore --> deve esere child oppure ancestor senza fasi...
if (answ)
{
// se ancestor
if (idxFaseAnc == 0)
{
// cerco fasi dato ancestor...
var listChild = GDataServ.AnagFasiByAncestor(idxFase);
// solo se NON ha fasi child
answ = listChild == null || listChild.Count == 0;
}
}
return answ;
}
private async Task ReloadData()
{
ListTagFasi = await GDataServ.AnagTagFasiAll();
}
#endregion Private Methods
}
}
@@ -169,7 +169,7 @@
</div>
</td>
<td>
<div class="text-center py-1 @colorByVal(RecordSel.totOre, RecordSel.budgetTime)">
<div class="text-center py-1 @ColorByVal(RecordSel.totOre, RecordSel.budgetTime)">
<b>@($"{RecordSel.totOre:N2}")</b> / @($"{RecordSel.budgetTime:N0}")
</div>
</td>
@@ -221,7 +221,7 @@
</div>
</td>
<td>
<div class="text-center py-1 @colorByVal(item.totOre, item.budgetTime)">
<div class="text-center py-1 @ColorByVal(item.totOre, item.budgetTime)">
<b>@($"{item.totOre:N2}")</b> / @($"{item.budgetTime:N0}")
</div>
</td>
@@ -119,13 +119,13 @@ namespace GPW.CORE.ADM.Components.Compo
RecordEdit = null;
}
private List<AnagFasiModel>? ListFasiSel { get; set; } = null;
private List<AnagFasiExplModel>? ListFasiSel { get; set; } = null;
protected async Task DoShowFasi(CalcOreProgettiModel? selItem)
{
FullEdit = false;
// carico le fasi e le asso al controllo!
ListFasiSel = await GDataServ.AnagFasiByProj(selItem.IdxProgetto);
ListFasiSel = await GDataServ.AnagFasiExplByProj(selItem.IdxProgetto);
ShowFasi = true;
RecordSel = selItem;
RecordEdit = null;
@@ -285,7 +285,7 @@ namespace GPW.CORE.ADM.Components.Compo
/// <param name="real"></param>
/// <param name="bdgt"></param>
/// <returns></returns>
private string colorByVal(object real, object bdgt)
private string ColorByVal(object real, object bdgt)
{
string specClass = "default";
try
+1 -1
View File
@@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>4.1.2409.1110</Version>
<Version>4.1.2409.1111</Version>
</PropertyGroup>
<ItemGroup>
+253 -136
View File
@@ -21,6 +21,7 @@ namespace GPW.CORE.Data.Controllers
#endregion Public Constructors
#region Public Methods
/// <summary>
/// Recupera l'elenco Clienti (tutti)
/// </summary>
@@ -48,13 +49,64 @@ namespace GPW.CORE.Data.Controllers
return dbResult;
}
/// <summary>
/// Elimina il cliente (se non ci sono relazioni con fasi attive, in tal caso rende disattivo...)
/// </summary>
/// <returns></returns>
public bool AnagClientiDelete(AnagClientiModel remRec)
{
// init
bool answ = false;
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero cliente in primis...
var dbRec = localDbCtx
.DbSetAnagClienti
.Where(x => x.IdxCliente == remRec.IdxCliente)
.FirstOrDefault();
if (dbRec != null)
{
// controllo se abbia progetti associati
var listFasi = localDbCtx
.DbSetAnagProgetti
.Where(x => x.IdxCliente == remRec.IdxCliente)
.ToList();
// --> in tal caso disattivo...
if (listFasi != null && listFasi.Count > 0)
{
dbRec.Attivo = false;
//set modificato
localDbCtx.Entry(dbRec).State = EntityState.Modified;
}
else
{
// altrimenti elimino davvero...
localDbCtx
.DbSetAnagClienti
.Remove(dbRec);
}
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Errore in AnagClientiDelete:{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Recupera l'elenco Clienti (tutti)
/// </summary>
/// <returns></returns>
public bool AnagClientiUpsert(AnagClientiModel upsRec)
{
// init
// init
bool answ = false;
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
@@ -99,56 +151,6 @@ namespace GPW.CORE.Data.Controllers
}
return answ;
}
/// <summary>
/// Elimina il cliente (se non ci sono relazioni con fasi attive, in tal caso rende disattivo...)
/// </summary>
/// <returns></returns>
public bool AnagClientiDelete(AnagClientiModel remRec)
{
// init
bool answ = false;
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero cliente in primis...
var dbRec = localDbCtx
.DbSetAnagClienti
.Where(x => x.IdxCliente == remRec.IdxCliente)
.FirstOrDefault();
if (dbRec != null)
{
// controllo se abbia progetti associati
var listFasi = localDbCtx
.DbSetAnagProgetti
.Where(x => x.IdxCliente == remRec.IdxCliente)
.ToList();
// --> in tal caso disattivo...
if (listFasi != null && listFasi.Count > 0)
{
dbRec.Attivo = false;
//set modificato
localDbCtx.Entry(dbRec).State = EntityState.Modified;
}
else
{
// altrimenti elimino davvero...
localDbCtx
.DbSetAnagClienti
.Remove(dbRec);
}
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Errore in AnagClientiDelete:{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Cerca un device dato il suo secret
@@ -323,6 +325,39 @@ namespace GPW.CORE.Data.Controllers
return dbResult;
}
/// <summary>
/// Elenco fasi dato ancestor
/// </summary>
/// <param name="idxFaseAnc"></param>
/// <returns></returns>
public List<AnagFasiModel> AnagFasiByAncestor(int idxFaseAnc)
{
// init dati necessari
List<AnagFasiModel> dbResult = new List<AnagFasiModel>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero intero set...
var searchRecord = localDbCtx
.DbSetAnagFasi
.Where(x => x.IdxFaseAncest == idxFaseAnc)
.Include(p => p.ProgettoNav)
.ToList();
if (searchRecord != null)
{
dbResult = searchRecord;
}
}
catch (Exception exc)
{
Log.Error($"Errore in AnagFasiByAncestor:{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Elenco fasi dato chiave progetto
/// </summary>
@@ -353,6 +388,35 @@ namespace GPW.CORE.Data.Controllers
return dbResult;
}
/// <summary>
/// Elenco FasiExpl dato chiave progetto
/// </summary>
/// <param name="idxProj"></param>
/// <returns></returns>
public List<AnagFasiExplModel> AnagFasiExplByProj(int idxProj)
{
// init dati necessari
List<AnagFasiExplModel> dbResult = new List<AnagFasiExplModel>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
var pIdxPrj = new SqlParameter("@idxProgetto", idxProj);
dbResult = localDbCtx
.DbSetAnagFasiExpl
.FromSqlRaw("EXEC stp_AF_getByIdxProj @idxProgetto", pIdxPrj)
.ToList();
}
catch (Exception exc)
{
Log.Error($"Errore in AnagFasiExplByProj:{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Elenco Giustificativi
/// </summary>
@@ -522,7 +586,6 @@ namespace GPW.CORE.Data.Controllers
return dbResult;
}
public AnagProgettiModel AnagProjByKey(int IdxProj)
{
// init dati necessari
@@ -535,9 +598,9 @@ namespace GPW.CORE.Data.Controllers
// recupero intero set....
var dbRec = localDbCtx
.DbSetAnagProgetti
.Where(x => (x.IdxProgetto==IdxProj))
.Where(x => (x.IdxProgetto == IdxProj))
.FirstOrDefault();
if(dbRec!=null)
if (dbRec != null)
{
dbResult = dbRec;
}
@@ -549,6 +612,7 @@ namespace GPW.CORE.Data.Controllers
}
return dbResult;
}
/// <summary>
/// Elenco progetti calcolati con ore avanzamento filtrata
/// </summary>
@@ -579,7 +643,7 @@ namespace GPW.CORE.Data.Controllers
public bool AnagProjDelete(AnagProgettiModel remRec)
{
// init
// init
bool answ = false;
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
@@ -624,85 +688,6 @@ namespace GPW.CORE.Data.Controllers
return answ;
}
public bool AnagProjUpsert(AnagProgettiModel upsRec)
{
// init
bool answ = false;
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero cliente in primis...
var dbRec = localDbCtx
.DbSetAnagProgetti
.Where(x => x.IdxProgetto == upsRec.IdxProgetto)
.FirstOrDefault();
if (dbRec == null)
{
localDbCtx
.DbSetAnagProgetti
.Add(upsRec);
}
else
{
dbRec.Attivo = upsRec.Attivo;
dbRec.Avvio = upsRec.Avvio;
dbRec.Chiusura = upsRec.Chiusura;
dbRec.CodExt = upsRec.CodExt;
dbRec.DescrProj = upsRec.DescrProj;
dbRec.Gruppo = upsRec.Gruppo;
dbRec.IdxCliente = upsRec.IdxCliente;
dbRec.NomeProj = upsRec.NomeProj;
dbRec.OldIdx = upsRec.OldIdx;
dbRec.Starred = upsRec.Starred;
//set modificato
localDbCtx.Entry(dbRec).State = EntityState.Modified;
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Errore in AnagProjUpsert:{Environment.NewLine}{exc}");
}
}
return answ;
}
public bool AnagProjUpdStatus(int IdxProj, bool Attivo, bool Starred)
{
// init
bool answ = false;
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero cliente in primis...
var dbRec = localDbCtx
.DbSetAnagProgetti
.Where(x => x.IdxProgetto == IdxProj)
.FirstOrDefault();
if (dbRec != null)
{
dbRec.Attivo = Attivo;
dbRec.Starred = Starred;
//set modificato
localDbCtx.Entry(dbRec).State = EntityState.Modified;
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Errore in AnagProjUpdStatus:{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Clona record Progetti con stored
/// </summary>
@@ -752,6 +737,138 @@ namespace GPW.CORE.Data.Controllers
return result != 0;
}
public bool AnagProjUpdStatus(int IdxProj, bool Attivo, bool Starred)
{
// init
bool answ = false;
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero cliente in primis...
var dbRec = localDbCtx
.DbSetAnagProgetti
.Where(x => x.IdxProgetto == IdxProj)
.FirstOrDefault();
if (dbRec != null)
{
dbRec.Attivo = Attivo;
dbRec.Starred = Starred;
//set modificato
localDbCtx.Entry(dbRec).State = EntityState.Modified;
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Errore in AnagProjUpdStatus:{Environment.NewLine}{exc}");
}
}
return answ;
}
public bool AnagProjUpsert(AnagProgettiModel upsRec)
{
// init
bool answ = false;
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero cliente in primis...
var dbRec = localDbCtx
.DbSetAnagProgetti
.Where(x => x.IdxProgetto == upsRec.IdxProgetto)
.FirstOrDefault();
if (dbRec == null)
{
localDbCtx
.DbSetAnagProgetti
.Add(upsRec);
}
else
{
dbRec.Attivo = upsRec.Attivo;
dbRec.Avvio = upsRec.Avvio;
dbRec.Chiusura = upsRec.Chiusura;
dbRec.CodExt = upsRec.CodExt;
dbRec.DescrProj = upsRec.DescrProj;
dbRec.Gruppo = upsRec.Gruppo;
dbRec.IdxCliente = upsRec.IdxCliente;
dbRec.NomeProj = upsRec.NomeProj;
dbRec.OldIdx = upsRec.OldIdx;
dbRec.Starred = upsRec.Starred;
//set modificato
localDbCtx.Entry(dbRec).State = EntityState.Modified;
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Errore in AnagProjUpsert:{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Elenco Tags
/// </summary>
/// <returns></returns>
public List<AnagTagModel> AnagTagAll()
{
// init dati necessari
List<AnagTagModel> dbResult = new List<AnagTagModel>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero intero set...
dbResult = localDbCtx
.DbSetAnagTag
.OrderBy(x => x.Descrizione)
.ToList();
}
catch (Exception exc)
{
Log.Error($"Errore in AnagTagAll:{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Elenco Tags
/// </summary>
/// <returns></returns>
public List<AnagTagFasiModel> AnagTagFasiAll()
{
// init dati necessari
List<AnagTagFasiModel> dbResult = new List<AnagTagFasiModel>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero intero set...
dbResult = localDbCtx
.DbSetAnagTagFasi
.OrderBy(x => x.Descrizione)
.ToList();
}
catch (Exception exc)
{
Log.Error($"Errore in AnagTagFasiAll:{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Vista dati per FASE con totalizzaizone ore budget/real
/// </summary>
@@ -762,11 +879,11 @@ namespace GPW.CORE.Data.Controllers
CalcOreFasiModel dbResult = new CalcOreFasiModel();
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
var parIdxFase = new SqlParameter("@idxFase", idxFase);
var parIdxFase = new SqlParameter("@idxFaseAnc", idxFase);
var rawResult = localDbCtx
.DbSetCalcOreFasi
.FromSqlRaw("EXEC stp_AF_getByIdxFase_Child @idxFase", parIdxFase)
.FromSqlRaw("EXEC stp_AF_getByIdxFase_Child @idxFaseAnc", parIdxFase)
.ToList();
if (rawResult != null && rawResult.Count > 0)
{
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
public partial class AnagFasiExplModel
{
[Key]
public int IdxFase { get; set; }
public int? IdxProgetto { get; set; }
/// <summary>
/// codice fase gerarchico (F.1.2. = Fase 1, sottofase 2) - aggiornare con trigger!
/// </summary>
public string CodFase { get; set; } = "";
/// <summary>
/// fase ANCESTOR (contenitore), 0 = è top level
/// </summary>
public int IdxFaseAncest { get; set; } = 0;
public string NomeFase { get; set; } = "";
public string DescrizioneFase { get; set; } = "";
/// <summary>
/// indica se sia abilitata o meno a ricevere assegnazioni di record temporali
/// </summary>
public bool EnableTime { get; set; } = true;
/// <summary>
/// indica se sia abilitata o meno a ricevere assegnazioni di record di spesa
/// </summary>
public bool EnableMoney { get; set; } = false;
public bool Attivo { get; set; } = true;
/// <summary>
/// codice univoco
/// </summary>
public string CodClasse { get; set; } = "";
/// <summary>
/// codice esterno
/// </summary>
public string CodExt { get; set; } = "";
public decimal TotOre { get; set; } = 0;
/// <summary>
/// Budget del progetto (in ore)
/// </summary>
public decimal BudgetTime { get; set; } = 0;
public decimal BudgetMoney { get; set; } = 0;
public double PercOpen { get; set; } = 0;
public string CodTagFase { get; set; } = "";
}
}
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("AnagTagFasi")]
public partial class AnagTagFasiModel
{
[Key]
public string CodTagFase { get; set; } = "";
public string Descrizione { get; set; } = "";
public bool Enabled { get; set; } = true;
public string CodGruppo { get; set; } = "";
}
}
+22
View File
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("AnagTagModel")]
public partial class AnagTagModel
{
[Key]
public string CodTag { get; set; } = "";
public string Descrizione { get; set; } = "";
public bool Enabled { get; set; } = true;
}
}
+3
View File
@@ -46,6 +46,7 @@ namespace GPW.CORE.Data
public virtual DbSet<TimbratureExplModel> DbSetTimbratureExpl { get; set; } = null!;
public virtual DbSet<AnagClientiModel> DbSetAnagClienti { get; set; } = null!;
public virtual DbSet<AnagFasiModel> DbSetAnagFasi { get; set; } = null!;
public virtual DbSet<AnagFasiExplModel> DbSetAnagFasiExpl { get; set; } = null!;
public virtual DbSet<AnagProgettiModel> DbSetAnagProgetti { get; set; } = null!;
public virtual DbSet<AnagGruppiModel> DbSetAnagGruppi { get; set; } = null!;
public virtual DbSet<AnagOrariModel> DbSetAnagOrari { get; set; } = null!;
@@ -66,6 +67,8 @@ namespace GPW.CORE.Data
public virtual DbSet<DipendendiAndAnomalie> DbSetDipAndAnom { get; set; } = null!;
public virtual DbSet<TeRaExplModel> DbSetTeRaExpl { get; set; } = null!;
public virtual DbSet<StatsDayPresModel> DbSetStatsDayPres { get; set; } = null!;
public virtual DbSet<AnagTagModel> DbSetAnagTag { get; set; } = null!;
public virtual DbSet<AnagTagFasiModel> DbSetAnagTagFasi { get; set; } = null!;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
+328 -153
View File
@@ -248,6 +248,47 @@ namespace GPW.CORE.Data.Services
return dbResult;
}
/// <summary>
/// Elenco fasi dato ancestor
/// </summary>
/// <param name="idxFaseAnc"></param>
/// <returns></returns>
public List<AnagFasiModel> AnagFasiByAncestor(int idxFaseAnc)
{
string source = "DB";
List<AnagFasiModel>? dbResult = new List<AnagFasiModel>();
string currKey = $"{rKeyFasiAnc}:{idxFaseAnc}";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string? rawData = redisDb.StringGet(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.AnagFasiByAncestor(idxFaseAnc);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDb.StringSet(currKey, rawData, LongCache);
}
if (dbResult == null)
{
dbResult = new List<AnagFasiModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagFasiByAncestor | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Recupera info x una specifica FASE
/// </summary>
@@ -286,6 +327,8 @@ namespace GPW.CORE.Data.Services
return dbResult;
}
/// <summary>
/// Elenco fasi dato progetto
/// </summary>
@@ -329,6 +372,49 @@ namespace GPW.CORE.Data.Services
return dbResult;
}
/// <summary>
/// Elenco fasi dato progetto
/// </summary>
/// <param name="idxProj"></param>
/// <returns></returns>
public async Task<List<AnagFasiExplModel>?> AnagFasiExplByProj(int idxProj)
{
string source = "DB";
List<AnagFasiExplModel>? dbResult = new List<AnagFasiExplModel>();
// cerco "secca "in redis...
string currKey = $"{rKeyFasiByProj}_EXPL:{idxProj}";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string? rawData = await redisDb.StringGetAsync(currKey);
if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2)
{
source = "REDIS";
var tempResult = JsonConvert.DeserializeObject<List<AnagFasiExplModel>>(rawData);
if (tempResult == null)
{
dbResult = new List<AnagFasiExplModel>();
}
else
{
dbResult = tempResult;
}
}
else
{
dbResult = dbController.AnagFasiExplByProj(idxProj);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
}
if (dbResult == null)
{
dbResult = new List<AnagFasiExplModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagFasiExplByProj | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Elenco Giustificativi
/// </summary>
@@ -371,6 +457,47 @@ namespace GPW.CORE.Data.Services
return dbResult;
}
/// <summary>
/// Elenco gruppi (tutti)
/// </summary>
/// <returns></returns>
public async Task<List<AnagGruppiModel>> AnagGruppiAll()
{
string source = "DB";
List<AnagGruppiModel>? dbResult = new List<AnagGruppiModel>();
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<AnagGruppiModel>>(rawData);
if (tempResult == null)
{
dbResult = new List<AnagGruppiModel>();
}
else
{
dbResult = tempResult;
}
}
else
{
dbResult = dbController.AnagGruppiAll();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
}
if (dbResult == null)
{
dbResult = new List<AnagGruppiModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagGruppiAll | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Recupera l'elenco gruppi abilitati x il dipendente
/// </summary>
@@ -512,156 +639,6 @@ namespace GPW.CORE.Data.Services
Log.Debug($"AnagProjByKey | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Eliminazione record Progetto
/// - se ha fasi associati >> logica (disattiva)
/// - se non ha fasi elimino record
/// </summary>
/// <param name="remItem"></param>
/// <returns></returns>
public async Task<bool> AnagProjDelete(AnagProgettiModel remItem)
{
bool answ = false;
try
{
answ = dbController.AnagProjDelete(remItem);
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjDelete{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Upsert record Progetti
/// </summary>
/// <param name="currItem"></param>
/// <returns></returns>
public async Task<bool> AnagProjUpsert(AnagProgettiModel currItem)
{
bool answ = false;
try
{
answ = dbController.AnagProjUpsert(currItem);
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjUpsert{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Upsert record Progetti x stato attivo e starred
/// </summary>
/// <param name="IdxProj"></param>
/// <param name="Attivo"></param>
/// <param name="Starred"></param>
/// <returns></returns>
public async Task<bool> AnagProjUpdStatus(int IdxProj, bool Attivo, bool Starred)
{
bool answ = false;
try
{
answ = dbController.AnagProjUpdStatus(IdxProj, Attivo, Starred);
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjUpdStatus{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Clona record Progetti con stored
/// </summary>
/// <param name="IdxProj"></param>
/// <param name="NewName"></param>
/// <param name="DoYearSubst"></param>
/// <returns></returns>
public async Task<bool> AnagProjDoClone(int IdxProj, string NewName, bool DoYearSubst)
{
bool answ = false;
try
{
answ = dbController.AnagProjDoClone(IdxProj, NewName, DoYearSubst);
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjDoClone{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Forza ricalcolo statistiche progetti (ALL)
/// </summary>
/// <returns></returns>
public async Task<bool> AnagProjForceUpdate()
{
bool answ = false;
try
{
answ = dbController.AnagProjForceUpdate();
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjForceUpdate{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Elenco gruppi (tutti)
/// </summary>
/// <returns></returns>
public async Task<List<AnagGruppiModel>> AnagGruppiAll()
{
string source = "DB";
List<AnagGruppiModel>? dbResult = new List<AnagGruppiModel>();
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<AnagGruppiModel>>(rawData);
if (tempResult == null)
{
dbResult = new List<AnagGruppiModel>();
}
else
{
dbResult = tempResult;
}
}
else
{
dbResult = dbController.AnagGruppiAll();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
}
if (dbResult == null)
{
dbResult = new List<AnagGruppiModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagGruppiAll | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Elenco progetti calcolati con ore avanzamento filtrata
@@ -713,6 +690,73 @@ namespace GPW.CORE.Data.Services
Log.Debug($"AnagProjCalcFilt | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Eliminazione record Progetto
/// - se ha fasi associati &gt;&gt; logica (disattiva)
/// - se non ha fasi elimino record
/// </summary>
/// <param name="remItem"></param>
/// <returns></returns>
public async Task<bool> AnagProjDelete(AnagProgettiModel remItem)
{
bool answ = false;
try
{
answ = dbController.AnagProjDelete(remItem);
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjDelete{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Clona record Progetti con stored
/// </summary>
/// <param name="IdxProj"></param>
/// <param name="NewName"></param>
/// <param name="DoYearSubst"></param>
/// <returns></returns>
public async Task<bool> AnagProjDoClone(int IdxProj, string NewName, bool DoYearSubst)
{
bool answ = false;
try
{
answ = dbController.AnagProjDoClone(IdxProj, NewName, DoYearSubst);
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjDoClone{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Forza ricalcolo statistiche progetti (ALL)
/// </summary>
/// <returns></returns>
public async Task<bool> AnagProjForceUpdate()
{
bool answ = false;
try
{
answ = dbController.AnagProjForceUpdate();
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjForceUpdate{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Recupera info x uno specifico PROJ
/// </summary>
@@ -732,6 +776,134 @@ namespace GPW.CORE.Data.Services
return dbResult;
}
/// <summary>
/// Upsert record Progetti x stato attivo e starred
/// </summary>
/// <param name="IdxProj"></param>
/// <param name="Attivo"></param>
/// <param name="Starred"></param>
/// <returns></returns>
public async Task<bool> AnagProjUpdStatus(int IdxProj, bool Attivo, bool Starred)
{
bool answ = false;
try
{
answ = dbController.AnagProjUpdStatus(IdxProj, Attivo, Starred);
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjUpdStatus{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Upsert record Progetti
/// </summary>
/// <param name="currItem"></param>
/// <returns></returns>
public async Task<bool> AnagProjUpsert(AnagProgettiModel currItem)
{
bool answ = false;
try
{
answ = dbController.AnagProjUpsert(currItem);
// invalido la cache...
await ExecFlushRedisPattern($"{redisBaseAddr}:*");
}
catch (Exception exc)
{
Log.Error($"Eccezione in AnagProjUpsert{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Elenco TagFasi
/// </summary>
/// <returns></returns>
public async Task<List<AnagTagModel>> AnagTagAll()
{
string source = "DB";
List<AnagTagModel>? dbResult = new List<AnagTagModel>();
// cerco "secca "in redis...
string currKey = $"{rKeyTags}:GEN";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string? rawData = await redisDb.StringGetAsync(currKey);
if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2)
{
source = "REDIS";
var tempResult = JsonConvert.DeserializeObject<List<AnagTagModel>>(rawData);
if (tempResult == null)
{
dbResult = new List<AnagTagModel>();
}
else
{
dbResult = tempResult;
}
}
else
{
dbResult = dbController.AnagTagAll();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
}
if (dbResult == null)
{
dbResult = new List<AnagTagModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagTagAll | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Elenco TagFasi
/// </summary>
/// <returns></returns>
public async Task<List<AnagTagFasiModel>> AnagTagFasiAll()
{
string source = "DB";
List<AnagTagFasiModel>? dbResult = new List<AnagTagFasiModel>();
// cerco "secca "in redis...
string currKey = $"{rKeyTags}:FASI";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string? rawData = await redisDb.StringGetAsync(currKey);
if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2)
{
source = "REDIS";
var tempResult = JsonConvert.DeserializeObject<List<AnagTagFasiModel>>(rawData);
if (tempResult == null)
{
dbResult = new List<AnagTagFasiModel>();
}
else
{
dbResult = tempResult;
}
}
else
{
dbResult = dbController.AnagTagFasiAll();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
}
if (dbResult == null)
{
dbResult = new List<AnagTagFasiModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagTagFasiAll | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Vista dati per FASE (tipicamente master...) con totalizzaizone ore budget/real e stato fase
/// </summary>
@@ -2055,9 +2227,11 @@ namespace GPW.CORE.Data.Services
protected const string rKeyDailyData = $"{redisBaseAddr}:Cache:DailyData";
protected const string rKeyDipendenti = $"{redisBaseAddr}:Cache:Dipendenti";
protected const string rKeyEventListDip = $"{redisBaseAddr}:Cache:EventListDip";
protected const string rKeyFasiAll = $"{redisBaseAddr}:Cache:FasiAll";
protected const string rKeyFasiByProj = $"{redisBaseAddr}:Cache:FasiByProj";
protected const string rKeyFasiSearch = $"{redisBaseAddr}:Cache:FasiSearch";
protected const string rKeyFasi = $"{redisBaseAddr}:Cache:Fasi";
protected const string rKeyFasiAll = $"{redisBaseAddr}:Cache:Fasi:All";
protected const string rKeyFasiAnc = $"{redisBaseAddr}:Cache:Fasi:Ancest";
protected const string rKeyFasiByProj = $"{redisBaseAddr}:Cache:Fasi:ByProj";
protected const string rKeyFasiSearch = $"{redisBaseAddr}:Cache:Fasi:Search";
protected const string rKeyGiust = $"{redisBaseAddr}:Cache:Giustif";
protected const string rKeyGrpAll = $"{redisBaseAddr}:Cache:GrpAll";
protected const string rKeyGrpUser = $"{redisBaseAddr}:Cache:GrpUser";
@@ -2068,6 +2242,7 @@ namespace GPW.CORE.Data.Services
protected const string rKeyReportData = $"{redisBaseAddr}:Cache:ReportData";
protected const string rKeyRilTemp = $"{redisBaseAddr}:Cache:RilTemp";
protected const string rKeyStatPresDay = $"{redisBaseAddr}:Cache:StatPresDay";
protected const string rKeyTags = $"{redisBaseAddr}:Cache:Tags";
protected const string rKeyVC19 = $"{redisBaseAddr}:Cache:VC19";
protected const string rKeyVetoIns = $"{redisBaseAddr}:Cache:VetoInsert";
protected const string rKeyWeekStats = $"{redisBaseAddr}:Cache:WeekStats";
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>GPW - Gestione Presenze Web</i>
<h4>Versione: 4.1.2409.1110</h4>
<h4>Versione: 4.1.2409.1111</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
4.1.2409.1110
4.1.2409.1111
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>4.1.2409.1110</version>
<version>4.1.2409.1111</version>
<url>http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html</changelog>
<mandatory>false</mandatory>