3 Commits

Author SHA1 Message Date
Samuele Locatelli 018733e918 Merge branch 'develop' into WasmTest 2026-05-06 11:17:05 +02:00
Samuele E. Locatelli (W11-AI) 18579f792a Merge branch 'develop' of https://gitlab.steamware.net/egalware-web/gest/gpw_next into develop 2026-03-31 18:25:03 +02:00
Samuele E. Locatelli (W11-AI) f9e40a90de Implementazione interfaccia servizi CoreSmart server e x WASM, bozza metodi x WASM http calls 2026-03-31 18:24:59 +02:00
2562 changed files with 7538 additions and 132608 deletions
-36
View File
@@ -1,36 +0,0 @@
# GPW_NEXT Agent Instructions
## Architecture Overview
- **Multi-Project Structure**: The solution consists of several interconnected projects.
- **Smart10 Module**:
- `GPW.CORE.Smart10`: The ASP.NET Core Server project. Hosts API Controllers and implements Server-side logic.
- `GPW.CORE.Smart10.Client`: The Blazor WebAssembly project. Contains UI components and client-side services that consume APIs.
- **Data Layer**:
- `GPW.CORE.Data`: Contains EF Core models (`DbModels`), `GPWContext`, and the `GPWController` which acts as a data access layer.
- `GPW.CORE.Dto`: Contains Data Transfer Objects used for communication between Client and Server to avoid direct dependency on EF Core models.
- **Services Pattern**:
- **Client-side**: Services implement interfaces (e.g., `ITimbraturesService`) and use `HttpClient` to call REST endpoints.
- **Server-side (Prerendering)**: To support Blazor Web App prerendering, implement the same interfaces in the Server project using a "Server-side" implementation that calls `CoreSmartDataService` directly instead of via HTTP.
## Development Workflows
### Implementing New Features (Smart10 Example)
1. **DTO**: Define the required data structure in `GPW.CORE.Dto`.
2. **Server Data Access**: Ensure `CoreSmartDataService` (in `GPW.CORE.Smart10.Data`) or `GPWController` (in `GPW.CORE.Data`) has the necessary business logic.
3. **API Controller**: Add an endpoint in `GPW.CORE.Smart10\Controllers` to expose the data via REST.
4. **Client Interface**: Add the method signature to the interface in `GPW.CORE.Smart10.Client\Services`.
5. **Client Implementation**: Implement the service in `GPW.CORE.Smart10.Client\Services` using `HttpClient`.
6. **Server Implementation (Prerendering Support)**: Create a server-side implementation of the interface in `GPW.CORE.Smart10\Services` that calls `CoreSmartDataService` directly.
7. **Dependency Injection**:
- **Client**: Register the `HttpClient`-based service in `GPW.CORE.Smart10.Client\Program.cs`.
- **Server**: Register the direct-access service in `GPW.CORE.Smart10\Program.cs`.
### Testing & Verification
- **UI Testing**: Use the `Test...razor` pages in the Client project to validate end-to-end flows (Insert, Update, Delete, Search).
- **Manual Check**: For UI changes, verify the interaction between `@bind` and event handlers (use `@bind:after` for .NET 7+).
## Key Constraints & Gotchas
- **NLog**: Do not add `NLog.Web.AspNetCore` to the Client project; it is incompatible with the WASM runtime.
- **UID Logic**: Many entities use a calculated `UID` (e.g., `IdxDipendente_DataOra_Ora`) for RESTful operations (like `DELETE /api/resource/{uid}`) instead of passing entire objects.
- **Prerendering**: Always provide a server-side implementation of client-side services to avoid `InvalidOperationException` during the initial page load.
- **Namespace Integrity**: Be careful with namespaces when moving logic between `GPW.CORE.Smart10` (Server) and `GPW.CORE.Smart10.Client` (Client).
+8 -21
View File
@@ -1,13 +1,10 @@
<div class="card shadow"> <div class="card shadow">
<div class="card-header d-flex justify-content-between"> <div class="card-header">
<div class="px-0">
<h4>Dipendenti</h4> <h4>Dipendenti</h4>
</div>
<div class="px-0">
<div class="row"> <div class="row">
<div class="col-9"> <div class="col-9">
<div class="input-group input-group-sm" runat="server"> <div class="input-group" runat="server">
<span class="input-group-text">Clona</span> <span class="input-group-text">Clona</span>
<select @bind="@idxDipSel" class="form-select form-select-sm"> <select @bind="@idxDipSel" class="form-select form-select-sm">
<option value="0">--- Selezionare ---</option> <option value="0">--- Selezionare ---</option>
@@ -22,10 +19,10 @@
} }
</div> </div>
</div> </div>
<div class="col-3 ps-0"> <div class="col-3">
<div class="input-group input-group-sm" title="Mostra Inattivi"> <div class="input-group">
<span class="input-group-text">All</span> <span class="input-group-text">Show Inatt.</span>
<span class="form-control py-0"> <span class="form-control">
<span class="form-check form-switch"> <span class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@ShowInactive" @bind:after="ReloadData"> <input type="checkbox" class="form-check-input" @bind="@ShowInactive" @bind:after="ReloadData">
</span> </span>
@@ -34,7 +31,6 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="card-body p-1"> <div class="card-body p-1">
@if (ListRecords == null || isLoading) @if (ListRecords == null || isLoading)
{ {
@@ -47,12 +43,12 @@
else else
{ {
<table class="table table-striped table-sm text-start"> <table class="table table-striped table-sm text-start">
@* <thead> <thead>
<tr class=""> <tr class="">
<th>Dipendente</th> <th>Dipendente</th>
<th class="text-end"></th> <th class="text-end"></th>
</tr> </tr>
</thead> *@ </thead>
<tbody> <tbody>
@foreach (var item in ListRecords) @foreach (var item in ListRecords)
{ {
@@ -66,16 +62,7 @@
</tr> </tr>
} }
</tbody> </tbody>
@* <tfoot>
<tr>
<td colspan="2">
</td>
</tr>
</tfoot> *@
</table> </table>
} }
</div> </div>
<div class="card-footer p-0">
<EgwCoreLib.Razor.DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetPage" totalCount="@totalCount" showLoading="@isLoading"></EgwCoreLib.Razor.DataPager>
</div>
</div> </div>
+3 -13
View File
@@ -21,26 +21,16 @@
<label class="small">Exp. Abil</label> <label class="small">Exp. Abil</label>
</div> </div>
</div> </div>
<div class="col-md-1"> <div class="col-md-3">
<div class="form-floating">
<span class="form-control">
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" @bind="@CurrRecord.IsActive">
</div>
</span>
<label class="small">Attivo</label>
</div>
</div>
<div class="col-md-2">
<button class="btn btn-success btn-lg mt-2 w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button> <button class="btn btn-success btn-lg mt-2 w-100" @onclick="() => DoSave()"><i class="fas fa-floppy-disk"></i> Save</button>
</div> </div>
<div class="col-md-10 my-2"> <div class="col-md-9 my-2">
<div class="form-floating"> <div class="form-floating">
<input type="text" class="form-control" @bind="@CurrRecord.DescrGruppo"> <input type="text" class="form-control" @bind="@CurrRecord.DescrGruppo">
<label class="small">Descrizione</label> <label class="small">Descrizione</label>
</div> </div>
</div> </div>
<div class="col-md-2"> <div class="col-md-3">
<button class="btn btn-warning btn-lg mt-2 w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button> <button class="btn btn-warning btn-lg mt-2 w-100" @onclick="() => DoCancel()"><i class="fas fa-ban"></i> Cancel</button>
</div> </div>
</div> </div>
@@ -65,11 +65,11 @@
<div class="col-7"> <div class="col-7">
<div class="card shadow"> <div class="card shadow">
<div class="card-header"> <div class="card-header">
<div class="px-0 d-flex justify-content-between"> <div class="px-0 d-flex">
<div class="px-0"> <div class="px-2">
<h4>Gruppi</h4> <h4>Gruppi</h4>
</div> </div>
<div class="px-0"> <div class="px-2">
<button class="btn btn-success" @onclick=CreateNew tooltip="Add New"><i class="fa-solid fa-plus"></i> Add New</button> <button class="btn btn-success" @onclick=CreateNew tooltip="Add New"><i class="fa-solid fa-plus"></i> Add New</button>
</div> </div>
</div> </div>
@@ -96,7 +96,6 @@
<th>CodExt Grp. <Sorter ParamName="CodExt" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th> <th>CodExt Grp. <Sorter ParamName="CodExt" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th># Dip. <Sorter ParamName="NumDip" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th> <th># Dip. <Sorter ParamName="NumDip" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th>
<th class="text-end"><Sorter ParamName="Export" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter> Exp. Abil</th> <th class="text-end"><Sorter ParamName="Export" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter> Exp. Abil</th>
<th class="text-end"><Sorter ParamName="IsActive" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter> Attivo</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@@ -124,17 +123,14 @@
@item.DescrGruppo @item.DescrGruppo
</td> </td>
<td> <td>
@item.CodExt @item.NumDip
</td> </td>
<td> <td>
@item.NumDip @item.CodExt
</td> </td>
<td class="text-end"> <td class="text-end">
<input class="form-check-input" type="checkbox" disabled role="switch" @bind="@item.ExportEnab"> <input class="form-check-input" type="checkbox" disabled role="switch" @bind="@item.ExportEnab">
</td> </td>
<td class="text-end">
<input class="form-check-input" type="checkbox" disabled role="switch" @bind="@item.IsActive">
</td>
<td> <td>
@if (@item.NumDip == 0) @if (@item.NumDip == 0)
{ {
@@ -246,17 +246,6 @@ namespace GPW.CORE.ADM.Components.Compo
} }
break; break;
case "IsActive":
if (sortAsc)
{
SearchRecords = SearchRecords.OrderBy(x => x.IsActive).ToList();
}
else
{
SearchRecords = SearchRecords.OrderByDescending(x => x.IsActive).ToList();
}
break;
default: default:
break; break;
} }
@@ -42,23 +42,9 @@ namespace GPW.CORE.ADM.Components.Compo
protected async Task DoClone() protected async Task DoClone()
{ {
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler procedere con la clonazione del progetto(+fasi) selezionato?")) if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler procedere con la clonazione del progetto(+fasi) selezionato?"))
return; return;
// verifico se il gruppo sia attivo, se non lo fosse avvisa che andrà cambiato...
var listGroup = await GDataServ.AnagGruppiAll();
if (listGroup != null)
{
var currRec = listGroup.FirstOrDefault(x => x.Gruppo == CurrRecord.Gruppo);
if (currRec != null && !(currRec.IsActive??false))
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Attenzione! l record è associato ad un gruppo disattivo, ricordati di cambiarlo dopo la modifica. Confermi di voler procedere?"))
return;
}
}
bool fatto = false; bool fatto = false;
await Task.Delay(1); await Task.Delay(1);
if (CurrRecord != null) if (CurrRecord != null)
@@ -128,8 +128,8 @@ else
<thead> <thead>
<tr class="bg-dark text-light align-middle"> <tr class="bg-dark text-light align-middle">
<th></th> <th></th>
<th>Dipendente <Sorter ParamName="Dipendente" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th> <th>Dipendente</th>
<th>Periodo <Sorter ParamName="Periodo" IsAsc="@sortAsc" CurrParam="@sortField" sortReq="SortRequested"></Sorter></th> <th>Periodo</th>
<th class="text-end"></th> <th class="text-end"></th>
</tr> </tr>
</thead> </thead>
@@ -3,9 +3,7 @@ using GPW.CORE.Data.Services;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop; using Microsoft.JSInterop;
using NLog; using NLog;
using static EgwCoreLib.Razor.Sorter;
using static EgwCoreLib.Razor.Toggler; using static EgwCoreLib.Razor.Toggler;
using System.Linq.Dynamic.Core;
namespace GPW.CORE.ADM.Components.Compo namespace GPW.CORE.ADM.Components.Compo
{ {
@@ -374,7 +372,11 @@ namespace GPW.CORE.ADM.Components.Compo
} }
// conteggio! // conteggio!
totalCount = SearchRecords.Count; totalCount = SearchRecords.Count;
UpdateTable(); // paginazione
ListRecords = SearchRecords
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
} }
private void toggleEdit() private void toggleEdit()
@@ -383,38 +385,5 @@ namespace GPW.CORE.ADM.Components.Compo
} }
#endregion Private Methods #endregion Private Methods
private bool sortAsc = false;
private string sortField = "";
protected void SortRequested(SortCallBack e)
{
if (sortField == e.ParamName)
{
sortAsc = e.IsAscending;
}
sortField = e.ParamName;
UpdateTable();
}
private void UpdateTable()
{
// 1. Prepariamo la query base
var query = SearchRecords.AsEnumerable();
// 2. Applichiamo l'ordinamento dinamico
query = sortField switch
{
"Dipendente" => sortAsc ? query.OrderBy(x => x.DipNav.Abbrev) : query.OrderByDescending(x => x.DipNav.Abbrev),
"Periodo" => sortAsc ? query.OrderBy(x => x.DtStart) : query.OrderByDescending(x => x.DtStart),
_ => query.OrderByDescending(x => x.DtStart) // Ordinamento di default obbligatorio per la paginazione
};
// 3. Paginazione finale
ListRecords = query
.Skip(numRecord * (currPage - 1))
.Take(numRecord)
.ToList();
}
} }
} }
+2 -3
View File
@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<!-- Questa soluzione gestisce le funzionalità amministrative del sistema GPW, inclusa la gestione di dipendenti, progetti, fasi, calendari aziendali, timbrature, malattie e richieste dei dipendenti. -->
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Version>4.1.2607.0211</Version> <Version>4.1.2605.0611</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -39,7 +39,6 @@
<PackageReference Include="NLog" Version="6.1.1" /> <PackageReference Include="NLog" Version="6.1.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="6.1.2" /> <PackageReference Include="NLog.Web.AspNetCore" Version="6.1.2" />
<PackageReference Include="Radzen.Blazor" Version="7.0.8" /> <PackageReference Include="Radzen.Blazor" Version="7.0.8" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.7.2" />
<PackageReference Include="System.Text.Json" Version="8.0.5" /> <PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup> </ItemGroup>
-37
View File
@@ -1,37 +0,0 @@
# GPW.CORE.ADM
Modulo amministrativo e di gestione master della suite GPW, deputato alla manutenzione delle anagrafiche, alla configurazione dei parametri aziendali e alla risoluzione di anomalie nei dati operativi.
## Descrizione Generale
`GPW.CORE.ADM` è lo strumento di controllo per il personale amministrativo e i responsabili HR. Mentre il modulo `Smart8` è orientato all'utente finale per l'imputazione dei dati, `ADM` è progettato per la gestione della struttura organizzativa (progetti, gruppi, dipendenti) e per la correzione di errori o incongruenze che emergono durante l'attività quotidiana.
Il modulo combina funzioni di **Master Data Management (MDM)** con strumenti di **Data Cleaning** e **Audit**, garantendo che la base dati sia coerente e pronta per la reportistica.
## Funzionalità Principali
### 1. Gestione Anagrafica (Master Data Management)
Il modulo permette il controllo completo del catalogo dati utilizzato in tutta la suite:
- **Dipendenti**: Gestione del database personale, controllo delle licenze software attive/disponibili e gestione delle autorizzazioni (es. reset chiavi di autenticazione).
- **Struttura Organizzativa**: Gestione dei **Gruppi** di lavoro e della gerarchia dei **Progetti** (inclusa la gestione delle **Fasi** di progetto).
- **Clienti e Orari**: Gestione del catalogo clienti e configurazione degli orari aziendali.
- **Giustificazioni**: Definizione dei codici giustificativi (es. FER, PERM, 104) utilizzati per le assenze.
### 2. Strumenti di Manutenzione e Correzione (Data Cleaning)
Per correggere errori di inserimento o riconfigurare la struttura, il modulo offre strumenti avanzati:
- **Spostamento Gerarchico**: Strumenti per spostare fasi di progetto tra diversi progetti o per riorganizzare la gerarchia delle sub-fasi (`SpostaFasiMan`).
- **Correzione Imputazioni**: Possibilità di spostare masse di ore/attività da una struttura (Cliente/Progetto/Fase) a un'altra per rimediare a errori di selezione durante la timbratura (`SpostaOreMan`).
- **Ricalcolo Anomalie**: Capacità di eseguire ricalcoli massivi per sincronizzare le timbrature con le attività e generare automaticamente giustificativi di copertura in caso di buchi di presenza (`ReviewTimbMan`).
### 3. Audit e Supervisione
- **Review Timbrature**: Monitoraggio delle anomalie (es. timbrature mancanti, incongruenze temporali) con possibilità di intervento diretto su timbrature e giustificativi.
- **Monitoraggio Licenze**: Controllo in tempo reale del numero di licenze attive e disponibili per garantire la continuità del servizio.
## Architettura Tecnica
- **Framework**: Sviluppato in **Blazor** (Server/WASM) con .NET 8.0.
- **Data Access**: Utilizza `GpwDataService` per tutte le operazioni CRUD e per le procedure di ricalcolo complesso lato server.
- **Comunicazione**: Integrazione con `UIMessageService` per la sincronizzazione degli stati tra i vari componenti dell'interfaccia.
- **Export**: Supporto per l'esportazione di dati in formati standard (CSV, TXT) ottimizzati per integrazioni con software terzi (es. Zucchetti).
## Note per l'Uso
- **Autorizzazioni**: Molte funzioni (es. eliminazione record, ricalcoli massivi, gestione licenze) sono protette da controlli di ruolo tramite `AppAuthService`.
- **Sicurezza**: Le operazioni critiche (eliminazione, spostamento masse) richiedono sempre una conferma esplicita tramite interfaccia JavaScript.
-1
View File
@@ -1,5 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Razor"> <Project Sdk="Microsoft.NET.Sdk.Razor">
<!-- Questa soluzione contiene componenti UI personalizzati per applicazioni Blazor, come ad esempio grafici circolari (CircleGauge). -->
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@@ -775,7 +775,6 @@ namespace GPW.CORE.Data.Controllers
dbRec.CodExt = upsRec.CodExt; dbRec.CodExt = upsRec.CodExt;
dbRec.DescrGruppo = upsRec.DescrGruppo; dbRec.DescrGruppo = upsRec.DescrGruppo;
dbRec.ExportEnab = upsRec.ExportEnab; dbRec.ExportEnab = upsRec.ExportEnab;
dbRec.IsActive = upsRec.IsActive;
dbRec.Gruppo = upsRec.Gruppo; dbRec.Gruppo = upsRec.Gruppo;
//set modificato //set modificato
dbCtx.Entry(dbRec).State = EntityState.Modified; dbCtx.Entry(dbRec).State = EntityState.Modified;
@@ -3638,33 +3637,6 @@ namespace GPW.CORE.Data.Controllers
return dbResult; return dbResult;
} }
public async Task<TimbratureModel?> TimbratureByUidAsync(string UID)
{
TimbratureModel? dbRec = null;
using (GPWContext dbCtx = new GPWContext(_configuration))
{
try
{
// UID = $"{IdxDipendente:000}_{DataOra:yyyyMMdd}_{DataOra:HHmmss}"
var parts = UID.Split('_');
if (parts.Length == 3)
{
int idxDip = int.Parse(parts[0]);
DateTime dataOra = DateTime.ParseExact(parts[1] + "_" + parts[2], "yyyyMMdd_HHmmss", null);
dbRec = await dbCtx
.DbSetTimbrature
.FirstOrDefaultAsync(x => x.IdxDipendente == idxDip && x.DataOra == dataOra);
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in TimbratureByUidAsync: {Environment.NewLine}{exc}");
}
}
return dbRec;
}
public bool TimbratureDelete(TimbratureModel currItem) public bool TimbratureDelete(TimbratureModel currItem)
{ {
bool answ = false; bool answ = false;
@@ -19,18 +19,11 @@ namespace GPW.CORE.Data.DbModels
public string Gruppo { get; set; } = null!; public string Gruppo { get; set; } = null!;
public string? DescrGruppo { get; set; } public string? DescrGruppo { get; set; }
public string? CodExt { get; set; } public string? CodExt { get; set; }
/// <summary> /// <summary>
/// determina se sia abilitato x export dati /// determina se sia abilitato x export dati
/// </summary> /// </summary>
public bool? ExportEnab { get; set; } public bool? ExportEnab { get; set; }
/// <summary>
/// Gestione stato attivo/disattivo
/// </summary>
[Column("isActive")]
public bool? IsActive { get; set; }
[NotMapped] [NotMapped]
public int NumDip public int NumDip
{ {
-3
View File
@@ -4,9 +4,6 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Compile Remove="Utils.cs" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.11.4" /> <PackageReference Include="Azure.Identity" Version="1.11.4" />
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" /> <PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
@@ -1,135 +0,0 @@
using GPW.CORE.Dto;
namespace GPW.CORE.Data.Mappings
{
public static class DailyDataMappingExtensions
{
public static DailyDataDto ToDto(this GPW.CORE.Data.DTO.DailyDataDTO model)
{
return new DailyDataDto
{
IdxDipendente = model.IdxDipendente,
DtRif = model.DtRif,
ListRA = model.ListRA?.Select(ra => new RegAttivitaDto
{
IdxRa = ra.IdxRa,
IdxDipendente = ra.IdxDipendente,
IdxFase = ra.IdxFase,
Inizio = ra.Inizio,
Fine = ra.Fine,
Descrizione = ra.Descrizione,
OreTot = ra.OreTot,
Importo = ra.Importo
}).ToList(),
ListTimbr = model.ListTimbr?.Select(t => new TimbraturaDto
{
DataOra = t.DataOra,
IdxDipendente = t.IdxDipendente,
Entrata = t.Entrata,
CodTipoTimb = t.CodTipoTimb,
Approv = t.Approv
}).ToList(),
TimbrExpl = model.TimbrExpl != null ? new TimbraturaExplDto
{
DataLav = model.TimbrExpl.DataLav,
IdxDipendente = model.TimbrExpl.IdxDipendente,
CognomeNome = model.TimbrExpl.CognomeNome,
Entrata1 = model.TimbrExpl.Entrata1,
Uscita1 = model.TimbrExpl.Uscita1,
Entrata2 = model.TimbrExpl.Entrata2,
Uscita2 = model.TimbrExpl.Uscita2,
Entrata3 = model.TimbrExpl.Entrata3,
Uscita3 = model.TimbrExpl.Uscita3,
Entrata4 = model.TimbrExpl.Entrata4,
Uscita4 = model.TimbrExpl.Uscita4,
HLav = model.TimbrExpl.HLav,
MinLav = model.TimbrExpl.MinLav,
MinOrd = model.TimbrExpl.MinOrd,
MinNonLav = model.TimbrExpl.MinNonLav,
MinStra = model.TimbrExpl.MinStra,
MinPerm = model.TimbrExpl.MinPerm,
MinFer = model.TimbrExpl.MinFer,
MinMal = model.TimbrExpl.MinMal,
MinFest = model.TimbrExpl.MinFest,
MinCassa = model.TimbrExpl.MinCassa,
Min104 = model.TimbrExpl.Min104,
MinMpp = model.TimbrExpl.MinMpp,
MinArcoPres = model.TimbrExpl.MinArcoPres,
IsOkTim = model.TimbrExpl.IsOkTim,
IsOkApp = model.TimbrExpl.IsOkApp,
Block = model.TimbrExpl.Block,
ChkFunCod = model.TimbrExpl.ChkFunCod,
ChkFunRes = model.TimbrExpl.ChkFunRes,
IsOk = model.TimbrExpl.IsOk,
IsOkLav = model.TimbrExpl.IsOkLav,
HGiust = model.TimbrExpl.HGiust,
TempRil = model.TimbrExpl.TempRil
} : null,
ListRilTemp = model.ListRilTemp?.Select(r => new RilievoTempDto
{
IdxDipendente = r.IdxDipendente,
DtRilievo = r.DtRilievo,
TempRil = r.TempRil
}).ToList(),
ListCheckC19 = model.ListCheckC19?.Select(c => new CheckVc19Dto
{
IdxCheckVc19 = c.IdxCheckVc19,
DtCheck = c.DtCheck,
IdxDipendente = c.IdxDipendente,
Cognome = c.Cognome,
Nome = c.Nome,
Dob = c.Dob,
Payload = c.Payload
}).ToList(),
ListFermateAzienda = model.ListFermateAzienda?.Select(f => new CalFesteFerieDto
{
Data = f.data,
CodGiust = f.codGiust,
Descrizione = f.descrizione
}).ToList(),
ListMalattie = model.ListMalattie?.Select(m => new RegMalattieDto
{
IdxRegMal = m.IdxRegMal,
IdxDipendente = m.IdxDipendente,
DtInizio = m.DtInizio,
NumGG = m.NumGG,
CodCert = m.CodCert,
Conf = m.Conf
}).ToList(),
ListFerieDip = model.ListFerieDip?.Select(r => new RegRichiesteDto
{
IdxRegRich = r.IdxRegRich,
IdxDipendente = r.IdxDipendente,
CodGiust = r.CodGiust,
DtStart = r.DtStart,
DtEnd = r.DtEnd,
Note = r.Note,
Conf = r.Conf
}).ToList(),
ListRichiesteDip = model.ListRichiesteDip?.Select(r => new RegRichiesteDto
{
IdxRegRich = r.IdxRegRich,
IdxDipendente = r.IdxDipendente,
CodGiust = r.CodGiust,
DtStart = r.DtStart,
DtEnd = r.DtEnd,
Note = r.Note,
Conf = r.Conf
}).ToList()
};
}
public static GPW.CORE.Data.DTO.DailyDataDTO ToModel(this DailyDataDto dto)
{
// Nota: Questa conversione è complessa perché il modello EF (DailyDataDTO)
// è una struttura aggregata che non esiste direttamente come singola tabella.
// In un'architettura reale, questa operazione verrebbe fatta tramite un servizio
// che ricostruisce l'oggetto aggregato partendo dai singoli modelli.
// Per ora restituiamo un oggetto vuoto o implementiamo solo la parte base
// se necessario, ma solitamente dal DTO non si torna al modello aggregato EF
// a meno di operazioni di salvataggio specifico.
throw new NotImplementedException("Mapping da DailyDataDto a DailyDataDTO (modello aggregato) non implementato. Questa conversione è solitamente gestita dal servizio tramite i singoli modelli.");
}
}
}
@@ -1,32 +0,0 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Dto;
namespace GPW.CORE.Data.Mappings
{
public static class TimbratureMappingExtensions
{
public static TimbraturaDto ToDto(this TimbratureModel model)
{
return new TimbraturaDto
{
DataOra = model.DataOra,
IdxDipendente = model.IdxDipendente,
Entrata = model.Entrata,
CodTipoTimb = model.CodTipoTimb,
Approv = model.Approv
};
}
public static TimbratureModel ToModel(this TimbraturaDto dto)
{
return new TimbratureModel
{
DataOra = dto.DataOra,
IdxDipendente = dto.IdxDipendente,
Entrata = dto.Entrata,
CodTipoTimb = dto.CodTipoTimb,
Approv = dto.Approv
};
}
}
}
-20
View File
@@ -1,20 +0,0 @@
# GPW.CORE.Data
Progetto responsabile dell'accesso ai dati e della gestione della persistenza per l'ecosistema GPW.
## Caratteristiche principali
- **Accesso al Database**: Utilizza Entity Framework Core con SQL Server.
- **Modelli di Dati**: Contiene la definizione di tutti i modelli del database (es. `DipendentiModel`, `RegAttivitaModel`, `AnagProgettiModel`).
- **Autenticazione e Autorizzazione**: Gestisce il contesto di autenticazione utente (`UserAuthContext`) e l'integrazione con ASP.NET Core Identity.
- **Servizi di Dati**: Fornisce servizi per la gestione delle licenze, invio email (via MailKit) e gestione dei messaggi.
- **DTO**: Include oggetti di trasferimento dati per le operazioni di input/output.
- **Integrazione**: Supporta l'uso di Redis per il caching e l'integrazione con Azure Identity.
## Dipendenze principali
- Microsoft.EntityFrameworkCore (SQL Server)
- Microsoft.AspNetCore.Identity.UI
- MailKit
- StackExchange.Redis
- Azure.Identity
- NLog
- RestSharp

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show More