Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 018733e918 | |||
| 18579f792a | |||
| f9e40a90de |
@@ -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).
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<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>
|
||||||
|
|||||||
@@ -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,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>
|
||||||
|
|||||||
@@ -3637,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;
|
||||||
|
|||||||
@@ -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
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
Reference in New Issue
Block a user