Ancora spostamento

This commit is contained in:
Samuele Locatelli
2022-01-27 11:42:46 +01:00
parent 77444731a4
commit 1ca60db13c
321 changed files with 3 additions and 124263 deletions
-82
View File
@@ -1,82 +0,0 @@
using GPW.CORE.Api.Data;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Text;
namespace GPW.CORE.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CheckProj : ControllerBase
{
/// <summary>
/// Dataservice x accesso DB
/// </summary>
protected ApiDataService dataService { get; set; }
private readonly ILogger<WeatherForecastController> _logger;
public CheckProj(ILogger<WeatherForecastController> logger, ApiDataService DataService)
{
_logger = logger;
dataService = DataService;
_logger.LogInformation("Avviata classe CheckProj");
}
[HttpGet("TryLock")]
public async Task<string> Get()
{
string answ = "ND";
StringBuilder sbLog = new StringBuilder();
StringBuilder sbActions = new StringBuilder();
// recupero progetti attivi...
var currProj = await dataService.AnagProjActiv();
sbLog.AppendLine("-----------------------");
sbLog.AppendLine($"Found {currProj.Count} Active Projects");
// leggo fasi attive
var currFasiAct = await dataService.AnagFasiActiv();
sbLog.AppendLine($"Found {currFasiAct.Count} Active Phases");
sbLog.AppendLine("-----------------------");
// ciclo elenco fasi ancestor di ognuno...
foreach (var itemProj in currProj)
{
// cerco le sue fasi PARENT...
var subsetFasi = currFasiAct
.Where(x => x.IdxProgetto == itemProj.IdxProgetto && x.IdxFaseAncest == 0)
.ToList();
sbLog.AppendLine("----------");
string projData = $"[{itemProj.IdxProgetto}] {itemProj.ClienteNav.RagSociale} - {itemProj.NomeProj} | Found {subsetFasi.Count} Phases";
sbLog.AppendLine(projData);
// ciclo x ogni fase Parent
foreach (var parentFase in subsetFasi)
{
// se ne trovo valuto le ore impiegate...
var statoFase = await dataService.CalcOreFase(parentFase.IdxFase);
// se ore usate > (ore budget x %) --> CHIUDO!
if (statoFase != null && statoFase.percUsed >= (decimal)statoFase.percOpen)
{
// x ora LOG... poi chiudo...
string currAction = $"!!! [{parentFase.IdxFase}] Budget exhausted for Phase {parentFase.NomeFase} {statoFase.totOre:N2}h used, {statoFase.percUsed:P1} vs {statoFase.percOpen:P1}";
sbLog.AppendLine(currAction);
sbActions.AppendLine("----------");
sbActions.AppendLine(projData);
sbActions.AppendLine(currAction);
}
}
}
// LOG esteso locale
_logger.LogInformation(sbLog.ToString());
// ritorno solo LOG azioni
answ = sbActions.ToString();
return answ;
}
}
}
@@ -1,11 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace GPW.CORE.Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CheckTimbrature : ControllerBase
{
}
}
@@ -1,30 +0,0 @@
using Microsoft.AspNetCore.Mvc;
namespace GPW.CORE.Api.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}
-252
View File
@@ -1,252 +0,0 @@
using GPW.CORE.Data.DbModels;
using Newtonsoft.Json;
using NLog;
using Microsoft.AspNetCore.Identity.UI.Services;
using StackExchange.Redis.Extensions.Core.Abstractions;
using System.Diagnostics;
namespace GPW.CORE.Api.Data
{
public class ApiDataService
{
#region Private Fields
private static IConfiguration _configuration;
private static ILogger<ApiDataService> _logger;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private readonly IEmailSender _emailSender;
//private readonly IDistributedCache distributedCache;
private readonly IRedisCacheClient _redisCacheClient;
/// <summary>
/// Elenco obj in cache
/// </summary>
private List<string> cachedDataList = new List<string>();
#endregion Private Fields
#region Protected Fields
protected const string rKeyProjAct = "Check:ProjAct";
protected const string rKeyFasiAct = "Check:FasiAct";
protected const string rKeyCalcOreFase = "Check:OreFasi";
/// <summary>
/// TTL da 1 min x cache Redis
/// </summary>
protected const int shortTTL = 60 * 1;
#endregion Protected Fields
#region Public Fields
/// <summary>
/// Classe Accesso metodi DB
/// </summary>
public static CORE.Data.Controllers.GPWController dbController;
#endregion Public Fields
#region Public Constructors
/// <summary>
/// Init classe
/// </summary>
/// <param name="configuration"></param>
/// <param name="logger"></param>
/// <param name="emailSender"></param>
/// <param name="redisCacheClient"></param>
public ApiDataService(IConfiguration configuration, ILogger<ApiDataService> logger, IEmailSender emailSender, IRedisCacheClient redisCacheClient)
//public ApiDataService(IConfiguration configuration, ILogger<ApiDataService> logger, IDistributedCache distributedCache, IEmailSender emailSender, IRedisCacheClient redisCacheClient)
{
_logger = logger;
_configuration = configuration;
_emailSender = emailSender;
_redisCacheClient = redisCacheClient;
// conf DB
string connStrDB = _configuration.GetConnectionString("GPW.DB");
if (string.IsNullOrEmpty(connStrDB))
{
_logger.LogError("ConnString empty!");
}
else
{
dbController = new CORE.Data.Controllers.GPWController(configuration);
_logger.LogInformation("DbController OK");
}
}
#endregion Public Constructors
#region Protected Methods
/// <summary>
/// Recupero chiave da redis
/// </summary>
/// <param name="rKey"></param>
/// <returns></returns>
protected async Task<string> getRSV(string rKey)
{
string answ = await _redisCacheClient.GetDbFromConfiguration().GetAsync<string>(rKey);
return answ;
}
/// <summary>
/// Salvataggio chiave in redis
/// </summary>
/// <param name="rKey"></param>
/// <param name="rVal"></param>
/// <param name="ttlSec"></param>
/// <returns></returns>
protected async Task<bool> setRSV(string rKey, string rVal, int ttlSec)
{
bool fatto = false;
await _redisCacheClient.GetDbFromConfiguration().AddAsync(rKey, rVal, DateTimeOffset.Now.AddSeconds(ttlSec));
fatto = true;
return fatto;
}
/// <summary>
/// Salvataggio chiave in redis
/// </summary>
/// <param name="rKey"></param>
/// <param name="rValInt"></param>
/// <param name="ttlSec"></param>
/// <returns></returns>
protected async Task<bool> setRSV(string rKey, int rValInt, int ttlSec)
{
bool fatto = false;
await _redisCacheClient.GetDbFromConfiguration().AddAsync<int>(rKey, rValInt, DateTimeOffset.Now.AddSeconds(ttlSec));
fatto = true;
return fatto;
}
/// <summary>
/// Registra in cache chiave se non fosse già in elenco
/// </summary>
/// <param name="newKey"></param>
protected void trackCache(string newKey)
{
if (!cachedDataList.Contains(newKey))
{
cachedDataList.Add(newKey);
}
}
#endregion Protected Methods
#region Public Methods
/// <summary>
/// Recupera l'elenco progetti (ATTIVI)
/// </summary>
/// <returns></returns>
public async Task<List<AnagProgettiModel>> AnagProjActiv()
{
List<AnagProgettiModel> dbResult = new List<AnagProgettiModel>();
string cacheKey = $"{rKeyProjAct}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject<List<AnagProgettiModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.AnagProjAll(true);
rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
await setRSV(cacheKey, rawData, shortTTL);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per AnagProjActiv: {ts.TotalMilliseconds} ms");
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco fasi (ATTIVE)
/// </summary>
/// <returns></returns>
public async Task<List<AnagFasiModel>> AnagFasiActiv()
{
List<AnagFasiModel> dbResult = new List<AnagFasiModel>();
string cacheKey = $"{rKeyFasiAct}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject<List<AnagFasiModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.AnagFasiAll(true);
rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
await setRSV(cacheKey, rawData, shortTTL);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per AnagFasiActiv: {ts.TotalMilliseconds} ms");
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Vista dati per FASE (tipicamente master...) con totalizzaizone ore budget/real e stato fase
/// </summary>
/// <param name="idxFase"></param>
/// <returns></returns>
public async Task<CalcOreFasiModel> CalcOreFase(int idxFase)
{
CalcOreFasiModel? dbResult = new CalcOreFasiModel();
string cacheKey = $"{rKeyCalcOreFase}:{idxFase}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject<CalcOreFasiModel>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.CalcOreFase(idxFase);
rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
await setRSV(cacheKey, rawData, shortTTL);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per CalcOreFase: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new CalcOreFasiModel();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// invalida tutta la cache in caso di update
/// </summary>
/// <returns></returns>
public async Task InvalidateAllCache()
{
foreach (var item in cachedDataList)
{
await _redisCacheClient.GetDbFromConfiguration().RemoveAsync(item);
}
cachedDataList = new List<string>();
}
#endregion Public Methods
}
}
-23
View File
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0" />
<PackageReference Include="StackExchange.Redis" Version="2.2.88" />
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="7.1.1" />
<PackageReference Include="StackExchange.Redis.Extensions.Newtonsoft" Version="7.1.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GPW.CORE.Data\GPW.CORE.Data.csproj" />
</ItemGroup>
</Project>
-63
View File
@@ -1,63 +0,0 @@
using GPW.CORE.Api.Data;
using GPW.CORE.Data;
using Microsoft.AspNetCore.Identity.UI.Services;
using StackExchange.Redis.Extensions.Core.Configuration;
using StackExchange.Redis.Extensions.Newtonsoft;
using System.Text.Json.Serialization;
var builder = WebApplication.CreateBuilder(args);
// configuration setup
ConfigurationManager configuration = builder.Configuration;
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// abilitazione x email management con MailKit
builder.Services.AddTransient<IEmailSender, MailKitEmailSender>();
builder.Services.Configure<MailKitEmailSenderOptions>(options =>
{
options.Host_Address = configuration["ExternalProviders:MailKit:SMTP:Address"];
options.Host_Port = Convert.ToInt32(configuration["ExternalProviders:MailKit:SMTP:Port"]);
options.Host_Username = configuration["ExternalProviders:MailKit:SMTP:Account"];
options.Host_Password = configuration["ExternalProviders:MailKit:SMTP:Password"];
options.Sender_EMail = configuration["ExternalProviders:MailKit:SMTP:SenderEmail"];
options.Sender_Name = configuration["ExternalProviders:MailKit:SMTP:SenderName"];
});
//services.AddStackExchangeRedisCache(options =>
//{
// options.Configuration = Configuration.GetConnectionString("Redis");
//});
builder.Services.AddControllers()
.AddJsonOptions(c => c.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve);
builder.Services.AddStackExchangeRedisExtensions<NewtonsoftSerializer>((options) =>
{
return configuration.GetSection("Redis").Get<RedisConfiguration>();
});
builder.Services.AddSingleton<ApiDataService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AllowUntrustedCertificate>true</AllowUntrustedCertificate>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>ef8d5a17-0d60-4ef0-9262-57afac574843</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://IIS01:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/GPW/Api</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
<UserName>jenkins</UserName>
<_SavePWD>True</_SavePWD>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TimeStampOfAssociatedLegacyPublishXmlFile />
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAk75miMJLMkCTEelQutKpbwAAAAACAAAAAAADZgAAwAAAABAAAAD64JiQMe/ZFQyoGM4R9sGPAAAAAASAAACgAAAAEAAAAM/q6+akRak8c3V0r3Mk+WoYAAAAsnZQbXwmQ0HddyBl23zqJ7UdrMoQ01oAFAAAAChHebeDEvGpMY3I9BCRoDeEkL/A</EncryptedPassword>
<History>True|2022-01-26T12:02:23.5485315Z;False|2022-01-26T13:01:54.1329262+01:00;True|2021-11-08T09:03:21.6459850+01:00;True|2021-11-08T09:03:16.0102315+01:00;True|2021-10-29T16:19:46.3691199+02:00;True|2021-10-29T16:19:41.0608384+02:00;True|2021-10-26T16:11:45.5614027+02:00;True|2021-10-26T16:11:39.3438864+02:00;True|2021-10-26T16:11:33.8810094+02:00;True|2021-10-21T17:34:31.5116686+02:00;True|2021-10-21T17:33:36.5842465+02:00;True|2021-10-21T17:33:31.1197556+02:00;True|2021-10-21T17:32:02.6752268+02:00;True|2021-10-21T17:31:01.4481659+02:00;True|2021-10-21T17:30:54.5129982+02:00;True|2021-10-21T17:30:26.4580323+02:00;True|2021-10-21T17:29:05.5768737+02:00;True|2021-10-21T17:29:00.6469015+02:00;True|2021-10-21T17:25:28.7571399+02:00;True|2021-10-21T17:25:24.8661113+02:00;True|2021-10-18T20:21:43.5592264+02:00;True|2021-10-18T20:15:20.3159574+02:00;True|2021-10-18T20:15:15.7014379+02:00;True|2021-10-18T20:10:02.7090938+02:00;True|2021-10-18T20:09:50.1979643+02:00;True|2021-10-18T20:09:20.6062870+02:00;True|2021-10-18T20:02:51.7298688+02:00;True|2021-10-18T20:02:46.6139358+02:00;True|2021-10-18T18:32:46.3582973+02:00;True|2021-10-18T18:32:40.4187829+02:00;True|2021-10-18T18:16:06.7339286+02:00;True|2021-10-18T18:15:55.3572290+02:00;True|2021-10-18T12:45:35.3623591+02:00;True|2021-10-18T12:45:31.6185568+02:00;True|2021-10-18T12:38:20.4056350+02:00;True|2021-10-18T12:14:33.7489648+02:00;True|2021-10-18T12:10:37.6779923+02:00;False|2021-10-18T12:09:50.4457635+02:00;False|2021-10-18T12:08:24.6162366+02:00;</History>
</PropertyGroup>
</Project>
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AllowUntrustedCertificate>true</AllowUntrustedCertificate>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>ef8d5a17-0d60-4ef0-9262-57afac574843</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://IIS02:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/GPW/Api</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
<UserName>jenkins</UserName>
<_SavePWD>True</_SavePWD>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TimeStampOfAssociatedLegacyPublishXmlFile />
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAk75miMJLMkCTEelQutKpbwAAAAACAAAAAAADZgAAwAAAABAAAAB43BVhUmznhAu3pUfV1IfOAAAAAASAAACgAAAAEAAAAEV8hgbujDFfsMjS77NS2oYYAAAAUHPGFaVWgRqQPDU4wk5KGABmVHKko4/9FAAAANtaROBOcPHljx4RnmQHj5aHdtYk</EncryptedPassword>
<History>True|2022-01-26T12:04:22.2336648Z;False|2022-01-26T13:04:06.0677616+01:00;True|2021-11-08T09:03:37.7855257+01:00;True|2021-11-08T09:03:34.8263479+01:00;True|2021-11-08T09:03:31.8889390+01:00;True|2021-10-29T16:19:33.6539408+02:00;True|2021-10-29T16:19:28.2082360+02:00;True|2021-10-26T16:12:11.7740950+02:00;True|2021-10-26T16:11:56.2014641+02:00;True|2021-10-26T16:11:22.2897842+02:00;False|2021-10-26T16:10:58.3733037+02:00;False|2021-10-26T16:10:29.4793991+02:00;True|2021-10-21T17:35:11.9761128+02:00;True|2021-10-18T20:22:00.9305399+02:00;True|2021-10-18T18:32:29.4558070+02:00;True|2021-10-18T18:32:22.8950294+02:00;True|2021-10-18T18:16:13.7563877+02:00;True|2021-10-18T18:15:48.5678387+02:00;True|2021-10-18T12:45:45.7228681+02:00;True|2021-10-18T12:14:22.3221605+02:00;True|2021-10-18T12:14:15.7373530+02:00;True|2021-10-18T12:10:43.8607301+02:00;</History>
</PropertyGroup>
</Project>
@@ -1,31 +0,0 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:39480",
"sslPort": 44359
}
},
"profiles": {
"GPW.CORE.Api": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7178;http://localhost:5178",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
-13
View File
@@ -1,13 +0,0 @@
namespace GPW.CORE.Api
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}
@@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
-43
View File
@@ -1,43 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"GPW.DB": "Server=SQLSTEAM;Database=GPW;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.API;",
"Redis": "localhost:6379,DefaultDatabase=15"
},
"ExternalProviders": {
"MailKit": {
"SMTP": {
"Address": "smtp.gmail.com",
"Port": "465",
"Account": "steamwarebot@gmail.com",
"Password": "drmfsls16",
"SenderEmail": "steamwarebot@gmail.com",
"SenderName": "Steamware Email BOT"
}
}
},
"MailDest": {
"Admin": "samuele@steamware.net",
"ProcOp": "ceo@steamware.net"
},
"Redis": {
"Password": "",
"AllowAdmin": false,
"Ssl": false,
"ConnectTimeout": 6000,
"ConnectRetry": 2,
"Hosts": [
{
"Host": "localhost",
"Port": "6379"
}
],
"Database": 15
}
}
-640
View File
@@ -1,640 +0,0 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using NLog;
namespace GPW.CORE.Data.Controllers
{
public class GPWController : IDisposable
{
#region Private Fields
private static IConfiguration _configuration = null!;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Public Constructors
public GPWController(IConfiguration configuration)
{
_configuration = configuration;
}
#endregion Public Constructors
#region Public Methods
/// <summary>
/// Recupera l'elenco Clienti (tutti)
/// </summary>
/// <returns></returns>
public List<AnagClientiModel> AnagClientiAll()
{
// init dati necessari
List<AnagClientiModel> dbResult = new List<AnagClientiModel>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero intero set...
dbResult = localDbCtx
.DbSetAnagClienti
.OrderBy(x => x.RagSociale)
.ToList();
}
catch (Exception exc)
{
Log.Error($"Errore in AnagClientiAll:{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Recupera l'elenco delle fasi (tutte)
/// </summary>
/// <returns></returns>
public List<AnagFasiModel> AnagFasiAll(bool onlyActive)
{
// 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...
dbResult = localDbCtx
.DbSetAnagFasi
.Where(x => ((bool)x.Attivo == true && onlyActive == true) || !onlyActive)
.ToList();
}
catch (Exception exc)
{
Log.Error($"Errore in AnagFasiAll:{Environment.NewLine}{exc}");
}
}
return dbResult;
}
public List<AnagGruppiModel> AnagGruppiAll()
{
// init dati necessari
List<AnagGruppiModel> dbResult = new List<AnagGruppiModel>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero intero set...
dbResult = localDbCtx
.DbSetAnagGruppi
.ToList();
}
catch (Exception exc)
{
Log.Error($"Errore in AnagGruppiAll:{Environment.NewLine}{exc}");
}
}
return dbResult;
}
public List<AnagProgettiModel> AnagProjAll(bool onlyActive)
{
// init dati necessari
List<AnagProgettiModel> dbResult = new List<AnagProgettiModel>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
// recupero intero set....
dbResult = localDbCtx
.DbSetAnagProgetti
.Where(x => ((bool)x.Attivo == true && onlyActive == true) || !onlyActive)
.Include(c => c.ClienteNav)
.OrderBy(x => x.NomeProj)
.ToList();
}
catch (Exception exc)
{
Log.Error($"Errore in AnagProjAll:{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Vista dati per progetto con totalizzaizone ore budget/real
/// </summary>
/// <param name="idxProj"></param>
/// <returns></returns>
public CalcOreProgettiModel CalcOreProj(int idxProj)
{
CalcOreProgettiModel dbResult = new CalcOreProgettiModel();
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
var idxProgetto = new SqlParameter("@idxProgetto", idxProj);
var rawResult = localDbCtx
.DbSetCalcOreProj
.FromSqlRaw("EXEC stp_AP_getByIdxPrj @idxProgetto", idxProgetto)
.ToList();
if (rawResult != null && rawResult.Count > 0)
{
dbResult = rawResult[0];
}
}
return dbResult;
}
/// <summary>
/// Vista dati per FASE con totalizzaizone ore budget/real
/// </summary>
/// <param name="idxFase"></param>
/// <returns></returns>
public CalcOreFasiModel CalcOreFase(int idxFase)
{
CalcOreFasiModel dbResult = new CalcOreFasiModel();
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
var parIdxFase = new SqlParameter("@idxFase", idxFase);
var rawResult = localDbCtx
.DbSetCalcOreFasi
.FromSqlRaw("EXEC stp_AF_getByIdxFase_Child @idxFase", parIdxFase)
.ToList();
if (rawResult != null && rawResult.Count > 0)
{
dbResult = rawResult[0];
}
}
return dbResult;
}
/// <summary>
/// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public List<CheckVc19Model> CheckVC19List(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
// init dati necessari
List<CheckVc19Model> dbResult = new List<CheckVc19Model>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
dbResult = localDbCtx
.DbSetCheckVc19
.Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtCheck && x.DtCheck <= dtFine)
.ToList();
}
return dbResult;
}
/// <summary>
/// Recupera l'elenco dei dettagli giornalieri attività di un dipendente, dato periodo riferimento
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public List<DailyDataDTO> DailyDetails(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
// init dati necessari
List<DailyDataDTO> dbResult = new List<DailyDataDTO>();
List<TimbratureExplModel> rawTimbExp = new List<TimbratureExplModel>();
List<TimbratureModel> rawTimbr = new List<TimbratureModel>();
List<RegAttivitaModel> rawRegAtt = new List<RegAttivitaModel>();
List<RilievoTempModel> rawRilTemp = new List<RilievoTempModel>();
List<CheckVc19Model> rawCheckC19 = new List<CheckVc19Model>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
// recupero intero set dati timbrature e attività....
rawTimbExp = localDbCtx
.DbSetTimbratureExpl
.Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DataLav && x.DataLav <= dtFine)
.ToList();
rawTimbr = localDbCtx
.DbSetTimbrature
.Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DataOra && x.DataOra <= dtFine)
.ToList();
rawRegAtt = localDbCtx
.DbSetRegAttivita
.Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.Inizio && x.Inizio <= dtFine)
.Include(a => a.FasiNav).ThenInclude(p => p.ProgettoNav).ThenInclude(c => c.ClienteNav)
.ToList();
rawRilTemp = localDbCtx
.DbSetRilievoTemp
.Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtRilievo && x.DtRilievo <= dtFine)
.ToList();
rawCheckC19 = localDbCtx
.DbSetCheckVc19
.Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtCheck && x.DtCheck <= dtFine)
.ToList();
// calcolo intervallo date...
int numDays = dtFine.Subtract(dtInizio).Days;
// x ogni giorno scompongo il set di info...
for (int i = 0; i <= numDays; i++)
{
DateTime thisDay = dtInizio.AddDays(i);
DailyDataDTO currDayDto = new DailyDataDTO()
{
IdxDipendente = idxDipendente,
DtRif = thisDay,
ListRA = rawRegAtt
.Where(x => thisDay <= x.Inizio && x.Inizio <= thisDay.AddDays(1))
.ToList(),
ListTimbr = rawTimbr
.Where(x => thisDay <= x.DataOra && x.DataOra <= thisDay.AddDays(1))
.ToList(),
TimbrExpl = rawTimbExp
.Where(x => thisDay == x.DataLav)
.FirstOrDefault(),
ListRilTemp = rawRilTemp
.Where(x => thisDay <= x.DtRilievo && x.DtRilievo <= thisDay.AddDays(1))
.ToList(),
ListCheckC19 = rawCheckC19
.Where(x => thisDay <= x.DtCheck && x.DtCheck <= thisDay.AddDays(1))
.ToList()
};
dbResult.Add(currDayDto);
}
}
return dbResult;
}
public bool DbForceMigrate()
{
bool answ = false;
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
localDbCtx.DbForceMigrate();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione in DbForceMigrate{Environment.NewLine}{exc}");
}
}
return answ;
}
public List<DipendentiModel> DipendentiGetAll()
{
List<DipendentiModel> dbResult = new List<DipendentiModel>();
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
dbResult = localDbCtx
.DbSetDipendenti
.ToList();
}
return dbResult;
}
public List<AnagKeyValueModel> AnagKeyValGetAll()
{
List<AnagKeyValueModel> dbResult = new List<AnagKeyValueModel>();
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
dbResult = localDbCtx
.DbSetAnagKeyValue
.ToList();
}
return dbResult;
}
public void Dispose()
{
Log.Info("Dispose di GPWController");
}
/// <summary>
/// Elenco pareto progetti ordinati da filtro
/// </summary>
/// <param name="idxDip"></param>
/// <param name="dataStart"></param>
/// <param name="dataEnd"></param>
/// <param name="maxResult"></param>
/// <returns></returns>
public List<ParetoRegAttModel> ParetoRegAtt(int idxDip, DateTime dataStart, DateTime dataEnd, int maxResult)
{
List<ParetoRegAttModel> dbResult = new List<ParetoRegAttModel>();
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
var idxDipendente = new SqlParameter("@idxDipendente", idxDip);
var inizio = new SqlParameter("@inizio", dataStart);
var fine = new SqlParameter("@fine", dataEnd);
var maxRes = new SqlParameter("@maxRes", maxResult);
dbResult = localDbCtx
.DbSetParetoRegAtt
.FromSqlRaw("EXEC stp_freqProjByDipPeriodo @idxDipendente, @inizio,@fine,@maxRes", idxDipendente, inizio, fine, maxRes)
.ToList();
}
return dbResult;
}
public bool RegAttDelete(RegAttivitaModel currItem)
{
bool answ = false;
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
localDbCtx.Remove(currItem);
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione in RegAttUpdate{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Recupera ultima attività dipendente
/// </summary>
/// <param name="IdxDipendente"></param>
/// <param name="onlyActive">cerca ultima solo tra attive (=true) o tutte (=false)</param>
/// <returns></returns>
public RegAttivitaModel RegAttLastByDip(int IdxDipendente, bool onlyActive)
{
RegAttivitaModel dbResult = new RegAttivitaModel();
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
dbResult = localDbCtx
.DbSetRegAttivita
.Where(x => x.FasiNav.Attivo || !onlyActive)
.OrderByDescending(x => x.Inizio)
.FirstOrDefault(x => x.IdxDipendente == IdxDipendente);
}
catch (Exception exc)
{
Log.Error($"Eccezione in RegAttLastByDip{Environment.NewLine}{exc}");
}
if (dbResult == null)
{
dbResult = new RegAttivitaModel();
}
}
return dbResult;
}
public bool RegAttUpdate(RegAttivitaModel currItem)
{
bool answ = false;
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
var currRec = localDbCtx
.DbSetRegAttivita
.FirstOrDefault(x => x.IdxRa == currItem.IdxRa);
if (currRec != null)
{
currRec.IdxDipendente = currItem.IdxDipendente;
currRec.IdxFase = currItem.IdxFase;
currRec.Inizio = currItem.Inizio;
currRec.Fine = currItem.Fine;
currRec.Descrizione = currItem.Descrizione;
localDbCtx
.DbSetRegAttivita
.Update(currRec);
}
// altrimenti aggiungo
else
{
localDbCtx
.DbSetRegAttivita
.Update(currItem);
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione in RegAttUpdate{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public List<RilievoTempModel> RilTempList(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
// init dati necessari
List<RilievoTempModel> dbResult = new List<RilievoTempModel>();
// cerco su DB recuperando set di dati....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
dbResult = localDbCtx
.DbSetRilievoTemp
.Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtRilievo && x.DtRilievo <= dtFine)
.ToList();
}
return dbResult;
}
public bool RilTempUpdate(RilievoTempModel currItem)
{
bool answ = false;
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
var currRec = localDbCtx
.DbSetRilievoTemp
.FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente && x.DtRilievo == currItem.DtRilievo);
if (currRec != null)
{
// aggiorno solo entrata/uscita
currRec.TempRil = currItem.TempRil;
localDbCtx
.DbSetRilievoTemp
.Update(currRec);
}
// altrimenti aggiungo
else
{
localDbCtx
.DbSetRilievoTemp
.Add(currItem);
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione in RilTempUpdate{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Annulla modifiche su una specifica entity (cancel update)
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool rollBackEntity(object item)
{
bool answ = false;
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
if (localDbCtx.Entry(item).State == EntityState.Deleted || localDbCtx.Entry(item).State == EntityState.Modified)
{
localDbCtx.Entry(item).Reload();
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in rollBackEntity{Environment.NewLine}{exc}");
}
}
return answ;
}
public bool TimbratureDelete(TimbratureModel currItem)
{
bool answ = false;
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
localDbCtx.Remove(currItem);
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione in TimbratureDelete{Environment.NewLine}{exc}");
}
}
return answ;
}
public bool TimbratureUpdate(TimbratureModel currItem)
{
bool answ = false;
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
try
{
var currRec = localDbCtx
.DbSetTimbrature
.FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente && x.DataOra == currItem.DataOra);
if (currRec != null)
{
// aggiorno solo entrata/uscita
currRec.Entrata = currItem.Entrata;
localDbCtx
.DbSetTimbrature
.Update(currRec);
}
// altrimenti aggiungo
else
{
localDbCtx
.DbSetTimbrature
.Add(currItem);
}
localDbCtx.SaveChanges();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione in TimbratureUpdate{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Recupera overview di un periodo settimanale x dipendente, data riferimento, numero settimane precedenti
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtRif">Data di riferimento (ultima/corrente)</param>
/// <param name="numWeek">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public List<WeekStatDTO> WeekOverview(int idxDipendente, DateTime dtRif, int numWeek)
{
// init dati necessari
List<WeekStatDTO> dbResult = new List<WeekStatDTO>();
List<WeekData> weekList = new List<WeekData>();
// aggiungo sett corrente + quelle richeiste...
for (int i = numWeek; i >= 0; i--)
{
var currWeek = new WeekData(dtRif.AddDays(-i * 7));
weekList.Add(currWeek);
}
// cerco su DB settimana x settimana....
using (GPWContext localDbCtx = new GPWContext(_configuration))
{
foreach (var item in weekList)
{
var totOreTim = localDbCtx
.DbSetTimbratureExpl
.Where(x => x.IdxDipendente == idxDipendente && x.DataLav >= item.inizio && x.DataLav <= item.fine)
.Sum(x => (double)x.HLav);
var totMinLav = localDbCtx
.DbSetRegAttivitaExpl
.Where(x => x.IdxDipendente == idxDipendente && x.DataLav >= item.inizio && x.DataLav <= item.fine)
.Sum(x => (int)x.MinRegAtt);
// aggiungo alla lista...
var weekData = new WeekStatDTO()
{
IdxDipendente = idxDipendente,
Anno = item.anno,
WeekNumber = item.weekNumber,
Inizio = item.inizio,
Fine = item.fine,
SumOreLav = totOreTim,
SumOreComm = (double)totMinLav / 60,
};
dbResult.Add(weekData);
}
}
return dbResult;
}
#endregion Public Methods
}
}
-71
View File
@@ -1,71 +0,0 @@
using GPW.CORE.Data.DbModels;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data.DTO
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
public class DailyDataDTO
{
public int IdxDipendente { get; set; } = 0;
public DateTime DtRif { get; set; } = DateTime.Today;
public List<RegAttivitaModel>? ListRA { get; set; }
public List<TimbratureModel>? ListTimbr { get; set; }
public TimbratureExplModel? TimbrExpl { get; set; }
public List<RilievoTempModel>? ListRilTemp { get; set; }
public List<CheckVc19Model>? ListCheckC19 { get; set; }
public DateTime DtInizio
{
get
{
DateTime answ = DtRif;
if (ListTimbr != null && ListTimbr.Count > 0)
{
answ = ListTimbr
.OrderBy(x => x.DataOra)
.Take(1)
.Select(x => x.DataOra)
.FirstOrDefault();
}
return answ;
}
}
public double OreLav
{
get
{
double answ = 0;
if (ListRA != null && ListRA.Count > 0)
{
answ = ListRA
.Sum(x => x.OreTot == null ? 0 : (double)x.OreTot);
}
return answ;
}
}
public double OreComm
{
get
{
double answ = 0;
if (TimbrExpl != null && TimbrExpl.HLav != null)
{
answ = (double)TimbrExpl.HLav;
}
return answ;
}
}
}
}
-40
View File
@@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data.DTO
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
public class PeriodoDTO
{
public DateTime Inizio { get; set; }
public DateTime Fine { get; set; }
public TipoPeriodo Tipo { get; set; } = TipoPeriodo.ND;
public bool IsClosed { get; set; } = false;
public decimal? OreTot { get; set; }
public TimeSpan Durata
{
get
{
TimeSpan valore = TimeSpan.FromHours(0);
if (OreTot != null)
{
try
{
valore = TimeSpan.FromHours((double)OreTot);
}
catch (Exception exc)
{ }
}
return valore;
}
}
}
}
-23
View File
@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data.DTO
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
public class WeekStatDTO
{
public int Anno { get; set; } = DateTime.Today.Year;
public int WeekNumber { get; set; } = 1;
public DateTime Inizio { get; set; } = DateTime.Today;
public DateTime Fine { get; set; } = DateTime.Today.AddDays(1);
public int IdxDipendente { get; set; } = 0;
public double SumOreLav { get; set; } = 0;
public double SumOreComm { get; set; } = 0;
}
}
@@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("AnagClienti")]
public partial class AnagClientiModel
{
public AnagClientiModel()
{
ProgettiNav = new HashSet<AnagProgettiModel>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxCliente { get; set; }
public string? RagSociale { get; set; } = "";
public string? Indirizzo { get; set; } = "";
public string? Cap { get; set; } = "";
public string? Citta { get; set; } = "";
public string? Prov { get; set; } = "";
public string? Tel { get; set; } = "";
public string? Url { get; set; } = "";
public string? Email { get; set; } = "";
public string? PIva { get; set; } = "";
public string? Cf { get; set; } = "";
public string? LogoUrl { get; set; } = "";
public string? Nota { get; set; } = "";
public int OldIdx { get; set; } = 0;
public bool Attivo { get; set; } = false;
/// <summary>
/// codice esterno
/// </summary>
public string? CodExt { get; set; } = "";
public virtual ICollection<AnagProgettiModel> ProgettiNav { get; set; }
}
}
-53
View File
@@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("AnagFasi")]
public partial class AnagFasiModel
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
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; } = "";
/// <summary>
/// Budget del progetto (in ore)
/// </summary>
public decimal BudgetTime { get; set; } = 0;
public decimal BudgetMoney { get; set; } = 0;
[ForeignKey("IdxProgetto")]
public virtual AnagProgettiModel? ProgettoNav { get; set; }
}
}
-21
View File
@@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("AnagGruppi")]
public partial class AnagGruppiModel
{
public string Gruppo { get; set; } = null!;
public string? DescrGruppo { get; set; }
public string? CodExt { get; set; }
/// <summary>
/// determina se sia abilitato x export dati
/// </summary>
public bool? ExportEnab { get; set; }
}
}
@@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("AnagKeyValue")]
public partial class AnagKeyValueModel
{
public string NomeVar { get; set; } = null!;
public int? ValInt { get; set; }
public double? ValFloat { get; set; }
public string? ValString { get; set; }
public string? Descrizione { get; set; }
}
}
@@ -1,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("AnagProgetti")]
public partial class AnagProgettiModel
{
public AnagProgettiModel()
{
FasiNav = new HashSet<AnagFasiModel>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxProgetto { get; set; }
public int IdxCliente { get; set; }
public string NomeProj { get; set; } = "";
public string DescrProj { get; set; } = "";
public int OldIdx { get; set; }
public bool? Attivo { get; set; }
/// <summary>
/// codice esterno
/// </summary>
public string CodExt { get; set; } = "";
public DateTime Avvio { get; set; }
public DateTime Chiusura { get; set; }
public string Gruppo { get; set; } = "";
public bool Starred { get; set; }
[ForeignKey("IdxCliente")]
public virtual AnagClientiModel ClienteNav { get; set; } = null!;
[ForeignKey("Gruppo")]
public virtual AnagGruppiModel GruppiNav { get; set; } = null!;
public virtual ICollection<AnagFasiModel> FasiNav { get; set; }
}
}
@@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
public partial class CalcOreFasiModel
{
[Key]
public int IdxFase { get; set; }
public int IdxProgetto { get; set; }
public string CodFase { get; set; } = "";
public int IdxFaseAncest { get; set; }
public string NomeFase { get; set; } = "";
public string DescrizioneFase { get; set; } = "";
public bool? EnableTime { get; set; }
public bool? EnableMoney { get; set; }
public bool? Attivo { get; set; }
public decimal budgetTime { get; set; } = 0;
public decimal budgetMoney { get; set; } = 0;
public double percOpen { get; set; } = 1;
public string CodClasse { get; set; } = "";
public string CodExt { get; set; } = "";
public decimal totOre { get; set; } = 0;
[NotMapped]
public decimal percUsed
{
get
{
decimal answ = 0;
decimal denom = budgetTime > 0 ? budgetTime : 1;
answ = totOre / denom;
return answ;
}
}
[NotMapped]
public decimal timeRem
{
get
{
return budgetTime - totOre;
}
}
}
}
@@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
public partial class CalcOreProgettiModel
{
[Key]
public int IdxProgetto { get; set; }
public int IdxCliente { get; set; }
public string NomeProj { get; set; } = "";
public string DescrProj { get; set; } = "";
public int OldIdx { get; set; }
public bool? Attivo { get; set; }
/// <summary>
/// codice esterno
/// </summary>
public string CodExt { get; set; } = "";
public DateTime Avvio { get; set; }
public DateTime Chiusura { get; set; }
public string Gruppo { get; set; } = "";
public string RagSociale { get; set; } = "";
public decimal budgetTime { get; set; } = 0;
public decimal budgetMoney { get; set; } = 0;
public decimal totOre { get; set; } = 0;
public decimal totOrePrevMont { get; set; } = 0;
public decimal totOreLast30 { get; set; } = 0;
[NotMapped]
public decimal percUsed
{
get
{
decimal answ = 0;
decimal denom = budgetTime > 0 ? budgetTime : 1;
answ = totOre / denom;
return answ;
}
}
[NotMapped]
public decimal timeRem
{
get
{
return budgetTime - totOre;
}
}
}
}
-29
View File
@@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("CheckVc19")]
public partial class CheckVc19Model
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxCheckVc19 { get; set; }
public DateTime DtCheck { get; set; } = DateTime.Now;
public int IdxDipendente { get; set; }
public string Cognome { get; set; } = null!;
public string Nome { get; set; } = null!;
public DateTime Dob { get; set; }
public string Payload { get; set; } = null!;
/// <summary>
/// Navigation property to Dipendente
/// </summary>
[ForeignKey("IdxDipendente")]
public virtual DipendentiModel? DipNav { get; set; }
}
}
-59
View File
@@ -1,59 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("Dipendenti")]
public partial class DipendentiModel
{
public DipendentiModel()
{
RegAttivitaNav = new HashSet<RegAttivitaModel>();
RilievoTempNav = new HashSet<RilievoTempModel>();
TimbratureNav = new HashSet<TimbratureModel>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxDipendente { get; set; }
public string? Matricola { get; set; }
public string Cf { get; set; } = null!;
public string? Cognome { get; set; }
public string? Nome { get; set; }
public DateTime? DataNascita { get; set; }
public string? LuogoNascita { get; set; }
public string? ProvNascita { get; set; }
public string? NazNascita { get; set; }
public string CodHw { get; set; } = null!;
public string? CodOrario { get; set; }
public bool? MailLastOp { get; set; }
public bool? MailDay { get; set; }
public bool? MailWeek { get; set; }
public bool? MailMonth { get; set; }
public string Email { get; set; } = null!;
public string AuthKey { get; set; } = null!;
/// <summary>
/// numero di impieghi della authKey
/// </summary>
public int? NumAuth { get; set; }
public string? WolMac { get; set; }
public string Dominio { get; set; } = null!;
public string Utente { get; set; } = null!;
/// <summary>
/// nome/codice dipendente per sistema esterno da importare
/// </summary>
public string CodDipendenteExt { get; set; } = null!;
public string? Gruppo { get; set; }
public DateTime? DataAssunzione { get; set; }
public DateTime? DataCessazione { get; set; }
public bool? Attivo { get; set; }
public virtual ICollection<RegAttivitaModel> RegAttivitaNav { get; set; }
public virtual ICollection<RilievoTempModel> RilievoTempNav { get; set; }
public virtual ICollection<TimbratureModel> TimbratureNav { get; set; }
}
}
@@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
public partial class ParetoRegAttModel
{
[Key]
public long RowNum { get; set; } = 0;
public string nomeComm { get; set; } = "";
public int idxFaseComm { get; set; } = 0;
public int idxFase { get; set; } = 0;
public string nomeProj { get; set; } = "";
public string nomeFase { get; set; } = "";
public decimal freq { get; set; } = 0;
public decimal qty { get; set; } = 0;
public int tot{ get; set; } = 0;
}
}
@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("RegAttivitaExpl")]
public partial class RegAttivitaExplModel
{
public DateTime DataLav { get; set; }
public int IdxDipendente { get; set; }
public string? CognomeNome { get; set; }
/// <summary>
/// totale dei minuti di attività registrate per la giornata (da trigger suRegAttivita)
/// </summary>
public int? MinRegAtt { get; set; }
public string? DescrProj { get; set; }
}
}
@@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("RegAttivita")]
public partial class RegAttivitaModel
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxRa { get; set; }
public int IdxDipendente { get; set; } = 0;
public int IdxFase { get; set; }
public DateTime Inizio { get; set; }
public DateTime Fine { get; set; }
public string? Descrizione { get; set; }
/// <summary>
/// Ore Attività - prima era ([dbo].[f_hourInterval]([inizio],[fine])) poi sostituita per performance
/// </summary>
public decimal? OreTot { get; set; }
[NotMapped]
public TimeSpan Durata
{
get
{
TimeSpan valore = TimeSpan.FromHours(0);
if (OreTot != null)
{
try
{
valore = TimeSpan.FromHours((double)OreTot);
}
catch (Exception exc)
{ }
}
return valore;
}
}
public decimal? Importo { get; set; }
[ForeignKey("IdxDipendente")]
public virtual DipendentiModel? DipNav { get; set; }
[ForeignKey("IdxFase")]
public virtual AnagFasiModel? FasiNav { get; set; }
}
}
@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("RilievoTemp")]
public partial class RilievoTempModel
{
public int IdxDipendente { get; set; }
public DateTime DtRilievo { get; set; }
public decimal TempRil { get; set; }
/// <summary>
/// Navigation property to Dipendente
/// </summary>
[ForeignKey("IdxDipendente")]
public virtual DipendentiModel DipNav { get; set; } = null!;
}
}
@@ -1,80 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("TimbratureExpl")]
public partial class TimbratureExplModel
{
public DateTime DataLav { get; set; }
public int IdxDipendente { get; set; }
public string? CognomeNome { get; set; }
public DateTime? Entrata1 { get; set; }
public DateTime? Uscita1 { get; set; }
public DateTime? Entrata2 { get; set; }
public DateTime? Uscita2 { get; set; }
public DateTime? Entrata3 { get; set; }
public DateTime? Uscita3 { get; set; }
public DateTime? Entrata4 { get; set; }
public DateTime? Uscita4 { get; set; }
public double? HLav { get; set; }
public int? MinLav { get; set; }
public int? MinOrd { get; set; }
/// <summary>
/// minuti non lavorati (ovvero se fatti meno di ordinari e senza giustificativi)
/// </summary>
public int? MinNonLav { get; set; }
public int? MinStra { get; set; }
public int? MinPerm { get; set; }
public int? MinFer { get; set; }
public int? MinMal { get; set; }
public int? MinFest { get; set; }
/// <summary>
/// Minuti di Cassa Integrazione
/// </summary>
public int? MinCassa { get; set; }
/// <summary>
/// Minuti Permessi per 104
/// </summary>
public int? Min104 { get; set; }
public int? MinMpp { get; set; }
/// <summary>
/// DATEDIFF(n, ISNULL(entrata_1,GETDATE()), ISNULL(ISNULL(uscita_4,ISNULL(uscita_3,ISNULL(uscita_2,ISNULL(uscita_1,entrata_1)))),GETDATE()))
/// </summary>
public int? MinArcoPres { get; set; }
public bool? IsOkTim { get; set; }
/// <summary>
/// dato sintetico x indicare se TUTTE le timbrature componenti siano approvate
/// </summary>
public bool? IsOkApp { get; set; }
/// <summary>
/// determina se il record sia &quot;bloccato&quot; (archiviazione e blocco mesi precedenti...)
/// </summary>
public bool? Block { get; set; }
/// <summary>
/// eventuale diagnostica da check function sulla riga indicata (codice)
/// </summary>
public string? ChkFunCod { get; set; }
/// <summary>
/// eventuale diagnostica da check function sulla riga indicata (spiegazione)
/// </summary>
public string? ChkFunRes { get; set; }
public int? IsOk { get; set; }
/// <summary>
/// determina se la giornata sia ok (oreLav + giustificativi &gt;= oreOrd)
/// </summary>
public int IsOkLav { get; set; }
/// <summary>
/// totale ore giustificate
/// </summary>
public double? HGiust { get; set; }
/// <summary>
/// Temperatura rilevata
/// </summary>
public decimal TempRil { get; set; }
}
}
-31
View File
@@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace GPW.CORE.Data.DbModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
[Table("Timbrature")]
public partial class TimbratureModel
{
public DateTime DataOra { get; set; }
public int IdxDipendente { get; set; }
public bool? Entrata { get; set; }
public string? Ipv4 { get; set; }
public string? CodTipoTimb { get; set; }
/// <summary>
/// Approvazioen timbratura (default true...)
/// </summary>
public bool? Approv { get; set; }
/// <summary>
/// Navigation property to Dipendente
/// </summary>
[ForeignKey("IdxDipendente")]
public virtual DipendentiModel DipNav { get; set; } = null!;
}
}
-15
View File
@@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data
{
public enum TipoPeriodo
{
ND = 0,
Lavoro = 1
}
}
-22
View File
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MailKit" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NLog" Version="4.7.13" />
</ItemGroup>
</Project>
-743
View File
@@ -1,743 +0,0 @@
using System;
using System.Collections.Generic;
using GPW.CORE.Data.DbModels;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Configuration;
using NLog;
namespace GPW.CORE.Data
{
public partial class GPWContext : DbContext
{
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private IConfiguration _configuration = null!;
public GPWContext()
{
}
public GPWContext(IConfiguration configuration)
{
_configuration = configuration;
}
public GPWContext(DbContextOptions<GPWContext> options) : base(options)
{
try
{
// se non ci fosse... crea o migra!
Database.Migrate();
}
catch (Exception exc)
{
Log.Error(exc, "Exception during context initialization 02");
}
}
public virtual DbSet<CheckVc19Model> DbSetCheckVc19 { get; set; } = null!;
public virtual DbSet<DipendentiModel> DbSetDipendenti { get; set; } = null!;
public virtual DbSet<RegAttivitaModel> DbSetRegAttivita { get; set; } = null!;
public virtual DbSet<RegAttivitaExplModel> DbSetRegAttivitaExpl { get; set; } = null!;
public virtual DbSet<RilievoTempModel> DbSetRilievoTemp { get; set; } = null!;
public virtual DbSet<TimbratureModel> DbSetTimbrature { get; set; } = null!;
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<AnagProgettiModel> DbSetAnagProgetti { get; set; } = null!;
public virtual DbSet<AnagGruppiModel> DbSetAnagGruppi { get; set; } = null!;
public virtual DbSet<ParetoRegAttModel> DbSetParetoRegAtt { get; set; } = null!;
public virtual DbSet<CalcOreProgettiModel> DbSetCalcOreProj { get; set; } = null!;
public virtual DbSet<CalcOreFasiModel> DbSetCalcOreFasi { get; set; } = null!;
public virtual DbSet<AnagKeyValueModel> DbSetAnagKeyValue { get; set; } = null!;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
string connString = _configuration.GetConnectionString("GPW.DB");
if (!string.IsNullOrEmpty(connString))
{
optionsBuilder.UseSqlServer(connString);
}
else
{
optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=Sauder_NKC;Trusted_Connection=True;");
optionsBuilder.UseSqlServer("Server=SQLSTEAM;Database=GPW;Trusted_Connection=True;");
}
}
}
public void DbForceMigrate()
{
try
{
// se non ci fosse... crea o migra!
Database.Migrate();
Log.Info("DbForceMigrate: done!");
}
catch (Exception exc)
{
Log.Error(exc, "DbForceMigrate: Exception during context initialization 01");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.UseCollation("Latin1_General_CI_AS");
modelBuilder.Entity<CheckVc19Model>(entity =>
{
entity.Property(e => e.Cognome)
.HasMaxLength(100)
.HasColumnName("cognome")
.HasDefaultValueSql("('')");
entity.Property(e => e.Dob)
.HasColumnType("datetime")
.HasColumnName("DOB")
.HasDefaultValueSql("(getdate())");
entity.Property(e => e.DtCheck)
.HasColumnType("datetime")
.HasColumnName("dtCheck")
.HasDefaultValueSql("(getdate())");
entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente");
entity.Property(e => e.Nome)
.HasMaxLength(100)
.HasColumnName("nome")
.HasDefaultValueSql("('')");
entity.Property(e => e.Payload)
.HasMaxLength(500)
.HasColumnName("payload")
.HasDefaultValueSql("('')");
});
modelBuilder.Entity<DipendentiModel>(entity =>
{
entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente");
entity.Property(e => e.Attivo)
.HasColumnName("attivo")
.HasDefaultValueSql("((1))");
entity.Property(e => e.AuthKey)
.HasMaxLength(50)
.HasColumnName("authKey")
.HasDefaultValueSql("('##########')");
entity.Property(e => e.Cf)
.HasMaxLength(16)
.HasColumnName("CF")
.HasDefaultValueSql("('0000000000000000')");
entity.Property(e => e.CodDipendenteExt)
.HasMaxLength(50)
.HasColumnName("codDipendenteExt")
.HasDefaultValueSql("('')")
.HasComment("nome/codice dipendente per sistema esterno da importare");
entity.Property(e => e.CodHw)
.HasMaxLength(50)
.HasColumnName("codHw")
.HasDefaultValueSql("('')");
entity.Property(e => e.CodOrario)
.HasMaxLength(50)
.HasColumnName("codOrario");
entity.Property(e => e.Cognome).HasMaxLength(50);
entity.Property(e => e.DataAssunzione)
.HasColumnType("date")
.HasColumnName("dataAssunzione")
.HasDefaultValueSql("('1900-01-01')");
entity.Property(e => e.DataCessazione)
.HasColumnType("date")
.HasColumnName("dataCessazione")
.HasDefaultValueSql("('9999-12-31')");
entity.Property(e => e.DataNascita)
.HasColumnType("datetime")
.HasColumnName("dataNascita");
entity.Property(e => e.Dominio)
.HasMaxLength(50)
.HasColumnName("dominio")
.HasDefaultValueSql("('DOMINIO')");
entity.Property(e => e.Email)
.HasMaxLength(250)
.HasColumnName("email")
.HasDefaultValueSql("('')");
entity.Property(e => e.Gruppo)
.HasMaxLength(50)
.HasColumnName("gruppo")
.HasDefaultValueSql("('NA')");
entity.Property(e => e.LuogoNascita)
.HasMaxLength(50)
.HasColumnName("luogoNascita");
entity.Property(e => e.MailDay)
.HasColumnName("mailDay")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MailLastOp)
.HasColumnName("mailLastOp")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MailMonth)
.HasColumnName("mailMonth")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MailWeek)
.HasColumnName("mailWeek")
.HasDefaultValueSql("((0))");
entity.Property(e => e.Matricola)
.HasMaxLength(50)
.HasColumnName("matricola");
entity.Property(e => e.NazNascita)
.HasMaxLength(50)
.HasColumnName("nazNascita");
entity.Property(e => e.Nome).HasMaxLength(50);
entity.Property(e => e.NumAuth)
.HasColumnName("numAuth")
.HasDefaultValueSql("((0))")
.HasComment("numero di impieghi della authKey");
entity.Property(e => e.ProvNascita)
.HasMaxLength(50)
.HasColumnName("provNascita");
entity.Property(e => e.Utente)
.HasMaxLength(50)
.HasColumnName("utente")
.HasDefaultValueSql("('UTENTE')");
entity.Property(e => e.WolMac)
.HasMaxLength(50)
.HasColumnName("WOL_MAC");
});
modelBuilder.Entity<RegAttivitaModel>(entity =>
{
entity.HasIndex(e => e.Inizio, "ix_RA_inizio");
entity.HasIndex(e => new { e.IdxDipendente, e.Inizio }, "ix_idxDip");
entity.HasIndex(e => new { e.IdxFase, e.Inizio }, "ix_idxFase")
.HasFillFactor(100);
entity.HasIndex(e => new { e.Inizio, e.IdxDipendente }, "ix_inizio");
entity.Property(e => e.IdxRa).HasColumnName("idxRA");
entity.Property(e => e.Descrizione)
.HasMaxLength(500)
.HasColumnName("descrizione");
entity.Property(e => e.Fine)
.HasColumnType("datetime")
.HasColumnName("fine");
entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente");
entity.Property(e => e.IdxFase).HasColumnName("idxFase");
entity.Property(e => e.Importo)
.HasColumnType("decimal(19, 4)")
.HasColumnName("importo")
.HasDefaultValueSql("((0))");
entity.Property(e => e.Inizio)
.HasColumnType("datetime")
.HasColumnName("inizio");
entity.Property(e => e.OreTot)
.HasColumnType("decimal(19, 4)")
.HasColumnName("oreTot")
.HasComputedColumnSql("(CONVERT([decimal](19,4),CONVERT([decimal](19,4),datediff(minute,isnull([inizio],'19000101'),isnull([fine],'19000101')),(0))/(60),(0)))", false)
.HasComment("Ore Attività - prima era ([dbo].[f_hourInterval]([inizio],[fine])) poi sostituita per performance");
//entity.HasOne(d => d.DipNav)
// .WithMany(p => p.RegAttivitaNav)
// .HasForeignKey(d => d.IdxDipendente)
// .OnDelete(DeleteBehavior.ClientSetNull)
// .HasConstraintName("FK_RegAttivita_Dipendenti");
});
modelBuilder.Entity<RilievoTempModel>(entity =>
{
entity.HasKey(e => new { e.IdxDipendente, e.DtRilievo });
entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente");
entity.Property(e => e.DtRilievo)
.HasColumnType("datetime")
.HasColumnName("dtRilievo");
entity.Property(e => e.TempRil)
.HasColumnType("decimal(9, 3)")
.HasColumnName("tempRil");
entity.HasOne(d => d.DipNav)
.WithMany(p => p.RilievoTempNav)
.HasForeignKey(d => d.IdxDipendente)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_RilievoTemp_Dipendenti");
});
modelBuilder.Entity<TimbratureModel>(entity =>
{
entity.HasKey(e => new { e.IdxDipendente, e.DataOra });
entity.HasIndex(e => new { e.IdxDipendente, e.Entrata }, "ix_Timbrature_IdxDip_Entrata");
entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente");
entity.Property(e => e.DataOra)
.HasColumnType("datetime")
.HasColumnName("dataOra");
entity.Property(e => e.Approv)
.HasDefaultValueSql("((0))")
.HasComment("Approvazioen timbratura (default true...)");
entity.Property(e => e.CodTipoTimb)
.HasMaxLength(10)
.HasDefaultValueSql("(N'BC')");
entity.Property(e => e.Entrata).HasColumnName("entrata");
entity.Property(e => e.Ipv4)
.HasMaxLength(15)
.HasColumnName("IPv4")
.HasDefaultValueSql("(N'0.0.0.0')");
entity.HasOne(d => d.DipNav)
.WithMany(p => p.TimbratureNav)
.HasForeignKey(d => d.IdxDipendente)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Timbrature_Dipendenti");
});
modelBuilder.Entity<RegAttivitaExplModel>(entity =>
{
entity.HasKey(e => new { e.DataLav, e.IdxDipendente });
entity.ToTable("RegAttivitaExpl");
entity.Property(e => e.DataLav)
.HasColumnType("date")
.HasColumnName("dataLav");
entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente");
entity.Property(e => e.CognomeNome)
.HasMaxLength(100)
.HasDefaultValueSql("('')");
entity.Property(e => e.DescrProj)
.HasMaxLength(500)
.HasColumnName("descrProj")
.HasDefaultValueSql("('')");
entity.Property(e => e.MinRegAtt)
.HasColumnName("minRegAtt")
.HasDefaultValueSql("((0))")
.HasComment("totale dei minuti di attività registrate per la giornata (da trigger suRegAttivita)");
});
modelBuilder.Entity<TimbratureExplModel>(entity =>
{
entity.HasKey(e => new { e.DataLav, e.IdxDipendente })
.HasName("PK_TimbratureExpl_1");
entity.ToTable("TimbratureExpl");
entity.HasIndex(e => new { e.CognomeNome, e.DataLav }, "ix_TimbrExpl_CognomeNome_DataLav")
.HasFillFactor(100);
entity.HasIndex(e => e.IdxDipendente, "ix_idxDip")
.HasFillFactor(100);
entity.Property(e => e.DataLav)
.HasColumnType("date")
.HasColumnName("dataLav");
entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente");
entity.Property(e => e.Block)
.HasColumnName("block")
.HasDefaultValueSql("((0))")
.HasComment("determina se il record sia \"bloccato\" (archiviazione e blocco mesi precedenti...)");
entity.Property(e => e.ChkFunCod)
.HasMaxLength(50)
.HasColumnName("chkFunCod")
.HasDefaultValueSql("('')")
.HasComment("eventuale diagnostica da check function sulla riga indicata (codice)");
entity.Property(e => e.ChkFunRes)
.HasMaxLength(50)
.HasColumnName("chkFunRes")
.HasDefaultValueSql("('')")
.HasComment("eventuale diagnostica da check function sulla riga indicata (spiegazione)");
entity.Property(e => e.CognomeNome).HasMaxLength(100);
entity.Property(e => e.Entrata1)
.HasColumnType("datetime")
.HasColumnName("entrata_1");
entity.Property(e => e.Entrata2)
.HasColumnType("datetime")
.HasColumnName("entrata_2");
entity.Property(e => e.Entrata3)
.HasColumnType("datetime")
.HasColumnName("entrata_3");
entity.Property(e => e.Entrata4)
.HasColumnType("datetime")
.HasColumnName("entrata_4");
entity.Property(e => e.HGiust)
.HasColumnName("h_giust")
.HasComputedColumnSql("(((((((CONVERT([float],[minPerm],(0))+[minFer])+[minMal])+[minFest])+[min104])+[minMpp])+[minCassa])/(60))", false)
.HasComment("totale ore giustificate");
entity.Property(e => e.HLav).HasColumnName("h_lav");
entity.Property(e => e.IsOk)
.HasColumnName("isOk")
.HasComputedColumnSql("(([isOkTim]&[isOkApp])&case when [minOrd]<=((((((([minLav]+[minPerm])+[minFer])+[minMal])+[minFest])+[minCassa])+[min104])+[minMpp]) then (1) else (0) end)", false);
entity.Property(e => e.IsOkApp)
.HasColumnName("isOkApp")
.HasDefaultValueSql("((1))")
.HasComment("dato sintetico x indicare se TUTTE le timbrature componenti siano approvate");
entity.Property(e => e.IsOkLav)
.HasColumnName("isOkLav")
.HasComputedColumnSql("(case when [minOrd]<=((((((([minLav]+[minPerm])+[minFer])+[minMal])+[minFest])+[minCassa])+[min104])+[minMpp]) then (1) else (0) end)", false)
.HasComment("determina se la giornata sia ok (oreLav + giustificativi >= oreOrd)");
entity.Property(e => e.IsOkTim)
.HasColumnName("isOkTim")
.HasDefaultValueSql("((0))");
entity.Property(e => e.Min104)
.HasColumnName("min104")
.HasDefaultValueSql("((0))")
.HasComment("Minuti Permessi per 104");
entity.Property(e => e.MinArcoPres)
.HasColumnName("minArcoPres")
.HasComputedColumnSql("(datediff(minute,isnull([entrata_1],getdate()),isnull(isnull([uscita_4],isnull([uscita_3],isnull([uscita_2],isnull([uscita_1],[entrata_1])))),getdate())))", false)
.HasComment("DATEDIFF(n, ISNULL(entrata_1,GETDATE()), ISNULL(ISNULL(uscita_4,ISNULL(uscita_3,ISNULL(uscita_2,ISNULL(uscita_1,entrata_1)))),GETDATE()))");
entity.Property(e => e.MinCassa)
.HasColumnName("minCassa")
.HasDefaultValueSql("((0))")
.HasComment("Minuti di Cassa Integrazione");
entity.Property(e => e.MinFer)
.HasColumnName("minFer")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MinFest)
.HasColumnName("minFest")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MinLav)
.HasColumnName("minLav")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MinMal)
.HasColumnName("minMal")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MinMpp)
.HasColumnName("minMpp")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MinNonLav)
.HasColumnName("minNonLav")
.HasDefaultValueSql("((0))")
.HasComment("minuti non lavorati (ovvero se fatti meno di ordinari e senza giustificativi)");
entity.Property(e => e.MinOrd)
.HasColumnName("minOrd")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MinPerm)
.HasColumnName("minPerm")
.HasDefaultValueSql("((0))");
entity.Property(e => e.MinStra)
.HasColumnName("minStra")
.HasDefaultValueSql("((0))");
entity.Property(e => e.TempRil)
.HasColumnType("decimal(9, 3)")
.HasColumnName("tempRil")
.HasComment("Temperatura rilevata");
entity.Property(e => e.Uscita1)
.HasColumnType("datetime")
.HasColumnName("uscita_1");
entity.Property(e => e.Uscita2)
.HasColumnType("datetime")
.HasColumnName("uscita_2");
entity.Property(e => e.Uscita3)
.HasColumnType("datetime")
.HasColumnName("uscita_3");
entity.Property(e => e.Uscita4)
.HasColumnType("datetime")
.HasColumnName("uscita_4");
});
modelBuilder.Entity<AnagClientiModel>(entity =>
{
entity.Property(e => e.IdxCliente).HasColumnName("idxCliente");
entity.Property(e => e.Attivo).HasDefaultValueSql("((1))");
entity.Property(e => e.Cap)
.HasMaxLength(5)
.HasColumnName("CAP");
entity.Property(e => e.Cf)
.HasMaxLength(20)
.HasColumnName("CF");
entity.Property(e => e.Citta)
.HasMaxLength(50)
.HasColumnName("citta");
entity.Property(e => e.CodExt)
.HasMaxLength(50)
.HasColumnName("codExt")
.HasDefaultValueSql("('n.d.')")
.HasComment("codice esterno");
entity.Property(e => e.Email)
.HasMaxLength(50)
.HasColumnName("email");
entity.Property(e => e.Indirizzo)
.HasMaxLength(50)
.HasColumnName("indirizzo");
entity.Property(e => e.LogoUrl)
.HasMaxLength(50)
.HasColumnName("logoUrl");
entity.Property(e => e.Nota)
.HasMaxLength(500)
.HasColumnName("nota");
entity.Property(e => e.OldIdx).HasDefaultValueSql("((-1))");
entity.Property(e => e.PIva)
.HasMaxLength(20)
.HasColumnName("pIva");
entity.Property(e => e.Prov)
.HasMaxLength(50)
.HasColumnName("prov");
entity.Property(e => e.RagSociale).HasMaxLength(250);
entity.Property(e => e.Tel)
.HasMaxLength(50)
.HasColumnName("tel");
entity.Property(e => e.Url)
.HasMaxLength(50)
.HasColumnName("url");
});
modelBuilder.Entity<AnagFasiModel>(entity =>
{
entity.HasIndex(e => new { e.IdxProgetto, e.Attivo }, "ix_AnagFasi_idxProgetto_Attivo");
entity.Property(e => e.IdxFase).HasColumnName("idxFase");
entity.Property(e => e.Attivo)
.IsRequired()
.HasDefaultValueSql("((1))");
entity.Property(e => e.BudgetMoney)
.HasColumnType("decimal(19, 4)")
.HasColumnName("budgetMoney");
entity.Property(e => e.BudgetTime)
.HasColumnType("decimal(19, 4)")
.HasColumnName("budgetTime")
.HasComment("Budget del progetto (in ore)");
entity.Property(e => e.CodClasse)
.HasMaxLength(10)
.HasColumnName("codClasse")
.HasComment("codice univoco");
entity.Property(e => e.CodExt)
.HasMaxLength(50)
.HasColumnName("codExt")
.HasComment("codice esterno");
entity.Property(e => e.CodFase)
.HasMaxLength(250)
.HasColumnName("codFase")
.HasComment("codice fase gerarchico (F.1.2. = Fase 1, sottofase 2) - aggiornare con trigger!");
entity.Property(e => e.DescrizioneFase)
.HasMaxLength(250)
.HasColumnName("descrizioneFase");
entity.Property(e => e.EnableMoney)
.HasColumnName("enableMoney")
.HasDefaultValueSql("((0))")
.HasComment("indica se sia abilitata o meno a ricevere assegnazioni di record di spesa");
entity.Property(e => e.EnableTime)
.HasColumnName("enableTime")
.HasDefaultValueSql("((0))")
.HasComment("indica se sia abilitata o meno a ricevere assegnazioni di record temporali");
entity.Property(e => e.IdxFaseAncest)
.HasColumnName("idxFaseAncest")
.HasComment("fase ANCESTOR (contenitore), 0 = è top level");
entity.Property(e => e.IdxProgetto).HasColumnName("idxProgetto");
entity.Property(e => e.NomeFase)
.HasMaxLength(250)
.HasColumnName("nomeFase");
});
modelBuilder.Entity<AnagProgettiModel>(entity =>
{
entity.Property(e => e.IdxProgetto).HasColumnName("idxProgetto");
entity.Property(e => e.Attivo)
.IsRequired()
.HasDefaultValueSql("((1))");
entity.Property(e => e.Avvio)
.HasColumnType("datetime")
.HasColumnName("avvio")
.HasDefaultValueSql("(getdate())");
entity.Property(e => e.Chiusura)
.HasColumnType("datetime")
.HasColumnName("chiusura")
.HasDefaultValueSql("(dateadd(year,(10),getdate()))");
entity.Property(e => e.CodExt)
.HasMaxLength(50)
.HasColumnName("codExt")
.HasDefaultValueSql("('')")
.HasComment("codice esterno");
entity.Property(e => e.DescrProj)
.HasMaxLength(250)
.HasColumnName("descrProj")
.HasDefaultValueSql("('-')");
entity.Property(e => e.Gruppo)
.HasMaxLength(50)
.HasColumnName("gruppo")
.HasDefaultValueSql("('STEAMWARE')");
entity.Property(e => e.IdxCliente).HasColumnName("idxCliente");
entity.Property(e => e.NomeProj)
.HasMaxLength(50)
.HasColumnName("nomeProj");
entity.Property(e => e.Starred).HasColumnName("starred");
});
modelBuilder.Entity<AnagGruppiModel>(entity =>
{
entity.HasKey(e => e.Gruppo);
entity.ToTable("AnagGruppi");
entity.Property(e => e.Gruppo)
.HasMaxLength(50)
.HasColumnName("gruppo");
entity.Property(e => e.CodExt)
.HasMaxLength(4)
.HasColumnName("codExt");
entity.Property(e => e.DescrGruppo)
.HasMaxLength(50)
.HasColumnName("descrGruppo");
entity.Property(e => e.ExportEnab)
.HasColumnName("exportEnab")
.HasDefaultValueSql("((1))")
.HasComment("determina se sia abilitato x export dati");
});
modelBuilder.Entity<AnagKeyValueModel>(entity =>
{
entity.HasKey(e => e.NomeVar);
entity.ToTable("AnagKeyValue");
entity.Property(e => e.NomeVar)
.HasMaxLength(50)
.HasColumnName("nomeVar");
entity.Property(e => e.Descrizione)
.HasMaxLength(250)
.HasColumnName("descrizione")
.HasDefaultValueSql("('-')");
entity.Property(e => e.ValFloat)
.HasColumnName("valFloat")
.HasDefaultValueSql("((0))");
entity.Property(e => e.ValInt)
.HasColumnName("valInt")
.HasDefaultValueSql("((0))");
entity.Property(e => e.ValString)
.HasMaxLength(250)
.HasColumnName("valString")
.HasDefaultValueSql("('')");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
-220
View File
@@ -1,220 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data
{
public class LiManObj
{
#region Public Enums
public enum StatoRichiesta
{
ND = 0,
Richiesta,
Valutazione,
Approvata,
Rifiutata
}
public enum TipoLicenza
{
ND = 0,
/// <summary>
/// Licenza LEgacy Steamware
/// </summary>
GLS,
/// <summary>
/// Master Key License, che ha una data di scadenza globale ed un token = numero di utenti/token massimi associati
/// </summary>
MasterKey,
/// <summary>
/// UserKey License (licenza che consuma un token utente della licenza master) - es GPW
/// </summary>
UserKey,
/// <summary>
/// Chiave tiupo Checksum basata su licenza masster + checksum MD5 di una serie di dati (child licenses)
/// </summary>
CheckSumKey
}
#endregion Public Enums
#region Public Classes
public class ApplicativoDTO
{
#region Public Properties
public string Chiave { get; set; } = "";
public string CodApp { get; set; } = "";
public string CodInst { get; set; } = "";
public DateTime DataEnigma { get; set; } = DateTime.Today.AddYears(-1);
public string Descrizione { get; set; } = "";
public string Enigma { get; set; } = "";
public int IdxLic { get; set; } = 0;
public bool IsActive
{
get => (Scadenza.Subtract(DateTime.Today).TotalDays > 0);
}
public bool Locked { get; set; } = false;
public int NumLicenze { get; set; } = 0;
public int NumLicenzeAttive { get; set; } = 0;
public string Payload { get; set; } = "";
public DateTime Scadenza { get; set; } = DateTime.Today.AddYears(-1);
public TipoLicenza Tipo { get; set; } = TipoLicenza.ND;
#endregion Public Properties
}
public class AttivazioneDTO
{
#region Public Properties
public string Chiave { get; set; } = "";
public string CodApp { get; set; } = "";
public string CodImpiego { get; set; } = "";
public string CodInst { get; set; } = "";
public string Descrizione { get; set; } = "";
public int IdxLic { get; set; } = 0;
public int IdxSubLic { get; set; } = 0;
public TipoLicenza Tipo { get; set; } = TipoLicenza.UserKey;
public DateTime VetoUnlock { get; set; } = DateTime.Today.AddMonths(2);
#endregion Public Properties
}
public class LicenseCoord
{
#region Public Properties
public string CodApp { get; set; } = "";
public string CodInst { get; set; } = "";
public string Enigma { get; set; } = "";
public string MasterKey { get; set; } = "";
#endregion Public Properties
}
public class SupportRequest
{
#region Public Properties
public string CodApp { get; set; } = "";
public string CodImp { get; set; } = "";
public string CodInst { get; set; } = "";
public string ContactEmail { get; set; } = "";
public string ContactName { get; set; } = "";
public string ContactPhone { get; set; } = "";
public int idxSubLic { get; set; } = 0;
public bool IsValid
{
get => !string.IsNullOrEmpty(MasterKey) && !string.IsNullOrEmpty(ContactName) && !string.IsNullOrEmpty(ContactEmail) && !string.IsNullOrEmpty(CodInst) && !string.IsNullOrEmpty(CodApp);
}
public string MasterKey { get; set; } = "";
public string ReqBody { get; set; } = "";
#endregion Public Properties
}
/// <summary>
/// Oggetto Ticket
/// </summary>
public class TicketDTO
{
#region Public Properties
/// <summary>
/// Codice univoco della sub licenza (opzionale)
/// </summary>
public string CodImpiego { get; set; } = "";
/// <summary>
/// Contatto email del cliente richiedente
/// </summary>
public string ContactEmail { get; set; } = "";
/// <summary>
/// Contatto del cliente richiedente
/// </summary>
public string ContactName { get; set; } = "";
/// <summary>
/// Contatto telefonico del cliente richiedente
/// </summary>
public string ContactPhone { get; set; } = "";
public DateTime DtReq { get; set; } = DateTime.Now;
/// <summary>
/// IDX licenza master
/// </summary>
public int IdxLic { get; set; } = 0;
/// <summary>
/// IDX licenza child (opzionale)
/// </summary>
public int IdxSubLic { get; set; } = 0;
public int IdxTicket { get; set; } = 0;
/// <summary>
/// Motivazione della richiesta
/// </summary>
public string ReqBody { get; set; } = "";
/// <summary>
/// Stato richiesta
/// </summary>
public StatoRichiesta Status { get; set; } = StatoRichiesta.ND;
/// <summary>
/// Risposta alla richiesta
/// </summary>
public string SupplAnsw { get; set; } = "";
/// <summary>
/// Email del responsabile dell'azione (interno - supplier)
/// </summary>
public string SupplEmail { get; set; } = "";
/// <summary>
/// Cod dell'user responsabile dell'azione (interno - supplier)
/// </summary>
public string SupplUserCode { get; set; } = "";
/// <summary>
/// Tipologia di licenza gestita
/// </summary>
public TipoLicenza Tipo { get; set; } = TipoLicenza.UserKey;
#endregion Public Properties
}
public class UserLicenseRequest
{
#region Public Properties
public string MasterKey { get; set; } = "";
public Dictionary<string, string> ParamDict { get; set; } = new Dictionary<string, string>();
#endregion Public Properties
}
#endregion Public Classes
}
}
-64
View File
@@ -1,64 +0,0 @@
using MailKit.Net.Smtp;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using MimeKit;
using MimeKit.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data
{
/// Implementazione interfaccia email con pacchetto MailKIT
///
/// https://www.ryadel.com/en/asp-net-core-send-email-messages-smtp-mailkit/
/// </summary>
public class MailKitEmailSender : IEmailSender
{
#region Public Constructors
public MailKitEmailSender(IOptions<MailKitEmailSenderOptions> options)
{
this.Options = options.Value;
}
#endregion Public Constructors
#region Public Properties
public MailKitEmailSenderOptions Options { get; set; }
#endregion Public Properties
#region Public Methods
public Task Execute(string to, string subject, string message)
{
// create message
var email = new MimeMessage();
email.Sender = MailboxAddress.Parse(Options.Sender_EMail);
if (!string.IsNullOrEmpty(Options.Sender_Name))
email.Sender.Name = Options.Sender_Name;
email.From.Add(email.Sender);
email.To.Add(MailboxAddress.Parse(to));
email.Subject = subject;
email.Body = new TextPart(TextFormat.Html) { Text = message };
// send email
using (var smtp = new SmtpClient())
{
smtp.Connect(Options.Host_Address, Options.Host_Port, Options.Host_SecureSocketOptions);
smtp.Authenticate(Options.Host_Username, Options.Host_Password);
smtp.Send(email);
smtp.Disconnect(true);
}
return Task.FromResult(true);
}
public Task SendEmailAsync(string email, string subject, string message)
{
return Execute(email, subject, message);
}
#endregion Public Methods
}
}
@@ -1,36 +0,0 @@
using MailKit.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data
{
public class MailKitEmailSenderOptions
{
#region Public Constructors
public MailKitEmailSenderOptions()
{
Host_SecureSocketOptions = SecureSocketOptions.Auto;
}
#endregion Public Constructors
#region Public Properties
public string Host_Address { get; set; }
public string Host_Password { get; set; }
public int Host_Port { get; set; }
public SecureSocketOptions Host_SecureSocketOptions { get; set; }
public string Host_Username { get; set; }
public string Sender_EMail { get; set; }
public string Sender_Name { get; set; }
#endregion Public Properties
}
}
-64
View File
@@ -1,64 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data
{
public class Utils
{
/// <summary>
/// Effettua trim di una data al numero di minuti indicato
///
/// vedere qui:
/// https://stackoverflow.com/questions/1393696/rounding-datetime-objects
/// </summary>
/// <param name="DateOrig">DataOra originale</param>
/// <param name="roundMin">Minuti di arrotondamento richeisti</param>
/// <param name="isFloor">Arrotondamento x difetto (floor = true) o eccesso (false)</param>
/// <returns></returns>
public static DateTime DateRounded(DateTime DateOrig, int roundMin, bool isFloor)
{
long ticks = 0;
roundMin = roundMin <= 0 ? 1 : roundMin;
TimeOnly step = new TimeOnly(0, roundMin);
if (isFloor)
{
ticks= DateOrig.Ticks / step.Ticks;
}
else
{
ticks = (DateOrig.Ticks + step.Ticks - 1) / step.Ticks;
}
DateTime answ = new DateTime(ticks * step.Ticks, DateOrig.Kind);
return answ;
}
/// <summary>
/// Effettua arrotondamento di un timespan ad un dato step di minuti
///
/// vedere qui:
/// https://stackoverflow.com/questions/1393696/rounding-datetime-objects
/// </summary>
/// <param name="DateOrig">DataOra originale</param>
/// <param name="roundMin">Minuti di arrotondamento richeisti</param>
/// <param name="isFloor">Arrotondamento x difetto (floor = true) o eccesso (false)</param>
/// <returns></returns>
public static TimeSpan TSpanRounded(TimeSpan TSpanOrig, int roundMin, bool isFloor)
{
long ticks = 0;
roundMin = roundMin <= 0 ? 1 : roundMin;
TimeOnly step = new TimeOnly(0, roundMin);
if (isFloor)
{
ticks = TSpanOrig.Ticks / step.Ticks;
}
else
{
ticks = (TSpanOrig.Ticks + step.Ticks - 1) / step.Ticks;
}
TimeSpan answ = new TimeSpan(ticks * step.Ticks);
return answ;
}
}
}
-98
View File
@@ -1,98 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GPW.CORE.Data
{
public class WeekData
{
public int anno { get; set; } = DateTime.Today.Year;
public DateTime inizio { get; set; } = DateTime.Today;
public DateTime fine { get; set; } = DateTime.Today.AddDays(1);
public int weekNumber { get; set; } = 1;
/// <summary>
/// Calcola estremi settimana dato un giorno come lunedì-domenica
/// </summary>
/// <param name="dtRif"></param>
public WeekData(DateTime dtRif)
{
DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(dtRif);
this.anno = dtRif.Year;
this.weekNumber = GetIso8601WeekOfYear(dtRif);
this.inizio = dtRif.Date.AddDays(1 - (int)day);
this.fine = dtRif.Date.AddDays(7 - (int)day);
}
/// <summary>
/// Calcola estremi settimana dato numero + anno
/// </summary>
/// <param name="numWeek"></param>
public WeekData(int year, int numWeek)
{
this.anno = year;
this.weekNumber = numWeek;
DateTime dtRif = FirstDateOfWeekISO8601(year, numWeek);
DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(dtRif);
this.inizio = dtRif.Date.AddDays(1 - (int)day);
this.fine = dtRif.Date.AddDays(7 - (int)day);
}
/// <summary>
/// Calcolo settimana dell'anno ISO 8601
///
/// This presumes that weeks start with Monday.
/// Week 1 is the 1st week of the year with a Thursday in it.
///
/// rif: https://stackoverflow.com/questions/11154673/get-the-correct-week-number-of-a-given-date
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
public static int GetIso8601WeekOfYear(DateTime time)
{
// Seriously cheat. If its Monday, Tuesday or Wednesday, then it'll
// be the same week# as whatever Thursday, Friday or Saturday are,
// and we always get those right
DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
{
time = time.AddDays(3);
}
// Return the week of our adjusted day
return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear)
{
DateTime jan1 = new DateTime(year, 1, 1);
int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek;
// Use first Thursday in January to get first week of the year as
// it will never be in Week 52/53
DateTime firstThursday = jan1.AddDays(daysOffset);
var cal = CultureInfo.CurrentCulture.Calendar;
int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
var weekNum = weekOfYear;
// As we're adding days to a date in Week 1,
// we need to subtract 1 in order to get the right date for week #1
if (firstWeek == 1)
{
weekNum -= 1;
}
// Using the first Thursday as starting week ensures that we are starting in the right year
// then we add number of weeks multiplied with days
var result = firstThursday.AddDays(weekNum * 7);
// Subtract 3 days from Thursday to get Monday, which is the first weekday in ISO8601
return result.AddDays(-3);
}
}
}
-37
View File
@@ -1,37 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31912.275
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPW.CORE.UI", "GPW.CORE.UI\GPW.CORE.UI.csproj", "{E4229EE4-ED4F-4507-8058-B01DC3CA1B28}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPW.CORE.Data", "GPW.CORE.Data\GPW.CORE.Data.csproj", "{718B275D-7573-4CE2-87AF-57FCAAD71BD8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GPW.CORE.Api", "GPW.CORE.Api\GPW.CORE.Api.csproj", "{5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E4229EE4-ED4F-4507-8058-B01DC3CA1B28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E4229EE4-ED4F-4507-8058-B01DC3CA1B28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E4229EE4-ED4F-4507-8058-B01DC3CA1B28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4229EE4-ED4F-4507-8058-B01DC3CA1B28}.Release|Any CPU.Build.0 = Release|Any CPU
{718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Release|Any CPU.Build.0 = Release|Any CPU
{5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AE057165-54C4-4678-8617-A03F0E8F6495}
EndGlobalSection
EndGlobal
-5
View File
@@ -1,5 +0,0 @@
{
"version": 1,
"isRoot": true,
"tools": {}
}
-14
View File
@@ -1,14 +0,0 @@
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
-71
View File
@@ -1,71 +0,0 @@
@using CORE.Data.DbModels
@using UI.Data
@inject GpwDataService GDataServ
@inject MessageService AppMServ
@if (EnableAction)
{
<button @onclick="() => AddNew()" class="px-1 text-center btn btn-lg btn-outline-success">
@if (canPaste)
{
<i class="fas fa-clipboard"></i>
}
else
{
<i class="fas fa-plus-circle"></i>
}
</button>
}
else
{
<span>&nbsp;</span>
}
@code {
[Parameter]
public DateTime InizioPer { get; set; } = DateTime.Today.AddHours(8);
[Parameter]
public int IdxDip { get; set; } = 0;
[Parameter]
public EventCallback<RegAttivitaModel> NewItemCreated { get; set; }
[Parameter]
public bool EnableAction { get; set; } = true;
protected bool canPaste
{
get => AppMServ.clonedRA != null;
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void AddNew()
{
RegAttivitaModel newItem = new RegAttivitaModel();
TimeSpan durata = new TimeSpan(1, 0, 0);
// se ho un record clonato parto da quello...
if (AppMServ.clonedRA != null && (!GDataServ.VetoInsert || (AppMServ.clonedRA.FasiNav!=null && AppMServ.clonedRA.FasiNav.Attivo)))
{
newItem = AppMServ.clonedRA;
}
else
{
// recupero ultima fase x utente...
newItem = await GDataServ.RegAttLastByDip(AppMServ.IdxDipendente, GDataServ.VetoInsert);
}
// calcolo durata arrotondata ai 5 minuti...
durata = CORE.Data.Utils.TSpanRounded(newItem.Durata, 5, false);
newItem.IdxRa = 0;
newItem.Inizio = InizioPer;
newItem.Fine = InizioPer.AddMinutes(durata.TotalMinutes);
// salvo in AppMS
AppMServ.recordRA = newItem;
await NewItemCreated.InvokeAsync(newItem);
}
}
-62
View File
@@ -1,62 +0,0 @@
@inject IJSRuntime JSRuntime
<canvas id="@Id"></canvas>
@code {
public enum ChartType
{
Pie,
Bar
}
[Parameter]
public string Id { get; set; } = "MyChart";
[Parameter]
public ChartType Type { get; set; }
[Parameter]
public string[] Data { get; set; }
[Parameter]
public string[] BackgroundColor { get; set; }
[Parameter]
public string[] Labels { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await InitDefault();
}
protected async Task InitDefault()
{
// Here we create an anonymous type with all the options
// that need to be sent to Chart.js
var config = new
{
type = Type.ToString().ToLower(),
options = new
{
responsive = true,
scales = new
{
yAxes = new
{
suggestedMin = 0
}
}
},
data = new
{
datasets = new[]
{
new { data = Data, backgroundColor = BackgroundColor}
},
labels = Labels
}
};
await JSRuntime.InvokeVoidAsync("setup", Id, config);
}
}
-82
View File
@@ -1,82 +0,0 @@
@inject IJSRuntime JSRuntime
<canvas id="@Id"></canvas>
@code {
[Parameter]
public string Id { get; set; } = "MyHist";
[Parameter]
public string[] Data { get; set; }
[Parameter]
public string[] Labels { get; set; }
[Parameter]
public string lineColor { get; set; }
[Parameter]
public string backColor { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
//if (!firstRender)
//{
await renderChart();
//}
}
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui:
/// https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/
/// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected async Task renderChart()
{
// creazione di un oggetto anonymous type con tutte le opzioni da passare a chart.js
var config = new
{
type = "bar",
options = new
{
responsive = true,
scales = new
{
yAxes = new
{
suggestedMin = 0,
display = true,
ticks = new
{
beginAtZero = true,
maxTicksLimit = 10
}
}
}
},
data = new
{
datasets = new[]
{
new
{
data = Data,
borderColor = lineColor,
backgroundColor = backColor,
borderWidth = 1,
label= "Freq. Osservate"
}
},
labels = Labels
}
};
await JSRuntime.InvokeVoidAsync("setup", Id, config);
}
}
-90
View File
@@ -1,90 +0,0 @@
@inject IJSRuntime JSRuntime
<canvas id="@Id"></canvas>
@code {
[Parameter]
public string Id { get; set; } = "MyTs";
[Parameter]
public List<chartJsData.chartJsTSerie> DataTS { get; set; }
[Parameter]
public string lineColor { get; set; }
[Parameter]
public string backColor { get; set; }
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui:
/// https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/
/// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected override async Task OnAfterRenderAsync(bool firstRender)
{
//if (!firstRender)
//{
await renderChart();
//}
}
/// <summary>
/// Inizializzazione rendering componente
///
/// partendo da qui:
/// https://www.williamleme.com/posts/2020/003-chartjs-blazor/
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/
/// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected async Task renderChart()
{
// creazione di un oggetto anonymous type con tutte le opzioni da passare a chart.js
var config = new
{
type = "line",
options = new
{
responsive = true,
scales = new
{
yAxes = new
{
display = true,
ticks = new
{
maxTicksLimit = 10
}
},
xAxes = new
{
type = "timeseries",
distribution = "linear",
}
}
},
data = new
{
datasets = new[]
{
new
{
data = DataTS,
borderColor= lineColor,
backgroundColor= backColor,
lineTension= 0,
stepped= true,
label= "Temperatura Rilevata"
}
}
}
};
await JSRuntime.InvokeVoidAsync("setup", Id, config);
}
}
-16
View File
@@ -1,16 +0,0 @@
<div class="form-row text-light">
<div class="col-5 pr-0 text-left">
GPW.CORE.Logger <span class="small">v.@version</span>
</div>
<div class="col-7 pl-0 text-right">
<span class="small">@adesso</span>
<a class="text-light" href="https://www.egalware.com/" target="_blank"><img class="img-fluid" width="16" src="images/LogoEgw.png" /> Egalware </a>
</div>
</div>
@code {
protected DateTime adesso = DateTime.Now;
Version version = typeof(Program).Assembly.GetName().Version;
}
-56
View File
@@ -1,56 +0,0 @@
<div class="row">
<div class="col-12 col-lg-8 text-left">
<div class="row">
<div class="col-12 small">
@if (totalCount > 0)
{
<ul class="pagination pagination-sm mb-1">
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(1)"><i class="fas fa-angle-double-left"></i></button></li>
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(prevBlock)"><i class="fas fa-angle-left"></i></button></li>
@for (int i = @startPage; i <= endPage; ++i)
{
var pageNum = i;
<li class="page-item @cssActive(pageNum)"><button class="page-link" @onclick="() => PaginationItemClick(pageNum)">@pageNum</button></li>
}
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(nextBlock)"><i class="fas fa-angle-right"></i></button></li>
<li class="page-item"><button class="page-link" @onclick="() => PaginationItemClick(LastPage)"><i class="fas fa-angle-double-right"></i></button></li>
</ul>
}
</div>
</div>
<div class="row">
<div class="col-12 small">
@if (showLoading)
{
<div class="progress" style="height: 10px;">
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width:@percLoading%;"></div>
</div>
}
</div>
</div>
</div>
<div class="col-12 col-lg-4">
<div class="d-flex">
<div class="p-1 flex-fill text-right">
@if (!showLoading)
{
<span>@totalCount records</span>
}
</div>
<div class="p-1 flex-fill text-right small">
@if (totalCount > 0)
{
<div class="input-group input-group-sm">
<select @bind="@PageSize" class="form-control form-control-sm">
<option value="5">5</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
}
</div>
</div>
</div>
</div>
-201
View File
@@ -1,201 +0,0 @@
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.UI;
using GPW.CORE.UI.Shared;
namespace GPW.CORE.UI.Components
{
public partial class DataPager : ComponentBase
{
#region Protected Fields
protected bool _showLoading = false;
#endregion Protected Fields
#region Private Properties
private int endPage
{
get
{
int answ = (int)(currPage / numPages) * numPages + numPages;
answ = answ < LastPage ? answ : LastPage;
return answ;
}
}
private int LastPage
{
get
{
return Math.Max((int)Math.Ceiling(totalCount / (double)PageSize), 1);
}
}
private int nextBlock
{
get
{
int answ = currPage + numPages;
answ = answ < LastPage ? answ : LastPage;
return answ;
}
}
private int numPages { get; set; } = 10;
private int prevBlock
{
get
{
int answ = currPage - numPages;
answ = answ > 0 ? answ : 1;
return answ;
}
}
// calcola un set 1 .. numPages centrato sulla pagina corrente...
private int startPage
{
get
{
int answ = (int)(currPage / numPages) * numPages;
answ = answ > 0 ? answ : 1;
return answ;
}
}
#endregion Private Properties
#region Protected Properties
protected int _numPage { get; set; } = 1;
protected int _numRecord { get; set; } = 10;
protected int percLoading { get; set; } = 0;
#endregion Protected Properties
#region Public Properties
[Parameter]
public int currPage
{
get
{
return _numPage;
}
set
{
bool doReport = !_numPage.Equals(value);
if (doReport)
{
_numPage = value;
reportChangePage();
}
}
}
[Parameter]
public EventCallback<int> numPageChanged { get; set; }
[Parameter]
public EventCallback<int> numRecordChanged { get; set; }
[Parameter]
public int PageSize
{
get
{
return _numRecord;
}
set
{
bool doReport = !_numRecord.Equals(value);
if (doReport)
{
_numRecord = value;
reportChange();
}
}
}
[Parameter]
public bool showLoading
{
get
{
return _showLoading;
}
set
{
if (value)
{
Random random = new Random();
percLoading = random.Next(30, 90);
}
else
{
percLoading = 5;
}
_showLoading = value;
}
}
[Parameter]
public int totalCount { get; set; } = 0;
#endregion Public Properties
#region Private Methods
private void reportChange()
{
numRecordChanged.InvokeAsync(PageSize);
}
private void reportChangePage()
{
numPageChanged.InvokeAsync(currPage);
}
#endregion Private Methods
#region Protected Methods
protected string cssActive(int numPage)
{
string answ = "";
if (numPage == currPage)
{
answ = "active";
}
return answ;
}
protected override async Task OnInitializedAsync()
{
await Task.Run(() => showLoading = false);
}
protected void PaginationItemClick(int page)
{
currPage = page;
}
#endregion Protected Methods
}
}
@@ -1,35 +0,0 @@
@if (CurrDay == DayOfWeek.Saturday)
{
@if ((Ora - 8) % 2 == 0)
{
<td style="width: 13.8%;" rowspan="2">
<i>DayAgendaDetail</i>
</td>
}
}
else if (CurrDay == DayOfWeek.Sunday)
{
@if ((Ora - 8) % 4 == 0)
{
<td style="width: 13.8%;" rowspan="4">
<i>DayAgendaDetail</i>
</td>
}
}
else
{
<td style="width: 13.8%;">
<i>DayAgendaDetail</i>
</td>
}
@code {
[Parameter]
public DayOfWeek CurrDay { get; set; } = DayOfWeek.Sunday;
[Parameter]
public int Ora { get; set; } = 0;
}
-121
View File
@@ -1,121 +0,0 @@
@using CORE.Data.DbModels
@using UI.Data
@inject IJSRuntime JSRuntime
@inject GpwDataService GDataServ
@inject MessageService AppMServ
<div class="card">
<div class="card-header bg-dark text-light py-1">
<div class="row">
<div class="col-8">
<h4>Daily Cheks</h4>
</div>
<div class="col-4 py-1">
<button type="button" class="btn btn-block btn-warning py-1" @onclick="DoClose"><i class="fas fa-times"></i> Chiudi</button>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-4">
@if (listRilTemp != null)
{
<ChartTS Id="TempRil" DataTS="@listRilTemp" lineColor="rgb(7, 173, 236)" backColor="rgba(107, 223, 255, 0.3)"></ChartTS>
<ChartHist Id="FreqTemp1" Data="@histData" Labels="@histLabel" lineColor="rgb(7, 173, 236)" backColor="rgba(107, 223, 255, 0.5)"></ChartHist>
}
else
{
<LoadingDataSmall></LoadingDataSmall>
}
</div>
<div class="col-4 px-0">
<div class="card">
<div class="card-header text-center">
<b>@TargetDate.ToString("dddd dd/MM/yyyy")</b>
</div>
<div class="card-body">
@if (currRecord != null)
{
<label class="small">temperatura odierna</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" style="width:3em;">
<i class="fas fa-thermometer-half"></i>
</span>
</div>
<input type="number" step="0.1" min="35" max="42" class="form-control text-right" @bind="@currRecord.TempRil"></input>
<div class="input-group-append">
<button class="btn btn-success btn-block" title="Salva temperatura" @onclick="() => DoSave()"><i class="far fa-save"></i></button>
</div>
</div>
}
else
{
<LoadingDataSmall></LoadingDataSmall>
}
</div>
<div class="card-footer">
<label class="small">periodo grafici</label>
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text" style="width:3em;">
<i class="far fa-calendar-alt"></i>
</span>
</div>
<select @bind="@numDays" class="form-control" title="finestra analisi">
<option value="30">1 Mese</option>
<option value="60">2 Mese</option>
<option value="90">3 Mese</option>
<option value="180">6 Mese</option>
<option value="365">1 Anno</option>
<option value="730">2 Anno</option>
</select>
</div>
</div>
</div>
</div>
<div class="col-4">
@if (listVC19 != null)
{
<h4>Check C19</h4>
<table class="table table-sm table-striped small">
<thead>
<tr>
<th>Check</th>
<th>Cognome</th>
<th>Nome</th>
<th>Data Nascita</th>
</tr>
</thead>
<tbody>
@foreach (var record in listVC19)
{
<tr>
<td>
@record.DtCheck.ToString("dd/MM/yy HH:mm")
</td>
<td>
@record.Cognome
</td>
<td>
@record.Nome
</td>
<td>
@record.Dob.ToShortDateString()
</td>
</tr>
}
</tbody>
</table>
}
else
{
<LoadingDataSmall></LoadingDataSmall>
}
</div>
</div>
</div>
</div>
@@ -1,129 +0,0 @@
using GPW.CORE.Data.DbModels;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.UI.Components
{
public partial class DayCheckEditor
{
#region Protected Fields
protected int _numDays = 30;
#endregion Protected Fields
#region Private Properties
private int numDays
{
get
{
return _numDays;
}
set
{
_numDays = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
#endregion Private Properties
#region Protected Properties
protected DateTime _targetDate { get; set; } = DateTime.Today;
protected RilievoTempModel? currRecord { get; set; } = null;
protected string[]? histData { get; set; } = null;
protected string[]? histLabel { get; set; } = null;
protected List<chartJsData.chartJsTSerie>? listRilTemp { get; set; } = null;
protected List<CheckVc19Model>? listVC19 { get; set; } = null;
#endregion Protected Properties
#region Public Properties
[Parameter]
public EventCallback<bool> CloseReq { get; set; }
[Parameter]
public DateTime TargetDate
{
get
{
return _targetDate;
}
set
{
_targetDate = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
#endregion Public Properties
#region Protected Methods
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void DoClose()
{
await CloseReq.InvokeAsync(true);
}
/// <summary>
/// Effettua salvataggio misurazione temperatura
/// </summary>
protected async void DoSave()
{
// chiamo classe gestione che salva e resetta cache dati...
if (currRecord != null)
{
await GDataServ.RilTempUpdate(currRecord);
}
// chiamo chiusura!
await CloseReq.InvokeAsync(true);
}
protected async Task ReloadData()
{
DateTime inizio = TargetDate.AddDays(1 - numDays);
DateTime fine = TargetDate.AddDays(1);
// recupero dati completi...
var rawVC19 = await GDataServ.CheckVC19List(AppMServ.IdxDipendente, fine.AddDays(-15), fine);
var rawData = await GDataServ.RilTempList(AppMServ.IdxDipendente, inizio, fine);
// calcolo dati derivati
listVC19 = rawVC19.OrderByDescending(x => x.DtCheck).ToList();
listRilTemp = rawData.Select(r => new chartJsData.chartJsTSerie()
{ x = r.DtRilievo, y = r.TempRil }).ToList();
// calcolo hist frequenza con EFCore: https://entityframeworkcore.com/knowledge-base/60871048/group-by-and-to-dictionary-in-ef-core-3-1
var histDict = rawData.GroupBy(r => r.TempRil.ToString("N1")).Select(g => new
{
g.Key,
Count = g.Count()
}).OrderBy(d => d.Key).ToDictionary(x => x.Key, x => x.Count.ToString());
histData = histDict.Values.ToArray();
histLabel = histDict.Keys.ToArray();
// cerco se c'è dato odierno della temperatura...
currRecord = rawData.Where(x => x.DtRilievo == TargetDate).FirstOrDefault();
if (currRecord == null)
{
currRecord = new RilievoTempModel()
{ IdxDipendente = AppMServ.IdxDipendente, DtRilievo = DateTime.Today, TempRil = 0 };
}
}
#endregion Protected Methods
}
}
-71
View File
@@ -1,71 +0,0 @@

<div class="d-flex justify-content-between border border-dark border-top-0 border-left-0 border-right-0">
<div class="p-1" style="width: 3rem;">
@if (IsTitle)
{
<b>DAY</b>
}
else
{
<div class="text-uppercase"><b>@DayDTO.DtRif.ToString("ddd")</b></div>
<div class="small">@DayDTO.DtRif.ToString("dd.MM")</div>
}
</div>
<div class="p-1 py-0 flex-fill text-left">
@if (IsTitle)
{
<div class="d-flex justify-content-between text-center">
@for (int i = StartHour; i <= EndHour; i++)
{
<div class="px-1 py-0" style="font-size: 1.2em;">
<b>@i.ToString("00")</b>
</div>
}
</div>
}
else
{
<!-- Timbrature -->
<div class="d-flex justify-content-between text-center">
@if (@DayDTO != null && @DayDTO.ListTimbr != null)
{
@foreach (var item in ListTimb())
{
<PeriodoLav Periodo="periodo" CurrPeriodo="item" ItemSelected="PeriodoSelected"></PeriodoLav>
}
}
</div>
<!-- RegAtt -->
<div class="d-flex justify-content-between text-center">
@if (@noData)
{
<AddRA NewItemCreated="ReportSelected" InizioPer="@FirstTimb" IdxDip="@IdxDipSel" EnableAction="@EnableActionMenu"></AddRA>
}
else if (@DayDTO != null && @DayDTO.ListRA != null)
{
@foreach (var item in ListRegAtt())
{
<RegAtt CurrData="item" Periodo="periodo" ListFasi="@ListFasi" IdxDipSel="@IdxDipSel" ItemCloned="ReportCloned" ItemSelected="ReportSelected" ItemUpdated="ReportUpdated" EnableActionMenu="@EnableActionMenu"></RegAtt>
}
}
</div>
}
</div>
<div class="p-1 text-right" style="width: 5.0rem;">
@if (IsTitle)
{
<div class="small"><b>Timb</b> <i class="far fa-calendar-alt"></i></div>
<div class="small"><b>Lavo</b> <i class="far fa-hourglass"></i></div>
}
else
{
<div class="btn btn-sm btn-block btn-dark px-1 py-0" @onclick="SelTimbrature"><b>@TotLav</b> <i class="far fa-calendar-alt"></i></div>
<div class="btn btn-sm btn-block @cssBadgeLav px-1 py-0 mt-1"><b>@TotComm</b> <i class="far fa-hourglass"></i></div>
<div class="btn btn-sm btn-block btn-light border border-dark px-1 py-0 mt-1" @onclick="SelTemperature"><i class="fas fa-thermometer-half @cssThermo"></i> <i class="fas fa-certificate @cssCheck"></i></div>
}
</div>
</div>
-429
View File
@@ -1,429 +0,0 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using Microsoft.AspNetCore.Components;
namespace GPW.CORE.UI.Components
{
public partial class DayHoriz
{
#region Protected Fields
/// <summary>
/// record prima timbratura x
/// </summary>
protected DateTime FirstTimb = DateTime.Now;
#endregion Protected Fields
#region Private Properties
private bool noData { get => DayDTO == null || DayDTO.ListRA == null || DayDTO.ListRA.Count == 0; }
private bool OkTemp
{
get
{
bool answ = false;
if (DayDTO != null && DayDTO.ListRilTemp != null)
{
answ = DayDTO.ListRilTemp.Count > 0;
}
return answ;
}
}
private bool OkVC19
{
get
{
bool answ = false;
if (DayDTO != null && DayDTO.ListCheckC19 != null)
{
answ = DayDTO.ListCheckC19.Count > 0;
}
return answ;
}
}
private Double oreComm
{
get
{
double answ = 0;
if (DayDTO != null && DayDTO.ListRA != null)
{
answ = (double)DayDTO.ListRA.Sum(x => x.OreTot);
}
return answ;
}
}
private Double oreLav
{
get
{
double answ = 0;
if (DayDTO != null && DayDTO.TimbrExpl != null && DayDTO.TimbrExpl.HLav != null)
{
answ = (double)DayDTO.TimbrExpl.HLav;
if (DayDTO.DtRif == DateTime.Today)
{
if (DayDTO.ListTimbr != null)
{
// aggiungo ultima timb fino ad adesso...
var lastIn = DayDTO.ListTimbr.Where(x => x.Entrata == true).OrderByDescending(x => x.DataOra).FirstOrDefault();
var lastOut = DayDTO.ListTimbr.Where(x => x.Entrata == false).OrderByDescending(x => x.DataOra).FirstOrDefault();
// se MANCA timb uscita finale...
if (lastIn != null)
{
if (lastOut == null || lastOut.DataOra < lastIn.DataOra)
{
DateTime adesso = DateTime.Now;
answ += adesso.Subtract(lastIn.DataOra).TotalHours;
}
}
}
}
}
return answ;
}
}
private int periodo
{
get
{
int answ = 1;
if (DayDTO != null)
{
answ = EndHour - StartHour;
}
return answ;
}
}
private decimal tempRil
{
get
{
decimal answ = 0;
if (OkTemp)
{
answ = DayDTO.ListRilTemp[0].TempRil;
}
return answ;
}
}
private string TotComm
{
get
{
TimeSpan tSpan = TimeSpan.FromHours(oreComm);
return $"{tSpan.Hours}h {tSpan.Minutes}'";
}
}
private string TotLav
{
get
{
TimeSpan tSpan = TimeSpan.FromHours(oreLav);
return $"{tSpan.Hours}h {tSpan.Minutes}'";
}
}
#endregion Private Properties
#region Public Properties
public string cssBadgeLav
{
get
{
string bCtr = "btn";
string answ = $"{bCtr}-light";
var deltaComm = oreComm - oreLav;
if (Math.Abs(deltaComm) < 0.5)
{
answ = $"{bCtr}-info";
}
else if (Math.Abs(deltaComm) < 1)
{
answ = $"{bCtr}-warning";
}
else
{
answ = $"{bCtr}-danger";
}
return answ;
}
}
public string cssCheck
{
get => OkVC19 ? "text-success" : "text-secondary";
}
public string cssThermo
{
get
{
string answ = "";
// verifico in base a ok temp o meno...
if (OkTemp)
{
// colore in base al valore...
var currTemp = tempRil;
if (currTemp != null)
{
if (currTemp >= (decimal)37.5)
{
answ = "text-danger";
}
else if (currTemp >= 37)
{
answ = "text-warning";
}
else
{
answ = "text-success";
}
}
}
else
{
answ = "text-secondary";
}
return answ;
}
}
[Parameter]
public DailyDataDTO? DayDTO { get; set; }
[Parameter]
public bool EnableActionMenu { get; set; } = true;
[Parameter]
public int EndHour { get; set; }
[Parameter]
public int IdxDipSel { get; set; } = 0;
[Parameter]
public bool IsTitle { get; set; } = false;
[Parameter]
public EventCallback<RegAttivitaModel> ItemSelected { get; set; }
[Parameter]
public EventCallback<RegAttivitaModel> ItemUpdated { get; set; }
[Parameter]
public List<AnagFasiModel> ListFasi { get; set; } = null!;
[Parameter]
public EventCallback<List<TimbratureModel>?> PeriodSelected { get; set; }
[Parameter]
public EventCallback<DateTime> ReqTempList { get; set; }
[Parameter]
public int StartHour { get; set; }
#endregion Public Properties
#region Private Methods
private List<CORE.Data.DbModels.RegAttivitaModel> ListRegAtt()
{
// init
DateTime currHour = DayDTO.DtRif.AddHours(StartHour);
DateTime lastHour = DayDTO.DtRif.AddHours(EndHour);
List<CORE.Data.DbModels.RegAttivitaModel> result = new List<CORE.Data.DbModels.RegAttivitaModel>();
// ciclo partendo dal primo evento ed aggiungendo eventuali periodi in testa / coda / intermedi
foreach (var item in DayDTO.ListRA)
{
// se evento > ora corrente --> aggiungo vuoto...
if (item.Inizio > currHour)
{
CORE.Data.DbModels.RegAttivitaModel? newItem = new CORE.Data.DbModels.RegAttivitaModel()
{
Inizio = currHour,
IdxFase = 0,
Descrizione = "-",
Fine = item.Inizio,
OreTot = (decimal)item.Inizio.Subtract(currHour).TotalHours
};
result.Add(newItem);
}
// ...altrimenti parto con lui...
result.Add(item);
currHour = item.Fine;
}
// se non sono in fondo --> aggiungo!
if (currHour < lastHour)
{
CORE.Data.DbModels.RegAttivitaModel? newItem = new CORE.Data.DbModels.RegAttivitaModel()
{
Inizio = currHour,
IdxFase = 0,
Descrizione = "-",
Fine = lastHour,
OreTot = (decimal)lastHour.Subtract(currHour).TotalHours
};
result.Add(newItem);
}
return result;
}
private List<PeriodoDTO> ListTimb()
{
// init
List<PeriodoDTO> result = new List<PeriodoDTO>();
if (DayDTO != null)
{
// limiti estremi visualizzazione
DateTime currHour = DayDTO.DtRif.AddHours(StartHour);
DateTime lastHour = DayDTO.DtRif.AddHours(EndHour);
int idxTimb = 0;
if (DayDTO.ListTimbr != null)
{
// divido tra ingressi e uscite
var timbIN = DayDTO.ListTimbr.Where(x => x.Entrata == true).ToList();
var timbOUT = DayDTO.ListTimbr.Where(x => x.Entrata == false).ToList();
DateTime fineLav = currHour;
// sistemo la prima timbratura
if (timbIN.Count > 0)
{
var firstRec = timbIN.OrderBy(x => x.DataOra).FirstOrDefault();
if (firstRec != null)
{
FirstTimb = CORE.Data.Utils.DateRounded(firstRec.DataOra, 5, false);
}
}
// ciclo partendo dal primo evento timbratura IN ed aggiungendo eventuali periodi in testa / coda / intermedi
foreach (var item in timbIN)
{
bool isClosed = true;
// se evento > ora corrente --> aggiungo vuoto...
if (item.DataOra > currHour)
{
PeriodoDTO emptyPeriod = new PeriodoDTO()
{
Inizio = currHour,
Fine = item.DataOra,
Tipo = CORE.Data.TipoPeriodo.ND,
OreTot = (decimal)item.DataOra.Subtract(currHour).TotalHours,
IsClosed = true
};
result.Add(emptyPeriod);
}
// ...processo cercando uscita relativa oppure NOW
if (timbOUT.Count > idxTimb)
{
fineLav = timbOUT[idxTimb].DataOra;
}
else
{
DateTime adesso = DateTime.Now;
int minRound = ((int)Math.Floor((double)adesso.Minute / 5)) * 5;
fineLav = DateTime.Today.AddHours(adesso.Hour).AddMinutes(minRound);
isClosed = false;
}
PeriodoDTO workPeriod = new PeriodoDTO()
{
Inizio = item.DataOra,
Fine = fineLav,
Tipo = CORE.Data.TipoPeriodo.Lavoro,
OreTot = (decimal)fineLav.Subtract(item.DataOra).TotalHours,
IsClosed = isClosed
};
result.Add(workPeriod);
idxTimb++;
currHour = fineLav;
}
// se non sono in fondo --> aggiungo!
if (currHour < lastHour)
{
PeriodoDTO emptyPeriod = new PeriodoDTO()
{
Inizio = currHour,
Fine = lastHour,
Tipo = CORE.Data.TipoPeriodo.ND,
OreTot = (decimal)lastHour.Subtract(currHour).TotalHours,
IsClosed = true
};
result.Add(emptyPeriod);
}
}
}
return result;
}
#endregion Private Methods
#region Protected Methods
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void PeriodoSelected(PeriodoDTO selPeriodo)
{
if (DayDTO != null)
{
await PeriodSelected.InvokeAsync(DayDTO.ListTimbr);
}
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void ReportCloned()
{
await ItemSelected.InvokeAsync(null);
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void ReportSelected(RegAttivitaModel selRecord)
{
await ItemSelected.InvokeAsync(selRecord);
}
/// <summary>
/// Indico item aggiornato
/// </summary>
protected async void ReportUpdated()
{
await ItemUpdated.InvokeAsync(null);
}
protected async void SelTemperature()
{
if (DayDTO != null)
{
await ReqTempList.InvokeAsync(DayDTO.DtRif);
}
}
protected async void SelTimbrature()
{
if (DayDTO != null)
{
await PeriodSelected.InvokeAsync(DayDTO.ListTimbr);
}
}
#endregion Protected Methods
}
}
-71
View File
@@ -1,71 +0,0 @@

<div class="d-flex">
<div class="px-2 flex-fill">
<label class="small">Gruppo</label>
<div class="input-group" title="Gruppo">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="far fa-object-group"></i>
</span>
</div>
<select @bind="@gruppoSel" class="form-control" title="Gruppo">
<option value="">--- Selezionare ---</option>
@foreach (var item in gruppiList)
{
<option value="@item.Gruppo">@item.DescrGruppo</option>
}
</select>
</div>
@if (!string.IsNullOrEmpty(gruppoSel))
{
<label class="small">Progetto</label>
<div class="input-group" title="Progetto">
<div class="input-group-prepend">
<span class="input-group-text" style="width:3em;">
<i class="fas fa-project-diagram"></i>
</span>
</div>
<select @bind="@idxProj" class="form-control bg-dark text-light text-left" title="Progetto">
@foreach (var item in projList)
{
<option value="@item.IdxProgetto">@item.ClienteNav.RagSociale | @item.NomeProj</option>
}
</select>
</div>
}
@if (idxProj > 0)
{
<label class="small">Fase</label>
<div class="input-group" title="Fase">
<div class="input-group-prepend">
<span class="input-group-text" style="width:3em;">
<i class="fas fa-tasks"></i>
</span>
</div>
<select @bind="@idxFase" class="form-control bg-primary text-light text-left" title="Fase">
@foreach (var item in fasiList)
{
if (@item.EnableTime)
{
<option value="@item.IdxFase">@item.NomeFase</option>
}
else
{
<option value="@item.IdxFase" disabled="disabled" class="text-warning">[@item.NomeFase]</option>
}
}
</select>
</div>
}
</div>
</div>
<div class="d-flex mt-2 flex-row-reverse">
<div class="px-2">
@if (idxFase > 0)
{
<button @onclick="() => SelectRecord()" class="btn btn-lg btn-block btn-success">Selezione Fase <i class="fas fa-arrow-alt-circle-right"></i></button>
}
</div>
</div>
-115
View File
@@ -1,115 +0,0 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.UI.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace GPW.CORE.UI.Components
{
public partial class FasiSearch
{
#region Protected Fields
protected string _gruppoSel = "";
protected int _idxProj = 0;
protected bool vetoUpd = false;
#endregion Protected Fields
#region Public Fields
public int idxFase = 0;
#endregion Public Fields
#region Private Properties
[Inject]
private MessageService AppMServ { get; set; }
[Inject]
private IJSRuntime JSRuntime { get; set; }
#endregion Private Properties
#region Protected Properties
protected List<AnagFasiModel> fasiList { get; set; } = new List<AnagFasiModel>();
[Inject]
protected GpwDataService GDataServ { get; set; }
protected List<AnagGruppiModel> gruppiList { get; set; } = new List<AnagGruppiModel>();
protected List<AnagProgettiModel> projList { get; set; } = new List<AnagProgettiModel>();
#endregion Protected Properties
#region Public Properties
public string gruppoSel
{
get
{
return _gruppoSel;
}
set
{
_gruppoSel = value;
if (!vetoUpd)
{
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
public int idxProj
{
get
{
return _idxProj;
}
set
{
_idxProj = value;
if (!vetoUpd)
{
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
[Parameter]
public EventCallback<int> ItemSelected { get; set; }
#endregion Public Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
protected async Task ReloadData()
{
gruppiList = await GDataServ.AnagGruppiAll();
var allProj = await GDataServ.AnagProjAll();
projList = allProj.Where(x => x.Attivo == true && x.Gruppo == gruppoSel).OrderBy(x => x.ClienteNav.RagSociale).ThenBy(x => x.NomeProj).ToList();
var allFasi = await GDataServ.AnagFasiAll();
fasiList = allFasi.Where(x => x.IdxProgetto == idxProj && x.Attivo == true).ToList();
}
protected async Task SelectRecord()
{
await ItemSelected.InvokeAsync(idxFase);
}
#endregion Protected Methods
}
}
-6
View File
@@ -1,6 +0,0 @@
<div class="row p-3 m-2">
<div class="col-12 text-center mt-5 py-5 alert alert-primary">
<h3>loading data</h3>
<i class="fas fa-spinner fa-spin fa-5x"></i>
</div>
</div>
@@ -1,6 +0,0 @@
<div class="row p-2 m-2">
<div class="col-12 text-center mt-2 py-2 alert alert-primary">
<b>loading data</b>
<i class="fas fa-spinner fa-spin fa-2x"></i>
</div>
</div>
-143
View File
@@ -1,143 +0,0 @@
@using GPW.CORE.Data.DbModels
@using CORE.Data.DbModels
@using UI.Data
@inject IJSRuntime JSRuntime
@inject GpwDataService GDataServ
@inject MessageService AppMServ
@if (ListRecords == null)
{
<LoadingData></LoadingData>
}
else
{
<table class="table table-sm table-striped table-responsive-md border border-dark">
<thead>
<tr class="bg-dark text-light">
<th>Progetto</th>
<th class="text-right">ore</th>
<th class="text-right">sel</th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
<tr class="@cssRiga(item.idxFase)">
<td>
<div class="d-flex">
<div class="px-2">
(@item.RowNum.ToString("00"))
</div>
<div class="px-2">
<b>@item.nomeProj</b> | @item.nomeComm - @item.nomeFase
</div>
</div>
</td>
<td class="text-right">@item.qty.ToString("N2")</td>
<td class="text-right"><button @onclick="() => SelectRecord(item.idxFase)" class="btn btn-sm btn-success"><i class="fas fa-arrow-alt-circle-right"></i></button></td>
</tr>
}
</tbody>
</table>
}
<div class="d-flex justify-content-between">
<div class="px-2">
<label class="small">giorni precedenti da considerare</label>
<div class="input-group input-group-sm mb-2">
<div class="input-group-prepend">
<span class="input-group-text"># days</span>
</div>
<input type="number" class="form-control text-right" placeholder="Giorni Precedenti" @bind-value="@ggPrec">
</div>
</div>
<div class="px-2">
<label class="small">Risultati Max</label>
<div class="input-group input-group-sm mb-2">
<div class="input-group-prepend">
<span class="input-group-text"># res</span>
</div>
<input type="number" class="form-control text-right" placeholder="Max Suggerimenti" @bind-value="@maxSugg">
</div>
</div>
</div>
@code {
private int _maxSugg = 10;
private int _ggPrec = 60;
private int idxFaseSel = 0;
[Parameter]
public EventCallback<int> ItemSelected { get; set; }
[Parameter]
public int idxFase
{
get
{
return idxFaseSel;
}
set
{
idxFaseSel = value;
}
}
private int maxSugg
{
get
{
return _maxSugg;
}
set
{
_maxSugg = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
private int ggPrec
{
get
{
return _ggPrec;
}
set
{
_ggPrec = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
protected List<ParetoRegAttModel>? ListRecords { get; set; } = null;
protected string cssRiga(int idxFase)
{
string answ = "";
if (idxFase == idxFaseSel)
{
answ = "bg-info text-light";
}
return answ;
}
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
protected async Task ReloadData()
{
idxFaseSel = 0;
ListRecords = await GDataServ.ParetoRegAtt(AppMServ.IdxDipendente, ggPrec, maxSugg);
}
protected async Task SelectRecord(int idxFase)
{
idxFaseSel = idxFase;
await ItemSelected.InvokeAsync(idxFase);
}
}
-80
View File
@@ -1,80 +0,0 @@
@using CORE.Data.DbModels
@using CORE.Data.DTO
@using UI.Data
@inject GpwDataService GDataServ
@inject MessageService AppMServ
@inject IJSRuntime JSRuntime
<div class="py-0 mb-1 flex-fill @blockCss" style="width: @widthPerc; font-size: 0.7em;">
@if (CurrPeriodo.Tipo != CORE.Data.TipoPeriodo.ND)
{
<div class="d-flex justify-content-between" @onclick="Edit">
<div class="px-1 bg-dark">
<span>@CurrPeriodo.Inizio.ToString("HH:mm")</span>
</div>
@if (CurrPeriodo.IsClosed)
{
@if ((double)CurrPeriodo.OreTot >= 1.25)
{
<div class="px-2 bg-dark">
<i class="far fa-calendar-alt"></i>
</div>
}
@if ((double)CurrPeriodo.OreTot >= 1)
{
<div class="px-1 bg-dark">
<span>@CurrPeriodo.Fine.ToString("HH:mm")</span>
</div>
}
}
else
{
<div class="px-1 bg-dark">
<span><i class="far fa-clock"></i></span>
</div>
}
</div>
}
</div>
@code {
[Parameter]
public PeriodoDTO CurrPeriodo { get; set; } = null!;
[Parameter]
public double Periodo { get; set; } = 1;
[Parameter]
public EventCallback<PeriodoDTO> ItemSelected { get; set; }
private string widthPerc
{
get
{
string answ = "1%";
if (CurrPeriodo != null)
{
double num = CurrPeriodo.OreTot != null ? (double)CurrPeriodo.OreTot : 0;
answ = $"{num / Periodo:P2}".Replace(",", ".");
}
return answ;
}
}
private string blockCss
{
get
{
string answ = CurrPeriodo.Tipo == CORE.Data.TipoPeriodo.ND ? "" : " border border-success bg-dark text-light rounded ";
return answ;
}
}
private async void Edit()
{
await ItemSelected.InvokeAsync(CurrPeriodo);
}
}
-275
View File
@@ -1,275 +0,0 @@
@using CORE.Data.DbModels
@using UI.Data
@inject IJSRuntime JSRuntime
@inject GpwDataService GDataServ
@inject MessageService AppMServ
@if (CalcOreFasi == null)
{
<LoadingDataSmall></LoadingDataSmall>
}
else
{
<div class="card border border-info">
<div class="card-header bg-info text-light py-1">
<div class="d-flex justify-content-between border border-top-0 border-left-0 border-right-0">
<div class="px-0">
<b>@currProj.Gruppo</b>
</div>
<div class="px-0">
<span>@currProj.ClienteNav.RagSociale</span>
</div>
</div>
<div class="d-flex justify-content-between">
<div class="px-0">
<span>@currProj.NomeProj</span>
</div>
</div>
</div>
<div class="card-body py-1">
<div class="d-flex justify-content-between">
<div class="px-0">
Budget: <b>@CalcOreFasi.budgetTime.ToString("N2")</b>
</div>
<div class="px-0 @cssCheckOre">
consumate: <b>@CalcOreFasi.percUsed.ToString("P1")</b>
</div>
</div>
<div class="d-flex justify-content-between">
<div class="px-0">
Caricate: <b>@CalcOreFasi.totOre.ToString("N2")</b>
</div>
<div class="px-0 @cssCheckOre">
rimanenti: <b>@CalcOreFasi.timeRem.ToString("N0")</b>
</div>
</div>
@if (!(bool)CalcOreFasi.Attivo || VetoProj)
{
if (VetoInsert)
{
<div class="alert alert-danger">
<b>Attenzione!</b>: impossibile caricare altre ore nel progetto, verificare l'attivazione e le ore a budget con amministrazione prima di procedere!
</div>
}
else
{
<div class="alert alert-warning">
<b>Attenzione!</b>: progetto inattivo: verificare con amministrazione prima di procedere!
</div>
}
}
</div>
</div>
<div class="card border border-info mt-1">
<div class="card-header bg-info text-light py-1">
@if (currFase != null)
{
<div class="d-flex justify-content-between">
<div class="px-0">
<b>@ancestFase.NomeFase</b>
</div>
<div class="px-0">
<span>@currFase.NomeFase</span>
</div>
</div>
}
</div>
<div class="card-body">
<div class="row">
<div class="col-6" title="Chiusura/prolungamento attività precedente all'avvio della nuova attività">
<label class="small">Consecutiva</label>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="switchClosePrec" @bind-value="@doClose" checked="@doClose">
<label class="custom-control-label" for="switchClosePrec">Chiudi</label>
</div>
</div>
<div class="col-6 text-right" title="Durata prevista attività (minuti)">
<label class="small">Durata Prevista</label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text">Min</span>
</div>
<input type="number" class="form-control text-right" placeholder="minuti" @bind-value="@minDur">
</div>
</div>
<div class="col-12" title="Descrizione di dettaglio attività">
<label class="small">Descrizione Attività</label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far fa-comment-alt"></i></span>
</div>
<input type="text" class="form-control text-right" placeholder="Inserire descrizione attività" @bind-value="@descrizione">
</div>
</div>
</div>
<div class="row">
<div class="col-6">
@if (AppMServ.PayloadOk)
{
if (CalcOreFasi != null)
{
if (buttonEnabled)
{
<button class="btn btn-lg btn-block btn-success" @onclick="() => StartRecord()"><i class="fas fa-play"></i> Start</button>
}
}
}
</div>
<div class="col-6">
<button class="btn btn-lg btn-block btn-warning" @onclick="() => ClosePage()"><i class="fas fa-ban"></i> Cancel</button>
</div>
</div>
</div>
</div>
}
@code {
private int _idxFase = 0;
private int idxProj = 0;
private int minDur = 30;
private bool doClose = true;
private string descrizione = "";
private string cssCheckOre = "";
private CalcOreFasiModel? CalcOreFasi { get; set; } = null;
private AnagFasiModel? currFase { get; set; } = null;
private AnagFasiModel? ancestFase { get; set; } = null;
private AnagProgettiModel? currProj { get; set; } = null;
[Parameter]
public int idxFase
{
get
{
return _idxFase;
}
set
{
_idxFase = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
[Parameter]
public EventCallback<bool> RecStarted { get; set; }
private bool buttonEnabled
{
get
{
bool answ = !VetoProj;
if (CalcOreFasi != null)
{
if (!(bool)CalcOreFasi.Attivo)
{
if (VetoInsert)
{
answ = false;
}
else
{
answ = true;
}
}
}
return answ;
}
}
private bool VetoInsert
{
get => GDataServ.VetoInsert;
}
private bool VetoProj
{
get
{
bool answ = false;
if (currProj != null)
{
var projAttivo = true;
_ = bool.TryParse($"{currProj.Attivo}", out projAttivo);
answ = !projAttivo;
}
return answ;
}
}
private async Task StartRecord()
{
// calcolo dataora chiusura...
DateTime newInizio = CORE.Data.Utils.DateRounded(DateTime.Now, 5, true);
// chiudo attività precedente (se c'è) odierna
if (doClose)
{
var lastRA = await GDataServ.RegAttLastByDip(AppMServ.IdxDipendente, false);
if (lastRA != null && lastRA.Inizio.Date == DateTime.Today)
{
lastRA.Fine = newInizio;
await GDataServ.RegAttUpdate(lastRA);
}
}
// registro nuova attività
RegAttivitaModel newItem = new RegAttivitaModel()
{
IdxDipendente = AppMServ.IdxDipendente,
Inizio = newInizio,
Fine = newInizio.AddMinutes(minDur),
IdxFase = idxFase,
Descrizione = descrizione
};
await GDataServ.RegAttUpdate(newItem);
// segnalo fatto
await RecStarted.InvokeAsync(false);
}
private async Task ClosePage()
{
await RecStarted.InvokeAsync(false);
}
protected async Task ReloadData()
{
// recupero dati fase completi...
currFase = await GDataServ.AnagFasiSearch(idxFase);
ancestFase = await GDataServ.AnagFasiSearch(currFase.IdxFaseAncest);
currProj = await GDataServ.AnagProjSearch((int)currFase.IdxProgetto);
if (currFase != null)
{
int idxFaseTgt = currFase.IdxFaseAncest == 0 ? currFase.IdxFase : currFase.IdxFaseAncest;
CalcOreFasi = await GDataServ.CalcOreFase(idxFaseTgt);
cssCheckOre = "text-success";
if (CalcOreFasi.percUsed > 1)
{
cssCheckOre = "text-danger";
}
else if (CalcOreFasi.percUsed * 100 > 80)
{
cssCheckOre = "text-warning";
}
//if (currFase.IdxProgetto != null)
//{
// int idxProj = (int)currFase.IdxProgetto;
// CalcOreProj = await GDataServ.CalcOreProj(idxProj);
// cssCheckOre = "text-success";
// if (CalcOreProj.percUsed > 1)
// {
// cssCheckOre = "text-danger";
// }
// else if (CalcOreProj.percUsed * 100 > 80)
// {
// cssCheckOre = "text-warning";
// }
//}
}
}
}
-92
View File
@@ -1,92 +0,0 @@
@using CORE.Data.DbModels
@using UI.Data
@inject GpwDataService GDataServ
@inject MessageService AppMServ
@inject IJSRuntime JSRuntime
<div class="py-0 small flex-fill @blockCss" style="width: @widthPerc">
<div class="d-flex">
@if (@CurrData.IdxFase > 0)
{
<div class="dropdown">
<button @onclick="() => Edit()" class="@buttonCss px-1 text-center border border-secondary border-top-0 border-bottom-0 border-left-0 btn btn-info btn-sm py-1" style="font-size: 0.72rem;" disabled="@(IsClipboard)">
@if (@CurrData.OreTot > 1)
{
<div>@CurrData.Inizio.ToString("HH:mm")</div>
<div>@CurrData.Fine.ToString("HH:mm")</div>
<div class="badge badge-dark">@($"{@CurrData.Durata.Hours}h {@CurrData.Durata.Minutes:00}'")</div>
}
else
{
<div>@CurrData.Inizio.ToString("HH")</div>
<div>@CurrData.Inizio.ToString("mm")</div>
<div class="badge badge-dark">@($"{CurrData.OreTot*60:N0}'")</div>
}
</button>
@if (!IsClipboard && EnableActionMenu)
{
<div class="@cssDropContent border border-dark table-dark text-light rounded p-2">
<div class="row">
<div class="col-12 pr-0">
<div class="text-light text-left"><b>@($"{CurrData.FasiNav?.ProgettoNav?.ClienteNav?.RagSociale}")</b> - <span class="textTrim max20Char" title="@CurrData.FasiNav?.ProgettoNav?.NomeProj">@($"{CurrData.FasiNav?.ProgettoNav?.NomeProj}")</span> | <span class="text-info text-left textTrim max20Char" title="@CurrData.FasiNav?.DescrizioneFase">@($"{CurrData.FasiNav?.DescrizioneFase}")</span></div>
<div class="text-warning text-left textTrim max30Char" title="@CurrData.Descrizione">@($"{CurrData.Descrizione}")</div>
</div>
</div>
@if (AppMServ.PayloadOk)
{
<div class="btn-group btn-group-sm w-100 py-2">
<button @onclick="() => Edit()" class="btn btn-sm btn-info"><i class="fas fa-pencil-alt"></i> Edit</button>
@if (!VetoInsert || CurrData.FasiNav.Attivo)
{
<button @onclick="() => Clone()" class="btn btn-sm btn-primary"><i class="far fa-copy"></i> Copy</button>
}
else
{
<span class="btn btn-sm btn-secondary disabled"><i class="far fa-copy"></i> Copy</span>
}
<button @onclick="() => Delete()" class="btn btn-sm btn-danger"><i class="fas fa-trash-alt"></i> Delete</button>
</div>
<div class="btn-group btn-group-sm w-100 small">
<button @onclick="() => AddTime(false,-120)" class="btn btn-sm btn-warning">-2h</button>
<button @onclick="() => AddTime(false,-60)" class="btn btn-sm btn-warning">-1h</button>
<button @onclick="() => AddTime(false,-30)" class="btn btn-sm btn-warning">-30'</button>
<button @onclick="() => AddTime(false,-15)" class="btn btn-sm btn-warning">-15'</button>
<span class="bg-dark text-light py-2" style="font-size: 1.3em; width: 4em;">@CurrData.Inizio.ToString("HH:mm")</span>
<button @onclick="() => AddTime(false,15)" class="btn btn-sm btn-success">+15'</button>
<button @onclick="() => AddTime(false,30)" class="btn btn-sm btn-success">+30'</button>
<button @onclick="() => AddTime(false,60)" class="btn btn-sm btn-success">+1h</button>
<button @onclick="() => AddTime(false,120)" class="btn btn-sm btn-success ">+2h</button>
</div>
<div class="btn-group btn-group-sm w-100 small mt-2">
<button @onclick="() => AddTime(true,-120)" class="btn btn-sm btn-outline-warning">-2h</button>
<button @onclick="() => AddTime(true,-60)" class="btn btn-sm btn-outline-warning">-1h</button>
<button @onclick="() => AddTime(true,-30)" class="btn btn-sm btn-outline-warning">-30'</button>
<button @onclick="() => AddTime(true,-15)" class="btn btn-sm btn-outline-warning">-15'</button>
<span class="bg-dark text-light py-2" style="font-size: 1.3em; width: 4em;">@CurrData.Fine.ToString("HH:mm")</span>
<button @onclick="() => AddTime(true,15)" class="btn btn-sm btn-outline-success">+15'</button>
<button @onclick="() => AddTime(true,30)" class="btn btn-sm btn-outline-success">+30'</button>
<button @onclick="() => AddTime(true,60)" class="btn btn-sm btn-outline-success">+1h</button>
<button @onclick="() => AddTime(true,120)" class="btn btn-sm btn-outline-success">+2h</button>
</div>
}
</div>
}
</div>
<div class="px-1 py-0 text-left textTrim flex-fill">
<div class="text-dark" title="@CurrData.FasiNav?.ProgettoNav?.ClienteNav?.RagSociale - @CurrData.FasiNav?.ProgettoNav?.NomeProj"><b>@(trimLine($"{CurrData.FasiNav?.ProgettoNav?.ClienteNav?.RagSociale}",65))</b> - @(trimLine($"{CurrData.FasiNav?.ProgettoNav?.NomeProj}",75))</div>
<div class="text-secondary" title="@CurrData.FasiNav?.DescrizioneFase">@(trimLine($"{CurrData.FasiNav?.DescrizioneFase}",130))</div>
<div class="small" title="@CurrData.Descrizione">@(trimLine($"{CurrData.Descrizione}",250))</div>
</div>
}
else
{
<div class="px-1 small textTrim">
<AddRA IdxDip="@IdxDipSel" NewItemCreated="ReportSelect" InizioPer="@CurrData.Inizio" EnableAction="@EnableActionMenu"></AddRA>
</div>
}
</div>
</div>
-244
View File
@@ -1,244 +0,0 @@
using GPW.CORE.Data.DbModels;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace GPW.CORE.UI.Components
{
public partial class RegAtt
{
#region Protected Fields
protected bool isSelected = false;
#endregion Protected Fields
#region Private Properties
private string blockCss
{
get
{
string answ = CurrData.IdxFase == 0 ? "" : " border border-info rounded";
return answ;
}
}
private bool dropActionTop
{
get
{
bool answ = false;
switch (CurrData.Inizio.DayOfWeek)
{
case DayOfWeek.Sunday:
case DayOfWeek.Saturday:
case DayOfWeek.Friday:
answ = true;
break;
default:
break;
}
return answ;
}
}
private string widthPerc
{
get
{
string answ = "1%";
if (CurrData != null)
{
double num = CurrData.OreTot != null ? (double)CurrData.OreTot : 0;
answ = $"{num / Periodo:P2}".Replace(",", ".");
}
return answ;
}
}
private bool VetoInsert
{
get => GDataServ.VetoInsert;
}
#endregion Private Properties
#region Protected Properties
protected string buttonCss
{
get => !IsClipboard ? "dropbtn" : "";
}
protected string cssSelected
{
get => isSelected ? "table-info" : "";
}
protected string cssDropContent
{
get => dropActionTop ? "dropdown-content-top" : "dropdown-content";
}
#endregion Protected Properties
#region Public Properties
[Parameter]
public RegAttivitaModel CurrData { get; set; } = null!;
[Parameter]
public bool EnableActionMenu { get; set; } = true;
[Parameter]
public int IdxDipSel { get; set; } = 0;
[Parameter]
public bool IsClipboard { get; set; } = false;
[Parameter]
public EventCallback<RegAttivitaModel> ItemCloned { get; set; }
[Parameter]
public EventCallback<RegAttivitaModel> ItemSelected { get; set; }
[Parameter]
public EventCallback<RegAttivitaModel> ItemUpdated { get; set; }
[Parameter]
public List<AnagFasiModel> ListFasi { get; set; } = null!;
[Parameter]
public double Periodo { get; set; } = 1;
#endregion Public Properties
#region Private Methods
/// <summary>
/// Verifico coerenza date (inizio < fine)
/// </summary>
/// <param name="modInizio">indica se la data modificata sia l'inizio</param>
private void checkCoerenzaDate(bool modInizio)
{
// verifica presenza errori
bool inError = CurrData.Inizio >= CurrData.Fine;
if (inError)
{
// se ho mod inizio --> tengo ferma fine, inizio 1/2 h prima
if (modInizio)
{
CurrData.Inizio = CurrData.Fine.AddMinutes(-30);
}
else
{
CurrData.Fine = CurrData.Inizio.AddMinutes(30);
}
}
}
#endregion Private Methods
#region Protected Methods
protected async void AddTime(bool isEnd, int deltaMin)
{
// verifico checkbox IsEnd
if (isEnd)
{
// modifico fine...
CurrData.Fine = CurrData.Fine.AddMinutes(deltaMin);
checkCoerenzaDate(false);
}
else
{
// modifico inizio...
CurrData.Inizio = CurrData.Inizio.AddMinutes(deltaMin);
checkCoerenzaDate(true);
}
// salvo
await GDataServ.RegAttUpdate(CurrData);
await ItemUpdated.InvokeAsync(CurrData);
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void Clone()
{
AppMServ.clonedRA = CurrData;
await ItemCloned.InvokeAsync(CurrData);
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void Delete()
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare il record selezionato??"))
return;
// aggiorno
await GDataServ.RegAttDelete(CurrData);
// registro fatto
await ItemUpdated.InvokeAsync(null);
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void Edit()
{
// SOLO SE non è una copia clipboard...
//if (!IsClipboard)
//{
isSelected = true;
await ItemSelected.InvokeAsync(CurrData);
//}
}
protected override void OnInitialized()
{
isSelected = false;
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void ReportSelect(RegAttivitaModel selRecord)
{
await ItemSelected.InvokeAsync(selRecord);
}
/// <summary>
/// Trim linea di testo secondo regole
/// </summary>
/// <param name = "stringOrig">Stringa origiale</param>
/// <param name = "multFact">Fattore di moltiplicazione (std: 130)</param>
/// <returns></returns>
protected string trimLine(object stringOrig, int multFact = 130)
{
double num = 1;
if (CurrData.OreTot != null)
{
num = (double)CurrData.OreTot;
}
double perc = num / Periodo;
int maxLenght = (int)(perc * multFact);
string answ = $"{stringOrig}";
if (answ.Length > maxLenght)
{
answ = $"{answ.Substring(0, maxLenght)}...";
}
return answ;
}
#endregion Protected Methods
}
}
-140
View File
@@ -1,140 +0,0 @@
@using CORE.Data.DbModels
@using UI.Data
<EditForm Model="@currRecord">
<div class="card">
<div class="card-header bg-info">
<div class="row">
<div class="col-8">
<h4>Modifica # <b>@currRecord.IdxRa</b></h4>
</div>
<div class="col-4 text-right">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="far fa-object-group"></i>
</span>
</div>
<InputSelect @bind-Value="@gruppoSel" class="form-control" 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-6">
<label class="small">Progetto</label>
<div class="input-group" title="Progetto">
<div class="input-group-prepend">
<span class="input-group-text" style="width:3em;">
<i class="fas fa-project-diagram"></i>
</span>
</div>
<InputSelect @bind-Value="@idxProj" class="form-control bg-dark text-light text-left" 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" title="Fase">
<div class="input-group-prepend">
<span class="input-group-text" style="width:3em;">
<i class="fas fa-tasks"></i>
</span>
</div>
<InputSelect @bind-Value="@currRecord.IdxFase" class="form-control bg-light text-left" 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>
<div class="col-6 px-0">
<label class="small">Periodo (arr 5 min)</label>
<div class="d-flex justify-content-between">
<div class="px-0">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="fas fa-play"></i>
</span>
</div>
<input type="datetime-local" @bind="@currRecord.Inizio" style="width: 12rem;"></input>
</div>
</div>
<div class="px-0">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="fas fa-stop"></i>
</span>
</div>
<input type="datetime-local" @bind="@currRecord.Fine" style="width: 12rem;"></input>
</div>
</div>
</div>
<label class="small">Descrizione</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="far fa-comment-alt"></i>
</span>
</div>
<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-4">
@if (AppMServ.PayloadOk)
{
<button type="button" class="btn btn-block btn-success" @onclick="DoUpdate"><i class="fas fa-check-circle"></i> Save</button>
}
</div>
<div class="col-4">
</div>
<div class="col-4">
<button type="button" class="btn btn-block btn-warning" @onclick="DoReset"><i class="fas fa-ban"></i> Cancel</button>
</div>
</div>
</div>
</div>
</EditForm>
@@ -1,211 +0,0 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.UI.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace GPW.CORE.UI.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; }
[Inject]
private IJSRuntime JSRuntime { get; set; }
private bool VetoInsert
{
get => GDataServ.VetoInsert;
}
#endregion Private Properties
#region Protected Properties
protected List<AnagFasiModel> fasiList { get; set; } = new List<AnagFasiModel>();
[Inject]
protected GpwDataService GDataServ { get; set; }
protected List<AnagGruppiModel> gruppiList { get; set; } = new List<AnagGruppiModel>();
protected List<AnagProgettiModel> projList { get; set; } = new List<AnagProgettiModel>();
#endregion Protected Properties
#region Public Properties
[Parameter]
public RegAttivitaModel currRecord
{
get
{
return AppMServ.recordRA;
}
set
{
AppMServ.recordRA = value;
vetoUpd = true;
if (value.FasiNav != null && value.FasiNav.ProgettoNav != null)
{
gruppoSel = value.FasiNav.ProgettoNav.Gruppo;
idxProj = value.FasiNav.IdxProgetto != null ? (int)value.FasiNav.IdxProgetto : 0;
}
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
vetoUpd = false;
}
}
public string gruppoSel
{
get
{
return _gruppoSel;
}
set
{
_gruppoSel = value;
if (!vetoUpd)
{
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
public int idxProj
{
get
{
return _idxProj;
}
set
{
_idxProj = value;
if (!vetoUpd)
{
var pUpd = Task.Run(async () => await ReloadData());
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()
{
// 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)
{
// verifica presenza errori
bool 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()
{
AppMServ.clonedRA = currRecord;
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;
// aggiorno
await GDataServ.RegAttDelete(currRecord);
// registro fatto
await ItemUpdated.InvokeAsync(true);
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void DoReset()
{
await ItemReset.InvokeAsync(true);
}
/// <summary>
/// Aggiorno e riporto update
/// </summary>
protected async void DoUpdate()
{
arrotondaMinuti();
// aggiorno
await GDataServ.RegAttUpdate(currRecord);
// resetto clone e record corrente...
AppMServ.clonedRA = null;
// registro fatto
await ItemUpdated.InvokeAsync(true);
}
protected async Task ReloadData()
{
gruppiList = await GDataServ.AnagGruppiAll();
var allProj = await GDataServ.AnagProjAll();
projList = allProj
.Where(x => x.Attivo == true && x.Gruppo == gruppoSel)
.OrderBy(x => x.ClienteNav.RagSociale)
.ThenBy(x => x.NomeProj)
.ToList();
var allFasi = await GDataServ.AnagFasiAll();
fasiList = allFasi
.Where(x => x.IdxProgetto == idxProj)
.ToList();
}
#endregion Protected Methods
}
}
-45
View File
@@ -1,45 +0,0 @@
<h3>Test</h3>
@*Vedere link
https://www.dallaskostna.ca/2021/03/13/scalable-vector-graphics-svg-and-blazor/
*@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1056" height="150" stroke="#000" stroke-linecap="round" stroke-linejoin="round" fill="#fff" fill-rule="evenodd">
<defs>
<linearGradient id="A" x1="-3.60%" y1="-33.86%" x2="61.76%" y2="68.40%">
<stop offset="0%" stop-color="#efefef" />
<stop offset="100%" stop-color="#b4b4b4" />
</linearGradient>
</defs>
<g class="B C">
<path d="M.2-.5h214.3v150H.2z" fill="url(#A)" />
<path d="M11.5 50H61v71.6H11.5z" />
</g>
<path d="M36.3 52.4H13.8v67h45v-67z" class="@testclass1" @onclick="test1" />
<path d="M17.7-.5h.2l-.2 47.8zM56-.5h.2L56 47.3z" fill="gray" class="B C" />
<path d="M67.7 50H147v71.6H67.7z" class="@testclass2" @onclick="test2" />
<g class="B C">
<path d="M74.2-.5h.2l-.2 47.8zm66 0h.2l-.2 47.8z" fill="gray" />
<path d="M153 50h49.6v71.6H153z" />
</g>
<path d="M177.8 52.4h-22.5v67h45v-67z" class="@testclass3" @onclick="test3" />
<path d="M159-.5h.2l-.2 47.8zm38.4 0h.2l-.2 47.8z" fill="gray" class="B C" />
</svg>
@code {
string testclass1 = "regionnotclicked";
string testclass2 = "regionnotclicked";
string testclass3 = "regionnotclicked";
private void test1()
{
testclass1 = "regionclicked";
}
private void test2()
{
testclass2 = "regionclicked";
}
private void test3()
{
testclass3 = "regionclicked";
}
}
-83
View File
@@ -1,83 +0,0 @@
@using CORE.Data.DbModels
@using UI.Data
@inject IJSRuntime JSRuntime
@inject GpwDataService GDataServ
@inject MessageService AppMServ
<table class="table table-sm table-striped table-responsive-md">
<thead>
<tr>
<th><i class="far fa-clock"></i></th>
<th title="Entrata"><i class="fas fa-sign-in-alt"></i></th>
<th>Scambio</th>
<th title="Uscita"><i class="fas fa-sign-out-alt"></i></th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListTimb)
{
<tr>
<td class="small">@item.DataOra.ToString("dd/MM - HH:mm")</td>
<td title="Entrata">
@if (@item.Entrata == true)
{
<i class="fas fa-times"></i>
}
</td>
<td>
<button class="btn btn-sm btn-primary" title="Scambio IN/OUT" @onclick="() => ScambioInOut(item)"><i class="fas fa-exchange-alt"></i></button>
</td>
<td title="Uscita">
@if (@item.Entrata == false)
{
<i class="fas fa-times"></i>
}
</td>
<td>
<button class="btn btn-sm btn-danger" @onclick="() => Delete(item)"><i class="fas fa-trash-alt"></i></button>
</td>
</tr>
}
</tbody>
</table>
@code {
private List<TimbratureModel> _ListTimb { get; set; } = new List<TimbratureModel>();
[Parameter]
public List<TimbratureModel> ListTimb
{
get
{
return _ListTimb.OrderByDescending(x => x.DataOra).ToList();
}
set
{
_ListTimb = value;
InvokeAsync(() =>
{
StateHasChanged();
});
}
}
[Parameter]
public EventCallback<TimbratureModel> ReqDelete { get; set; }
[Parameter]
public EventCallback<TimbratureModel> ReqUpdate { get; set; }
protected async void Delete(TimbratureModel currRecord)
{
await ReqDelete.InvokeAsync(currRecord);
}
protected async void ScambioInOut(TimbratureModel currRecord)
{
await ReqUpdate.InvokeAsync(currRecord);
}
}
-84
View File
@@ -1,84 +0,0 @@
@using CORE.Data.DbModels
@using UI.Data
<div class="card">
<div class="card-header bg-dark text-light py-1">
<div class="row">
<div class="col-8">
<h4>Timbrature</h4>
</div>
<div class="col-4 py-1">
<button type="button" class="btn btn-block btn-warning py-1" @onclick="DoClose"><i class="fas fa-times"></i> Chiudi</button>
</div>
</div>
</div>
<div class="card-body text-center">
<div class="row">
<div class="col-4">
<div class="card">
<div class="card-header p-0">
<div class="table-success p-2">
Timbrature Approvate
</div>
</div>
<div class="card-body p-0">
@if (ListTimbAppr != null)
{
<TimbList ListTimb="@ListTimbAppr" ReqDelete="DoDelete" ReqUpdate="DoUpdate"></TimbList>
}
else
{
<LoadingDataSmall></LoadingDataSmall>
}
</div>
</div>
</div>
<div class="col-4">
<div class="card">
<div class="card-header p-0">
<div class="table-warning p-2">
Mancate timbrature
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-12 py-2">
<input type="datetime-local" @bind="@DataRif"></input>
</div>
<div class="col-6">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="switchEntrata" checked="@IsUscita" title="Ingresso /Uscrita" @bind-value="@IsUscita"> <label class="custom-control-label small" for="switchEntrata">@txtMsgInOut</label>
</div>
</div>
<div class="col-6">
<button @onclick="DoAdd" class="btn btn-block btn-sm btn-primary"><i class="fas fa-calendar-plus"></i></button>
</div>
</div>
</div>
</div>
</div>
<div class="col-4">
<div class="card">
<div class="card-header p-0">
<div class="table-info p-2">
Richieste in corso
</div>
</div>
<div class="card-body p-0">
@if (ListTimbRich != null)
{
<TimbList ListTimb="@ListTimbRich" ReqDelete="DoDelete" ReqUpdate="DoUpdate"></TimbList>
}
else
{
<LoadingDataSmall></LoadingDataSmall>
}
</div>
</div>
</div>
</div>
</div>
</div>
-187
View File
@@ -1,187 +0,0 @@
using GPW.CORE.Data.DbModels;
using GPW.CORE.UI.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace GPW.CORE.UI.Components
{
public partial class TimbrEditor
{
#region Protected Fields
protected bool vetoUpd = false;
#endregion Protected Fields
#region Private Properties
[Inject]
private MessageService AppMServ { get; set; }
[Inject]
private IHttpContextAccessor httpContextAccessor { get; set; }
[Inject]
private IJSRuntime JSRuntime { get; set; }
#endregion Private Properties
#region Protected Properties
[Inject]
protected GpwDataService GDataServ { get; set; }
protected bool IsUscita { get; set; } = false;
protected List<TimbratureModel>? ListTimbAppr { get; set; }
protected List<TimbratureModel>? ListTimbRich { get; set; }
protected string txtMsgInOut
{
get => IsUscita ? "Uscita" : "Entrata";
}
#endregion Protected Properties
#region Public Properties
[Parameter]
public EventCallback<bool> CloseReq { get; set; }
[Parameter]
public DateTime DataRif { get; set; }
[Parameter]
public EventCallback<bool> ItemReset { get; set; }
[Parameter]
public EventCallback<bool> ItemUpdated { get; set; }
[Parameter]
public List<TimbratureModel> ListTimb { get; set; } = new List<TimbratureModel>();
#endregion Public Properties
#region Private Methods
private async Task ReloadData()
{
DateTime adesso = DateTime.Now;
ListTimb = (ListTimb == null) ? new List<TimbratureModel>() : ListTimb;
// prendo primo record timbrature o oggi...
if (ListTimb.Count > 0)
{
DataRif = ListTimb.FirstOrDefault().DataOra.Date.AddHours(adesso.Hour).AddMinutes(Math.Ceiling((double)adesso.Minute / 5) * 5);
}
else
{
DataRif = DateTime.Today.AddHours(adesso.Hour).AddMinutes(Math.Ceiling((double)adesso.Minute / 5) * 5);
}
await Task.Delay(1);
if (ListTimb != null)
{
ListTimbAppr = ListTimb.Where(x => x.Approv == true).OrderByDescending(x => x.DataOra).ToList();
ListTimbRich = ListTimb.Where(x => x.Approv == false).OrderByDescending(x => x.DataOra).ToList();
}
}
#endregion Private Methods
#region Protected Methods
protected async void DoAdd()
{
var remoteIp = httpContextAccessor.HttpContext.Connection?.RemoteIpAddress.ToString();
TimbratureModel currRecord = new TimbratureModel()
{
Entrata = !IsUscita,
Approv = false,
CodTipoTimb = "NoTim",
DataOra = DataRif,
IdxDipendente = AppMServ.IdxDipendente,
Ipv4 = $"{remoteIp}"
};
// aggiungo alla lista...
ListTimb.Add(currRecord);
ListTimbRich.Add(currRecord);
// aggiorno
await GDataServ.TimbratureUpdate(currRecord);
await Task.Delay(10);
await ReloadData();
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void DoClose()
{
await CloseReq.InvokeAsync(true);
}
/// <summary>
/// Aggiorno e riporto update
/// </summary>
protected async void DoDelete(TimbratureModel currRecord)
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler eliminare la richiesta selezionata??"))
return;
// elimino dalla lista...
ListTimb.Remove(currRecord);
if (ListTimbAppr.Contains(currRecord))
{
ListTimbAppr.Remove(currRecord);
}
if (ListTimbRich.Contains(currRecord))
{
ListTimbRich.Remove(currRecord);
}
// aggiorno
await GDataServ.TimbratureDelete(currRecord);
await Task.Delay(10);
await ReloadData();
await ItemUpdated.InvokeAsync(true);
}
/// <summary>
/// Aggiorno e riporto update
/// </summary>
protected async void DoUpdate(TimbratureModel currRecord)
{
// elimino da lista
ListTimb.Remove(currRecord);
// scambio
currRecord.Entrata = !currRecord.Entrata;
// aggiorno
await GDataServ.TimbratureUpdate(currRecord);
// ri-aggiungo in lista...
ListTimb.Add(currRecord);
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
#endregion Protected Methods
}
}
-5
View File
@@ -1,5 +0,0 @@
<h3>WeekPlanner</h3>
@code {
}
-72
View File
@@ -1,72 +0,0 @@
@using CORE.Data.DbModels
@using UI.Data
@inject MessageService AppMServ
<div class="card">
<div class="card-header bg-dark text-light py-1">
<div class="row">
<div class="col-6">
<h4>Selezione Data Riferimento</h4>
</div>
<div class="col-6 text-right">
Selezionare la data desiderata
</div>
</div>
</div>
<div class="card-body text-center">
<div class="row">
<div class="col-6">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">Data Target</span>
</div>
<input type="date" class="form-control" placeholder="Data ultima" @bind-value="@TargetDate">
</div>
</div>
<div class="col-3">
<button type="button" class="btn btn-sm btn-block btn-success py-1" @onclick="DoSelection"><i class="fas fa-check"></i> Conferma</button>
</div>
<div class="col-3">
<button type="button" class="btn btn-sm btn-block btn-warning py-1" @onclick="DoClose"><i class="fas fa-times"></i> Chiudi</button>
</div>
</div>
</div>
</div>
@code {
[Parameter]
public EventCallback<bool> CloseReq { get; set; }
[Parameter]
public EventCallback<bool> WeekSelected { get; set; }
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void DoClose()
{
await CloseReq.InvokeAsync(true);
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void DoSelection()
{
await WeekSelected.InvokeAsync(true);
}
protected DateTime TargetDate
{
get
{
return AppMServ.targetDate;
}
set
{
AppMServ.targetDate = value;
}
}
}
-164
View File
@@ -1,164 +0,0 @@
@using GPW.CORE.Data
<div class="card text-center">
<div class="card-header p-0">
<button class="btn btn-block @selStyle text-light py-1" @onclick="reportSelect">
<div class="d-flex justify-content-between">
<div class="py-0 px-1">
<sub>@currData?.Inizio.ToString("ddd dd.MM")</sub>
</div>
<div class="py-0 px-1">
W <b>@currData?.WeekNumber.ToString("00")</b><sub>/@currData?.Anno</sub>
</div>
<div class="py-0 px-1">
<sub>@currData?.Fine.ToString("ddd dd.MM")</sub>
</div>
</div>
</button>
</div>
<div class="card-body p-1">
<div class="row">
<div class="col-6 pr-1">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
</div>
<span class="form-control disabled text-dark" title="Ore Lavorate"><b>@currData?.SumOreLav.ToString("N2")</b></span>
</div>
</div>
<div class="col-6 pl-1">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far fa-hourglass"></i></span>
</div>
<span class="form-control disabled text-info" title="Ore Caricate"><b>@currData?.SumOreComm.ToString("N2")</b></span>
</div>
</div>
<div class="col-12">
<div class="progress" style="height: .75em;">
<div class="progress-bar bg-dark" style="@styleLav"></div>
</div>
<div class="progress" style="height: .75em;">
<div class="progress-bar bg-info" style="@styleCom"></div>
</div>
</div>
</div>
</div>
</div>
@code {
public class WeekArg
{
public int Year { get; set; }
public int Week { get; set; }
}
[Parameter]
public CORE.Data.DTO.WeekStatDTO? currData { get; set; }
[Parameter]
public int WeekSel { get; set; } = 0;
[Parameter]
public EventCallback<WeekData> weekSelected { get; set; }
protected int currWeekNum
{
get
{
int answ = 0;
if (currData != null)
{
answ = currData.WeekNumber;
}
return answ;
}
}
protected int currYearNum
{
get
{
int answ = 0;
if (currData != null)
{
answ = currData.Anno;
}
return answ;
}
}
protected void reportSelect()
{
weekSelected.InvokeAsync(new WeekData(currYearNum, currWeekNum));
}
protected string selStyle
{
get
{
string currCss = "bg-secondary";
if (currData != null)
{
currCss = currData.WeekNumber == WeekSel ? "btn-primary" : "btn-secondary";
}
return currCss;
}
}
protected double denom
{
get
{
double answ = 40;
// cerco massimo tra ore lav e commesse...
if (currData.SumOreLav > answ)
{
answ = currData.SumOreLav;
}
if (currData.SumOreComm > answ)
{
answ = currData.SumOreComm;
}
return answ;
}
}
protected string styleLav
{
get
{
double valPerc = 0;
if (currData != null)
{
try
{
valPerc = currData.SumOreLav / denom;
}
catch
{ }
}
return $"width: {valPerc:P0};";
}
}
protected string styleCom
{
get
{
double valPerc = 0;
if (currData != null)
{
try
{
valPerc = currData.SumOreComm / denom;
}
catch
{ }
}
return $"width: {valPerc:P0};";
}
}
}
-783
View File
@@ -1,783 +0,0 @@
using GPW.CORE.Data.DbModels;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using NLog;
using System.Diagnostics;
using System.Text;
namespace GPW.CORE.UI.Data
{
public class GpwDataService : IDisposable
{
#region Private Fields
private static IConfiguration _configuration = null!;
private static ILogger<GpwDataService> _logger = null!;
private static JsonSerializerSettings? JSSettings;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
//private readonly IEmailSender _emailSender;
//private readonly UserManager<IdentityUser> _userManager;
private readonly IDistributedCache distributedCache;
private readonly IMemoryCache memoryCache;
private List<string> cachedDataList = new List<string>();
/// <summary>
/// Durata assoluta massima della cache IN SECONDI
/// </summary>
private int chAbsExp = 60 * 5;
/// <summary>
/// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa
/// NON estende oltre il tempo massimo di validità della cache (chAbsExp)
/// </summary>
private int chSliExp = 60 * 1;
#endregion Private Fields
#region Protected Fields
protected const string rKeyAKV = "Cache:AKV";
protected const string rKeyCalcOreFase = "Cache:CalcOreFase";
protected const string rKeyCalcOreProj = "Cache:CalcOreProj";
protected const string rKeyCliAll = "Cache:CliAll";
protected const string rKeyDailyData = "Cache:DailyData";
protected const string rKeyDipendenti = "Cache:Dipendenti";
protected const string rKeyFasiAll = "Cache:FasiAll";
protected const string rKeyGrpAll = "Cache:GrpAll";
protected const string rKeyParetoRegAtt = "Cache:ParetoRegAtt";
protected const string rKeyProjAll = "Cache:ProjAll";
protected const string rKeyRilTemp = "Cache:RilTemp";
protected const string rKeyVC19 = "Cache:VC19";
protected const string rKeyVetoIns = "Cache:VetoInsert";
protected const string rKeyWeekStats = "Cache:WeekStats";
protected static string connStringBBM = "";
#endregion Protected Fields
#region Public Fields
public static CORE.Data.Controllers.GPWController dbController = null!;
public bool VetoInsert = false;
#endregion Public Fields
#region Public Constructors
public GpwDataService(IConfiguration configuration, ILogger<GpwDataService> logger, IMemoryCache memoryCache, IDistributedCache distributedCache)
{
_logger = logger;
_configuration = configuration;
// conf cache
this.memoryCache = memoryCache;
this.distributedCache = distributedCache;
// json serializer...
// FIX errore loop circolare
// https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/
JSSettings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
// cod app
CodApp = _configuration["CodApp"];
var strVeto = _configuration["VetoIns"];
_ = bool.TryParse(strVeto, out VetoInsert);
// conf DB
string connStr = _configuration.GetConnectionString("GPW.DB");
if (string.IsNullOrEmpty(connStr))
{
_logger.LogError("ConnString empty!");
}
else
{
dbController = new CORE.Data.Controllers.GPWController(configuration);
}
}
#endregion Public Constructors
#region Public Properties
public string CodApp { get; set; } = "";
#endregion Public Properties
#region Private Methods
private DistributedCacheEntryOptions cacheOpt(bool fastCache)
{
var numSecAbsExp = fastCache ? chAbsExp : chAbsExp * 10;
var numSecSliExp = fastCache ? chSliExp : chSliExp * 10;
return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp));
}
private DistributedCacheEntryOptions cacheOpt(int multFact)
{
var numSecAbsExp = chAbsExp * multFact;
var numSecSliExp = chSliExp * multFact;
return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp));
}
#endregion Private Methods
#region Protected Methods
/// <summary>
/// Registra in cache chiave se non fosse già in elenco
/// </summary>
/// <param name="newKey"></param>
protected void trackCache(string newKey)
{
if (!cachedDataList.Contains(newKey))
{
cachedDataList.Add(newKey);
}
}
#endregion Protected Methods
#region Public Methods
/// <summary>
/// Elenco AKV
/// </summary>
public async Task<List<AnagKeyValueModel>> AKVList()
{
List<AnagKeyValueModel> dbResult = new List<AnagKeyValueModel>();
// cerco da cache
string currKey = rKeyAKV;
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<AnagKeyValueModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.AnagKeyValGetAll();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(500));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per AKVList: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<AnagKeyValueModel>();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco fasi (tutte)
/// </summary>
/// <returns></returns>
public async Task<List<AnagClientiModel>> AnagClientiAll()
{
List<AnagClientiModel>? dbResult = new List<AnagClientiModel>();
string currKey = $"{rKeyCliAll}";
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<AnagClientiModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.AnagClientiAll();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per AnagClientiAll: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<AnagClientiModel>();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco fasi (tutte)
/// </summary>
/// <returns></returns>
public async Task<List<AnagFasiModel>> AnagFasiAll()
{
List<AnagFasiModel>? dbResult = new List<AnagFasiModel>();
string currKey = $"{rKeyFasiAll}";
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<AnagFasiModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.AnagFasiAll(false);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per AnagFasiAll: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<AnagFasiModel>();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera info x una specifica FASE
/// </summary>
/// <returns></returns>
public async Task<AnagFasiModel?> AnagFasiSearch(int idxFase)
{
AnagFasiModel dbResult = new AnagFasiModel();
var rawData = await AnagFasiAll();
if (rawData != null)
{
dbResult = rawData.FirstOrDefault(x => x.IdxFase == idxFase);
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco gruppi (tutti)
/// </summary>
/// <returns></returns>
public async Task<List<AnagGruppiModel>> AnagGruppiAll()
{
List<AnagGruppiModel>? dbResult = new List<AnagGruppiModel>();
string currKey = $"{rKeyGrpAll}";
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<AnagGruppiModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.AnagGruppiAll();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per AnagGruppiAll: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<AnagGruppiModel>();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco progetti (tutti)
/// </summary>
/// <returns></returns>
public async Task<List<AnagProgettiModel>> AnagProjAll()
{
List<AnagProgettiModel>? dbResult = new List<AnagProgettiModel>();
string currKey = $"{rKeyProjAll}";
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<AnagProgettiModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.AnagProjAll(false);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per AnagProjAll: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<AnagProgettiModel>();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera info x uno specifico PROJ
/// </summary>
/// <returns></returns>
public async Task<AnagProgettiModel?> AnagProjSearch(int idxProj)
{
AnagProgettiModel dbResult = new AnagProgettiModel();
var rawData = await AnagProjAll();
if (rawData != null)
{
dbResult = rawData.FirstOrDefault(x => x.IdxProgetto == idxProj);
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Vista dati per FASE (tipicamente master...) con totalizzaizone ore budget/real e stato fase
/// </summary>
/// <param name="idxFase"></param>
/// <returns></returns>
public async Task<CalcOreFasiModel> CalcOreFase(int idxFase)
{
CalcOreFasiModel? dbResult = new CalcOreFasiModel();
string currKey = $"{rKeyCalcOreFase}:{idxFase}";
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<CalcOreFasiModel>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.CalcOreFase(idxFase);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per CalcOreFase: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new CalcOreFasiModel();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Vista dati per progetto con totalizzaizone ore budget/real
/// </summary>
/// <param name="idxProj"></param>
/// <returns></returns>
public async Task<CalcOreProgettiModel> CalcOreProj(int idxProj)
{
CalcOreProgettiModel? dbResult = new CalcOreProgettiModel();
string currKey = $"{rKeyCalcOreProj}:{idxProj}";
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<CalcOreProgettiModel>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.CalcOreProj(idxProj);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per CalcOreProj: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new CalcOreProgettiModel();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco dei controlli VC19 nel periodo indicato x dipendente
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public async Task<List<CheckVc19Model>> CheckVC19List(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
List<CheckVc19Model>? dbResult = new List<CheckVc19Model>();
string currKey = $"{rKeyVC19}:{dtInizio:yyyyMMdd}:{dtFine:yyyMMdd}";
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<CheckVc19Model>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.CheckVC19List(idxDipendente, dtInizio, dtFine);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per CheckVC19List: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<CheckVc19Model>();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco dei dettagli giornalieri attività di un dipendente, dato periodo riferimento
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public async Task<List<CORE.Data.DTO.DailyDataDTO>> DailyDetails(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
List<CORE.Data.DTO.DailyDataDTO>? dbResult = new List<CORE.Data.DTO.DailyDataDTO>();
string currKey = $"{rKeyDailyData}:{idxDipendente}:{dtInizio.ToString("yyyy-MM-dd")}:{dtFine.ToString("yyyy-MM-dd")}";
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<CORE.Data.DTO.DailyDataDTO>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.DailyDetails(idxDipendente, dtInizio, dtFine);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per DailyDetails: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<CORE.Data.DTO.DailyDataDTO>();
}
return await Task.FromResult(dbResult);
}
public async Task<List<DipendentiModel>> DipendentiGetAll()
{
List<DipendentiModel>? dbResult = new List<DipendentiModel>();
string rawData;
var redisDataList = await distributedCache.GetAsync(rKeyDipendenti);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<DipendentiModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.DipendentiGetAll();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(rKeyDipendenti, redisDataList, cacheOpt(false));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per DipendentiGetAll: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<DipendentiModel>();
}
return await Task.FromResult(dbResult);
}
public void Dispose()
{
// Clear database controller
dbController.Dispose();
}
/// <summary>
/// invalida tutta la cache in caso di update
/// </summary>
/// <returns></returns>
public async Task InvalidateAllCache()
{
await distributedCache.RemoveAsync(rKeyDipendenti);
await distributedCache.RemoveAsync(rKeyFasiAll);
foreach (var item in cachedDataList)
{
await distributedCache.RemoveAsync(item);
}
cachedDataList = new List<string>();
}
/// <summary>
/// Invalida la cache corrispondente al apttern fornito
/// </summary>
/// <returns></returns>
public async Task InvalidateCache(string cachePattern)
{
foreach (var item in cachedDataList)
{
if (item.Contains(cachePattern))
{
await distributedCache.RemoveAsync(item);
}
}
}
/// <summary>
/// Statistiche ultime settimane
/// </summary>
/// <param name="idxDipendente"></param>
/// <param name="dtRif"></param>
/// <param name="numWeek"></param>
/// <returns></returns>
public async Task<List<CORE.Data.DTO.WeekStatDTO>> LastWeeks(int idxDipendente, DateTime dtRif, int numWeek)
{
List<CORE.Data.DTO.WeekStatDTO>? dbResult = new List<CORE.Data.DTO.WeekStatDTO>();
string currKey = $"{rKeyWeekStats}:{idxDipendente}:{dtRif.ToString("yyyy-MM-dd")}:{numWeek}";
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<CORE.Data.DTO.WeekStatDTO>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.WeekOverview(idxDipendente, dtRif, numWeek);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per LastWeeks: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<CORE.Data.DTO.WeekStatDTO>();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Elenco pareto progetti ordinati da filtro
/// </summary>
/// <param name="idxDip"></param>
/// <param name="numDayPrev"></param>
/// <param name="maxResult"></param>
/// <returns></returns>
public async Task<List<ParetoRegAttModel>> ParetoRegAtt(int idxDip, int numDayPrev, int maxResult)
{
List<ParetoRegAttModel>? dbResult = new List<ParetoRegAttModel>();
string currKey = $"{rKeyParetoRegAtt}:{idxDip}:{numDayPrev}:{maxResult}";
DateTime dataFine = DateTime.Today.AddDays(1);
DateTime dataInizio = dataFine.AddDays(-numDayPrev);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<ParetoRegAttModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.ParetoRegAtt(idxDip, dataInizio, dataFine, maxResult);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per ParetoRegAtt: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<ParetoRegAttModel>();
}
return await Task.FromResult(dbResult);
}
public async Task<bool> RegAttDelete(RegAttivitaModel currItem)
{
bool answ = false;
try
{
dbController.RegAttDelete(currItem);
// invalido la cache...
await InvalidateAllCache();
answ = true;
}
catch
{ }
return answ;
}
/// <summary>
/// Recupera ultima attività dipendente
/// </summary>
/// <param name="IdxDipendente"></param>
/// <param name="onlyActive">cerca ultima solo tra attive (=true) o tutte (=false)</param>
/// <returns></returns>
public async Task<RegAttivitaModel> RegAttLastByDip(int IdxDipendente, bool onlyActive)
{
RegAttivitaModel dbResult = dbController.RegAttLastByDip(IdxDipendente, onlyActive);
return await Task.FromResult(dbResult);
}
public async Task<bool> RegAttUpdate(RegAttivitaModel currItem)
{
bool answ = false;
try
{
dbController.RegAttUpdate(currItem);
// invalido la cache...
await InvalidateAllCache();
answ = true;
}
catch
{ }
return answ;
}
/// <summary>
/// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente
/// </summary>
/// <param name="idxDipendente">Dipendente interessato</param>
/// <param name="dtInizio">Data di riferimento (ultima/corrente)</param>
/// <param name="dtFine">NUm settimane precedenti da recuperare</param>
/// <returns></returns>
public async Task<List<RilievoTempModel>> RilTempList(int idxDipendente, DateTime dtInizio, DateTime dtFine)
{
List<RilievoTempModel>? dbResult = new List<RilievoTempModel>();
string currKey = $"{rKeyRilTemp}:{dtInizio:yyyyMMdd}:{dtFine:yyyMMdd}";
trackCache(currKey);
string rawData;
var redisDataList = await distributedCache.GetAsync(currKey);
if (redisDataList != null)
{
rawData = Encoding.UTF8.GetString(redisDataList);
dbResult = JsonConvert.DeserializeObject<List<RilievoTempModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.RilTempList(idxDipendente, dtInizio, dtFine);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDataList = Encoding.UTF8.GetBytes(rawData);
await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per RilTempList: {ts.TotalMilliseconds} ms");
}
if (dbResult == null)
{
dbResult = new List<RilievoTempModel>();
}
return await Task.FromResult(dbResult);
}
public async Task<bool> RilTempUpdate(RilievoTempModel currItem)
{
bool answ = false;
try
{
dbController.RilTempUpdate(currItem);
// invalido la cache...
await InvalidateCache(rKeyRilTemp);
//await InvalidateCache($"{rKeyWeekStats}:{currItem.IdxDipendente}");
await InvalidateCache($"{rKeyDailyData}:{currItem.IdxDipendente}");
answ = true;
}
catch
{ }
return answ;
}
public void rollBackEdit(object item)
{
dbController.rollBackEntity(item);
}
public async Task<bool> TimbratureDelete(TimbratureModel currItem)
{
bool answ = false;
try
{
dbController.TimbratureDelete(currItem);
// invalido la cache...
await InvalidateAllCache();
answ = true;
}
catch
{ }
return answ;
}
public async Task<bool> TimbratureUpdate(TimbratureModel currItem)
{
bool answ = false;
try
{
dbController.TimbratureUpdate(currItem);
// invalido la cache...
await InvalidateAllCache();
answ = true;
}
catch
{ }
return answ;
}
#endregion Public Methods
}
}
-308
View File
@@ -1,308 +0,0 @@
using GPW.CORE.Data;
using GPW.CORE.Data.DbModels;
using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json;
using RestSharp;
using System.Diagnostics;
using System.Text;
using System.Web;
namespace GPW.CORE.UI.Data
{
/// <summary>
/// Servizi e dati condivisi a livello applicazione
/// </summary>
public class LicenseService
{
#region Private Fields
private static ILogger<LicenseService> _logger;
private static IConfiguration _configuration;
private readonly IDistributedCache distributedCache;
/// <summary>
/// Chiave redis x attivazioni della licenza
/// </summary>
protected const string rKeyAttByLic = "LongCache:AttByLic";
/// <summary>
/// Durata assoluta massima della cache IN SECONDI
/// </summary>
private int chAbsExp = 60 * 5;
/// <summary>
/// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa
/// NON estende oltre il tempo massimo di validità della cache (chAbsExp)
/// </summary>
private int chSliExp = 60 * 1;
/// <summary>
/// Fattorte conversione cache sliding --> 1 h
/// </summary>
private int cacheFact = 12;
/// <summary>
/// Opzioni cache con moltiplicatore durata risp durata base (1/5 minuti)
/// </summary>
/// <param name="multFact"></param>
/// <returns></returns>
private DistributedCacheEntryOptions cacheOpt(int multFact)
{
var numSecAbsExp = chAbsExp * multFact;
var numSecSliExp = chSliExp * multFact;
return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp));
}
/// <summary>
/// Elenco obj in cache
/// </summary>
private List<string> cachedDataList = new List<string>();
/// <summary>
/// Init classe
/// </summary>
/// <param name="configuration"></param>
/// <param name="logger"></param>
/// <param name="distributedCache"></param>
public LicenseService(IConfiguration configuration, ILogger<LicenseService> logger, IDistributedCache distributedCache)
{
_logger = logger;
_configuration = configuration;
this.distributedCache = distributedCache;
}
/// <summary>
/// Recupero chiave da redis
/// </summary>
/// <param name="rKey"></param>
/// <returns></returns>
protected async Task<string> getRSV(string rKey)
{
string answ = "";
var redisDataList = await distributedCache.GetAsync(rKey);
if (redisDataList != null)
{
answ = Encoding.UTF8.GetString(redisDataList);
}
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;
var redisDataList = Encoding.UTF8.GetBytes(rVal);
await distributedCache.SetAsync(rKey, redisDataList, cacheOpt(cacheMult));
fatto = true;
return fatto;
}
/// <summary>
/// Salvataggio chiave 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)
{
bool fatto = false;
var redisDataList = Encoding.UTF8.GetBytes($"{rValInt}");
await distributedCache.SetAsync(rKey, redisDataList, cacheOpt(cacheMult));
fatto = true;
return fatto;
}
/// <summary>
/// Registra in cache chiave se non fosse già in elenco
/// </summary>
/// <param name="newKey"></param>
protected void trackCache(string newKey)
{
if (!cachedDataList.Contains(newKey))
{
cachedDataList.Add(newKey);
}
}
#endregion Private Fields
#region Public Events
public event Action EA_InfoUpdated = null!;
public List<LiManObj.AttivazioneDTO> ActivList { get; set; } = new List<LiManObj.AttivazioneDTO>();
#endregion Public Events
#region Public Properties
public async Task<List<LiManObj.AttivazioneDTO>> ActivListCache()
{
List<LiManObj.AttivazioneDTO> dbResult = new List<LiManObj.AttivazioneDTO>();
string cacheKey = $"{rKeyAttByLic}:{MasterKey}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject<List<LiManObj.AttivazioneDTO>>(rawData);
}
return await Task.FromResult(dbResult);
}
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 * cacheFact * 24);
fatto = true;
if (EA_InfoUpdated != null)
{
EA_InfoUpdated?.Invoke();
}
return fatto;
}
public List<AnagKeyValueModel> AKVList { get; set; } = new List<AnagKeyValueModel>();
public string Installazione { get; set; } = "";
public string Applicazione { 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;
}
}
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);
#endregion Public Properties
#region Private Methods
private void ReportUpdated()
{
if (EA_InfoUpdated != null)
{
EA_InfoUpdated?.Invoke();
}
}
/// <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>
/// 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;
}
/// <summary>
/// URL dell'API x chiamate gestione licenze
/// </summary>
private static string apiUrl = "https://liman.egalware.com/ELM.API/";
/// <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);
}
#endregion Private Methods
}
}
-210
View File
@@ -1,210 +0,0 @@
using GPW.CORE.Data;
using GPW.CORE.Data.DbModels;
using System.Security.Cryptography;
using System.Text;
namespace GPW.CORE.UI.Data
{
public class MessageService
{
#region Private Fields
private string _pageIcon = "";
private string _pageName = "";
private string _searchVal = "";
private DipendentiModel _rigaDip;
private bool showSearch;
#endregion Private Fields
#region Public Events
public event Action EA_HideSearch = null!;
public event Action EA_PageUpdated = null!;
public event Action EA_SearchUpdated = null!;
public event Action EA_ShowSearch = null!;
#endregion Public Events
#region Public Properties
public string PageIcon
{
get => _pageIcon;
set
{
if (_pageIcon != value)
{
_pageIcon = value;
ReportPageUpd();
}
}
}
public string PageName
{
get => _pageName;
set
{
if (_pageName != value)
{
_pageName = value;
ReportPageUpd();
}
}
}
public string SearchVal
{
get => _searchVal;
set
{
if (_searchVal != value)
{
_searchVal = value;
if (EA_SearchUpdated != null)
{
EA_SearchUpdated?.Invoke();
}
}
}
}
public DipendentiModel? RigaDip
{
get => _rigaDip;
set
{
if (_rigaDip != value)
{
_rigaDip = value;
if (EA_SearchUpdated != null)
{
EA_SearchUpdated?.Invoke();
}
}
}
}
public int IdxDipendente
{
get
{
int answ = 0;
if (_rigaDip != null)
{
answ = _rigaDip.IdxDipendente;
}
return answ;
}
}
public bool IsActive
{
get
{
bool answ = false;
if (_rigaDip != null)
{
answ = (bool)_rigaDip.Attivo;
}
return answ;
}
}
public bool PayloadOk { get; set; } = false;
/// <summary>
/// Calcola HASH del codice impiego = payload utente
/// </summary>
/// <param name="rigaDip"></param>
/// <returns></returns>
public string HashDip
{
get
{
string hash = "";
string answ = "";
if (_rigaDip != null)
{
answ = $"{_rigaDip.IdxDipendente}|{_rigaDip.Cognome}.{_rigaDip.Nome}|{_rigaDip.Cf}|{_rigaDip.DataAssunzione:yyyyMMdd}|{_rigaDip.Email}|{_rigaDip.Matricola}";
}
// hashing!
using (var md5 = MD5.Create())
{
byte[] InputBytes = Encoding.UTF8.GetBytes(answ);
var byteHash = md5.ComputeHash(InputBytes);
hash = BitConverter.ToString(byteHash).Replace("-", "").ToLowerInvariant();
}
return hash;
}
}
public bool ShowSearch
{
get => showSearch;
set
{
if (showSearch != value)
{
showSearch = value;
if (showSearch)
{
if (EA_ShowSearch != null)
{
EA_ShowSearch?.Invoke();
}
}
else
{
if (EA_HideSearch != null)
{
EA_HideSearch?.Invoke();
}
}
}
}
}
public RegAttivitaModel? recordRA { get; set; } = null;
public RegAttivitaModel? clonedRA { get; set; } = null;
public int selWeekNum { get; set; } = 0;
public int selYear { get; set; } = DateTime.Today.Year;
public DateTime targetDate { get; set; } = DateTime.Today;
#endregion Public Properties
#region Private Methods
private void ReportPageUpd()
{
if (EA_PageUpdated != null)
{
EA_PageUpdated?.Invoke();
}
}
private void ReportSearch()
{
if (EA_SearchUpdated != null)
{
EA_SearchUpdated?.Invoke();
}
}
#endregion Private Methods
}
}
-39
View File
@@ -1,39 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>3.0.2201.2519</Version>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Content Remove="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS02.pubxml" />
<_WebToolingArtifacts Remove="Properties\PublishProfiles\W2019-IIS-DEV.pubxml" />
</ItemGroup>
<ItemGroup>
<None Include="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NLog" Version="4.7.13" />
<PackageReference Include="RestSharp" Version="107.0.3" />
<PackageReference Include="StackExchange.Redis" Version="2.2.88" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GPW.CORE.Data\GPW.CORE.Data.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
</Target>
</Project>
-42
View File
@@ -1,42 +0,0 @@
@page
@model GPW.CORE.UI.Pages.ErrorModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Error</title>
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/css/site.css" rel="stylesheet" asp-append-version="true" />
</head>
<body>
<div class="main">
<div class="content px-4">
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
</div>
</div>
</body>
</html>
-27
View File
@@ -1,27 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Diagnostics;
namespace GPW.CORE.UI.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private readonly ILogger<ErrorModel> _logger;
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}
-189
View File
@@ -1,189 +0,0 @@
@page "/FastRec"
@attribute [Authorize]
@using GPW.CORE.UI
@using GPW.CORE.UI.Components
@using CORE.Data.DbModels
@using CORE.Data.DTO
@using UI.Data
@inject IJSRuntime JSRuntime
@inject GpwDataService GDataServ
@inject MessageService AppMServ
<div class="card">
<div class="card-header table-primary">
<div class="d-flex justify-content-between">
<div class="px-2">
<h3>Fast Recording</h3>
</div>
<div class="px-2">
<div class="input-group input-group-lg" title="Modalità ricerca Progetti / Fasi">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="fas fa-search"></i>
</span>
</div>
<select @bind="@TipoSearch" class="form-control form-control-sm">
<option value="0">Pareto attività</option>
<option value="1">Ricerca Libera</option>
</select>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-8">
@if (@TipoSearch == 0)
{
<ParetoRA ItemSelected="SelFase" idxFase="@idxFaseSel"></ParetoRA>
}
else if (@TipoSearch == 1)
{
<FasiSearch ItemSelected="SelFase"></FasiSearch>
}
</div>
<div class="col-4">
@if (idxFaseSel > 0)
{
<RecFaseStart RecStarted="RecDone" idxFase="@idxFaseSel"></RecFaseStart>
}
else
{
<div class="alert alert-info">
<h3>Attesa selezione</h3>
Selezionare una Fase per attivare la registrazione attività
</div>
}
</div>
<div class="col-12">
<DayHoriz IsTitle="true" StartHour="@startHour" EndHour="@endHour" ListFasi="@ListFasi" IdxDipSel="@idxDipendente"></DayHoriz>
@foreach (var currItem in ListRecords)
{
<DayHoriz DayDTO="@currItem" StartHour="@startHour" EndHour="@endHour" ListFasi="@ListFasi" IdxDipSel="@idxDipendente" EnableActionMenu="false"></DayHoriz>
}
</div>
</div>
</div>
</div>
@code {
private List<AnagFasiModel> ListFasi = new List<AnagFasiModel>();
private List<DailyDataDTO> ListRecords = new List<DailyDataDTO>();
private int _tipoSearch = 0;
public int TipoSearch
{
get
{
return _tipoSearch;
}
set
{
if (!_tipoSearch.Equals(value))
{
_tipoSearch = value;
idxFaseSel = 0;
}
}
}
protected int startHour = 7;
protected int endHour = 21;
protected bool isLoading = false;
private int idxFaseSel = 0;
private int idxDipendente
{
get => AppMServ.IdxDipendente;
}
private void SelFase(int idxFase)
{
idxFaseSel = idxFase;
}
private void RecDone(bool fatto)
{
idxFaseSel = 0;
}
private async Task ReloadData()
{
isLoading = true;
DateTime oggi = DateTime.Today;
var rawData=await GDataServ.DailyDetails(idxDipendente, oggi, oggi.AddDays(1));
ListRecords = rawData.Where(x=> x.DtRif==oggi).ToList();
await Task.Delay(100);
checkHourRange();
await Task.Delay(100);
isLoading = false;
}
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
private void checkHourRange()
{
int minHour = 9;
int maxHour = 18;
if (ListRecords != null)
{
int roundMin = 15;
// per ogni giornata
foreach (var giornata in ListRecords)
{
var minRecTimb = giornata.ListTimbr
.Where(x => x.Entrata == true)
.OrderBy(x => x.DataOra)
.FirstOrDefault();
if (minRecTimb != null)
{
if (minHour > minRecTimb.DataOra.AddMinutes(-roundMin).Hour)
{
minHour = minRecTimb.DataOra.AddMinutes(-roundMin).Hour;
}
}
var minRecRa = giornata.ListRA
.OrderBy(x => x.Inizio)
.FirstOrDefault();
if (minRecRa != null)
{
if (minHour > minRecRa.Inizio.AddMinutes(-roundMin).Hour)
{
minHour = minRecRa.Inizio.AddMinutes(-roundMin).Hour;
}
}
var maxRecTimb = giornata.ListTimbr
.Where(x => x.Entrata == false)
.OrderByDescending(x => x.DataOra)
.FirstOrDefault();
if (maxRecTimb != null)
{
if (maxHour < maxRecTimb.DataOra.AddMinutes(roundMin).Hour + 1)
{
maxHour = maxRecTimb.DataOra.AddMinutes(roundMin).Hour + 1;
}
}
var maxRecRa = giornata.ListRA
.OrderByDescending(x => x.Fine)
.FirstOrDefault();
if (maxRecRa != null)
{
if (maxHour < maxRecRa.Fine.AddMinutes(roundMin).Hour + 1)
{
maxHour = maxRecRa.Fine.AddMinutes(roundMin).Hour + 1;
}
}
}
}
startHour = minHour;
endHour = maxHour;
}
}
-39
View File
@@ -1,39 +0,0 @@
@page "/ForceReset"
@attribute [Authorize]
@using CORE.Data.DbModels
@using UI.Data
@inject GpwDataService GDataServ
@inject NavigationManager NavManager
@inject MessageService AppMServ
<div class="card">
<div class="card-header">
Data Reset
</div>
<div class="card-body">
<h1>@message</h1>
<LoadingData></LoadingData>
</div>
</div>
@code {
protected string message = "Resetting Cache!";
protected override async Task OnInitializedAsync()
{
await GDataServ.InvalidateAllCache();
AppMServ.clonedRA = null;
AppMServ.recordRA = null;
//AppMServ.RigaDip = null;
message = "Reset done!";
// attendo 500 msec
await Task.Delay(500);
// passo a pagina home
NavManager.NavigateTo("Planner");
}
}
-20
View File
@@ -1,20 +0,0 @@
@page "/"
<PageTitle>GPW</PageTitle>
<div class="row mt-3">
<div class="col-6">
<h1>GPW - Log Commesse</h1>
</div>
<div class="col-6 text-right">
<span class="badge badge-pill badge-dark" style="font-size:3em;">
<img class="img-fluid" width="48" src="images/LogoEgw.png" /> <b>Egalware</b>
</span>
</div>
<div class="col-12 text-center mt-5">
<div class="alert alert-secondary">
Gestione commesse utente GPW, visualizzazione formato planner settimanale
</div>
</div>
</div>
-145
View File
@@ -1,145 +0,0 @@
@page "/Planner"
@attribute [Authorize]
@using GPW.CORE.UI.Components
@if (selPeriod)
{
<dialog class="modal fade show" 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">
<WeekSelector CloseReq="ResetSelPeriodo" WeekSelected="ReloadPeriodo"></WeekSelector>
</div>
</div>
</dialog>
}
else if (showTemp)
{
<dialog class="modal fade show" 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">
<DayCheckEditor TargetDate="@DtRifTempRil" CloseReq="ResetDayCheck"></DayCheckEditor>
</div>
</div>
</dialog>
}
else if (currRecord != null)
{
<dialog class="modal fade show" 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="@currRecord" ItemReset="UpdRegAttData" ItemUpdated="UpdRegAttData"></RegAttEditor>
</div>
</div>
</dialog>
}
else if (ListTimbr != null)
{
<dialog class="modal fade show" 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">
<TimbrEditor ListTimb="@ListTimbr" CloseReq="ResetTimbData" ItemUpdated="UpdTimbData"></TimbrEditor>
</div>
</div>
</dialog>
}
<div class="card">
<div class="card-header table-primary py-1">
<div class="row">
<div class="col-12 col-lg-2 text-center">
<div class="btn-group w-100 mb-1">
<button class="btn btn-sm btn-dark pt-1 pb-0 @actionCss" @onclick="() => ResetWeek()" title="Ritorna a data corrente" disabled="@isLoading">
<h3><i class="fas fa-home"></i> Week Plan</h3>
</button>
</div>
<div class="btn-group w-100">
<button class="btn btn-sm btn-outline-primary py-0 @actionCss" @onclick="() => MoveWeek(-4)" title="-4 settimane" disabled="@isLoading">
<div><sub>@currWeekSel.inizio.ToString("dd.MM.yy")</sub></div>
<i class="fas fa-angle-double-left"></i>
</button>
<button class="btn btn-sm btn-primary py-0 @actionCss" @onclick="() => ShowSelPeriodo()" title="Imposta periodo" disabled="@isLoading">
<div>Week <b>@currWeekNum.ToString("00")</b></div>
<sub>@currYear</sub>
</button>
<button class="btn btn-sm btn-outline-primary py-0 @actionCss" @onclick="() => MoveWeek(4)" title="+4 settimane" disabled="@isLoading">
<div><sub>@currWeekSel.fine.ToString("dd.MM.yy")</sub></div>
<i class="fas fa-angle-double-right"></i>
</button>
</div>
</div>
<div class="col-12 col-lg-10">
@if (weekStatList != null)
{
<div class="row">
@foreach (var item in weekStatList)
{
<div class="col px-1">
<WeekStat currData="@item" WeekSel="@currWeekNum" weekSelected="setWeekNumber"></WeekStat>
</div>
}
</div>
}
else
{
<LoadingData></LoadingData>
}
</div>
</div>
</div>
<div class="card-body">
@if (ListRecords == null)
{
<LoadingData></LoadingData>
}
else
{
<div class="row">
<div class="col-12">
<DayHoriz IsTitle="true" StartHour="@startHour" EndHour="@endHour" ListFasi="@ListFasi" IdxDipSel="@IdxDipendente"></DayHoriz>
</div>
@foreach (var currItem in ListRecords)
{
<div class="col-12">
<DayHoriz DayDTO="@currItem" StartHour="@startHour" EndHour="@endHour" ListFasi="@ListFasi" ItemSelected="ReportSelect" ItemUpdated="UpdRegAttData" IdxDipSel="@IdxDipendente" PeriodSelected="PeriodoSelect" ReqTempList="ShowTempRil"></DayHoriz>
</div>
}
</div>
}
</div>
<div class="card-footer py-1">
<div class="d-flex justify-content-between">
<div class="py-1 px-2">
Selezione range orario:&nbsp;
<input @bind="startHour" style="width: 3em;" type="number" />
<i class="fas fa-angle-double-right"></i>
<input @bind="endHour" style="width: 3em;" type="number" />
</div>
<div class="py-1 px-2">
<span>@lastRefresh.ToString("HH:mm:ss")</span> <i class="far fa-clock"></i>
</div>
<div class="py-1 px-2">
@if (clonedRA != null)
{
<div class="d-flex">
<div class="px-2 flex-grow-1">
<RegAtt CurrData="@clonedRA" Periodo="@periodoClonato" ListFasi="@ListFasi" ItemSelected="ReportSelect" IdxDipSel="@IdxDipendente" IsClipboard="true"></RegAtt>
</div>
<div class="px-2">
<button class="btn btn-block btn-warning" @onclick="ResetClone" title="Reset Clipboard">
<i class="fas fa-clipboard"></i><br>
<i class="far fa-times-circle"></i>
</button>
</div>
</div>
}
</div>
</div>
</div>
</div>
-498
View File
@@ -1,498 +0,0 @@
using GPW.CORE.Data;
using GPW.CORE.Data.DbModels;
using GPW.CORE.Data.DTO;
using GPW.CORE.UI.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace GPW.CORE.UI.Pages
{
/// <summary>
/// Gestione pagina principale del planner
///
/// modale: vedere qui: https://gist.github.com/conficient/ba98d1662c659e170ec16650acea05c8
/// </summary>
//[Authorize(Roles = "SuperAdmin, Admin")]
public partial class Planner : IDisposable
{
#region Private Fields
private int _endHour = 19;
private int _startHour = 8;
private RegAttivitaModel currRecord = null;
private List<AnagFasiModel> ListFasi = new List<AnagFasiModel>();
private List<DailyDataDTO> ListRecords = new List<DailyDataDTO>();
private List<TimbratureModel> ListTimbr = null;
private bool selPeriod = false;
private List<WeekStatDTO> weekStatList = new List<WeekStatDTO>();
private bool showTemp = false;
private DateTime DtRifTempRil = DateTime.Today;
#endregion Private Fields
#region Private Properties
private int _currPage { get; set; } = 1;
private int _numRecord { get; set; } = 10;
private int _selPlantId { get; set; } = 0;
private int _selSuppId { get; set; } = 0;
private int _selTraspId { get; set; } = 0;
private int currPage
{
get => _currPage;
set
{
if (_currPage != value)
{
_currPage = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
private int endHour
{
get => _endHour;
set
{
// fix --> max 24...
_endHour = _endHour > 24 ? 24 : _endHour;
if (_endHour != value)
{
_endHour = value;
}
}
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => _numRecord;
set
{
if (_numRecord != value)
{
_numRecord = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
private double periodoClonato
{
get
{
double answ = 8;
// se ho record clkonato --> uso quello
if (clonedRA != null)
{
answ = clonedRA.Durata.TotalHours;
}
else
{
answ = endHour - startHour;
}
return answ;
}
}
private int startHour
{
get => _startHour;
set
{
// fix --> MIN 0...
_startHour = _startHour < 0 ? 0 : _startHour;
if (_startHour != value)
{
_startHour = value;
}
}
}
#endregion Private Properties
#region Protected Properties
protected string actionCss
{
get => isLoading ? "disabled" : "";
}
[Inject]
protected MessageService AppMServ { get; set; }
protected int currWeekNum
{
get
{
return AppMServ.selWeekNum;
}
set
{
AppMServ.selWeekNum = value;
}
}
protected WeekData currWeekSel
{
get
{
return new WeekData(currYear, currWeekNum);
}
}
protected int currYear
{
get
{
return AppMServ.selYear;
}
set
{
AppMServ.selYear = value;
}
}
[Inject]
protected GpwDataService DataService { get; set; }
/// <summary>
/// Dipendente corrente
/// </summary>
protected int IdxDipendente
{
get
{
return AppMServ.IdxDipendente;
}
}
[Inject]
protected IJSRuntime JSRuntime { get; set; }
[Inject]
protected NavigationManager NavManager { get; set; }
protected DateTime TargetDate
{
get
{
return AppMServ.targetDate;
}
set
{
AppMServ.targetDate = value;
}
}
#endregion Protected Properties
#region Public Properties
public RegAttivitaModel clonedRA
{
get
{
return AppMServ.clonedRA;
}
set
{
AppMServ.clonedRA = value;
}
}
#endregion Public Properties
#region Private Methods
private void checkHourRange()
{
int minHour = 9;
int maxHour = 18;
if (ListRecords != null)
{
int roundMin = 15;
// per ogni giornata
foreach (var giornata in ListRecords)
{
var minRecTimb = giornata.ListTimbr
.Where(x => x.Entrata == true)
.OrderBy(x => x.DataOra)
.FirstOrDefault();
if (minRecTimb != null)
{
if (minHour > minRecTimb.DataOra.AddMinutes(-roundMin).Hour)
{
minHour = minRecTimb.DataOra.AddMinutes(-roundMin).Hour;
}
}
var minRecRa = giornata.ListRA
.OrderBy(x => x.Inizio)
.FirstOrDefault();
if (minRecRa != null)
{
if (minHour > minRecRa.Inizio.AddMinutes(-roundMin).Hour)
{
minHour = minRecRa.Inizio.AddMinutes(-roundMin).Hour;
}
}
var maxRecTimb = giornata.ListTimbr
.Where(x => x.Entrata == false)
.OrderByDescending(x => x.DataOra)
.FirstOrDefault();
if (maxRecTimb != null)
{
if (maxHour < maxRecTimb.DataOra.AddMinutes(roundMin).Hour + 1)
{
maxHour = maxRecTimb.DataOra.AddMinutes(roundMin).Hour + 1;
}
}
var maxRecRa = giornata.ListRA
.OrderByDescending(x => x.Fine)
.FirstOrDefault();
if (maxRecRa != null)
{
if (maxHour < maxRecRa.Fine.AddMinutes(roundMin).Hour + 1)
{
maxHour = maxRecRa.Fine.AddMinutes(roundMin).Hour + 1;
}
}
}
}
startHour = minHour;
endHour = maxHour;
}
/// <summary>
/// Reinit dei dati
/// </summary>
/// <param name="dateReset"></param>
/// <returns></returns>
private async Task InitData(bool dateReset)
{
isLoading = true;
if (dateReset)
{
TargetDate = DateTime.Today;
}
weekStatList = await DataService.LastWeeks(IdxDipendente, TargetDate, 4);
currWeekNum = weekStatList.Last().WeekNumber;
isLoading = false;
}
private async Task ReloadData()
{
isLoading = true;
ListRecords = await DataService.DailyDetails(IdxDipendente, currWeekSel.inizio, currWeekSel.fine);
await Task.Delay(100);
checkHourRange();
await Task.Delay(100);
lastRefresh = DateTime.Now;
isLoading = false;
}
#endregion Private Methods
#region Protected Methods
protected async Task MoveWeek(int numWeek)
{
isLoading = true;
TargetDate = TargetDate.AddDays(numWeek * 7);
await Task.Delay(100);
await InitData(false);
await Task.Delay(100);
await ReloadData();
}
protected override async Task OnInitializedAsync()
{
await InitData(true);
await ReloadData();
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void PeriodoSelect(List<TimbratureModel> newList)
{
// salvo periodo selezionato
ListTimbr = newList;
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void ShowTempRil(DateTime dataRif)
{
// salvo data
DtRifTempRil = dataRif;
showTemp = true;
}
/// <summary>
/// Timer per refresh dati
///
/// https://stackoverflow.com/questions/63060065/blazor-timer-call-async-api-task-to-update-ui
/// https://www.janduniec.blog/index.php/100/timers-in-blazor/
/// </summary>
protected System.Timers.Timer UITimer;
protected DateTime lastRefresh = DateTime.Now;
protected override void OnInitialized()
{
// avvio un timer infinito x refresh pagina COMUNQUE ogni 60 sec anche non succedesse nulla...
UITimer = new System.Timers.Timer
{
Interval = 1000 * 60,
AutoReset = true,
Enabled = true
};
UITimer.Elapsed += async (s, ea) => await TryReload();
}
public void Dispose()
{
UITimer?.Dispose();
}
/// <summary>
/// Gestione refresh condizionale
/// </summary>
/// <returns></returns>
protected async Task TryReload()
{
await Task.Delay(1);
// effettuo reload SOLO SE no ho editing in corso...
if (!modeEdit)
{
await ReloadData();
await InvokeAsync(StateHasChanged);
}
}
protected bool modeEdit
{
get => (currRecord != null || ListTimbr != null || showTemp);
//get => (selPeriod || showTemp || currRecord != null || weekStatList != null || ListTimbr != null);
}
protected async Task ReloadPeriodo()
{
selPeriod = false;
showTemp = false;
weekStatList = null;
currRecord = null;
ListTimbr = null;
await Task.Delay(50);
await InitData(false);
await Task.Delay(50);
await ReloadData();
}
/// <summary>
/// Indico item selezionato
/// </summary>
protected async void ReportSelect(RegAttivitaModel selRecord)
{
// recupero attività selezionata in curr record
currRecord = selRecord;
}
protected void ResetClone()
{
clonedRA = null;
}
protected async Task ResetData()
{
currRecord = null;
ListTimbr = null;
await InitData(true);
await ReloadData();
}
protected async Task ResetSelPeriodo()
{
selPeriod = false;
showTemp = false;
currRecord = null;
ListTimbr = null;
await InitData(true);
await ReloadData();
}
protected async Task ResetDayCheck()
{
selPeriod = false;
showTemp = false;
currRecord = null;
ListTimbr = null;
await InitData(true);
await ReloadData();
}
protected async Task ResetTimbData()
{
currRecord = null;
ListTimbr = null;
await ReloadData();
}
protected async Task ResetWeek()
{
isLoading = true;
TargetDate = DateTime.Today;
await Task.Delay(100);
await InitData(false);
await Task.Delay(100);
await ReloadData();
}
protected async Task setWeekNumber(WeekData wData)
{
isLoading = true;
// seleziono settimana!
currYear = wData.anno;
currWeekNum = wData.weekNumber;
// resetto currRecord...
currRecord = null;
await ReloadData();
}
protected async Task ShowSelPeriodo()
{
selPeriod = true;
}
protected async Task UpdRegAttData()
{
isLoading = true;
currRecord = null;
ListTimbr = null;
await Task.Delay(100);
await ReloadData();
}
protected async Task UpdTimbData()
{
isLoading = true;
currRecord = null;
await Task.Delay(100);
await ReloadData();
}
#endregion Protected Methods
}
}
-383
View File
@@ -1,383 +0,0 @@
@page "/Test"
@attribute [AllowAnonymous]
@using GPW.CORE.UI.Components
<PageTitle>Test - Fasi</PageTitle>
<div class="row">
<div class="col-4">
<ChartTS Id="TempRil" DataTS="@getTsData()" lineColor="rgb(7, 173, 236)" backColor="rgba(107, 223, 255, 0.3)"></ChartTS>
</div>
<div class="col-4">
<ChartHist Id="FreqTemp" Data="@(new[] { "5", "8", "10", "6", "4", "3" })" Labels="@(new[] { "35.8", "35.9", "36.0", "36.1", "36.2", "36.3" })" lineColor="rgb(7, 173, 236)" backColor="rgba(107, 223, 255, 0.5)"></ChartHist>
</div>
<div class="col-4">
<Chart Id="Bar" Type="@Chart.ChartType.Bar" Data="@(new[] { "10", "9", "12", "8", "14" })" BackgroundColor="@(new[] { "yellow","red", "green", "blue"})" Labels="@(new[] { "S01","S02","S03","S04"})"></Chart>
</div>
</div>
@*<div class="p-1 flex-fill text-left">
<div class="d-flex justify-content-between text-center">
<div class="py-0 small flex-fill " style="width: 5.36%"><div class="d-flex"><div class="px-1 small textTrim"><button class="px-1 text-center btn btn-lg btn-outline-success"><i class="fas fa-plus-circle"></i></button></div></div></div><div class="py-0 small flex-fill border border-info rounded" style="width: 3.57%">
<div class="d-flex">
<div class="dropdown">
<button class="dropbtn px-1 text-center border border-secondary border-top-0 border-bottom-0 border-left-0 btn btn-info btn-sm" style="font-size: 0.72rem;">
<div>07</div>
<div>45</div>
<div class="badge badge-dark">30'</div>
</button><div class="dropdown-content border border-dark table-dark text-light rounded p-2">
<div class="row">
<div class="col-9 pr-0">
<div class="text-light text-left"><b>Steamware</b> - <span class="small">ORG Personale</span></div>
<div class="text-info text-left" title="Mail">Mail</div>
</div>
<div class="col-3">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="switch-87105" title="Modifica Fine" value="">
<label class="custom-control-label small" for="switch-87105">Fine</label>
</div>
</div>
</div>
<div class="btn-group btn-group-sm w-100 py-2">
<button class="btn btn-sm btn-info"><i class="fas fa-pencil-alt"></i> Edit</button>
<button class="btn btn-sm btn-primary"><i class="far fa-copy"></i> Copy</button>
<button class="btn btn-sm btn-danger"><i class="fas fa-trash-alt"></i> Delete</button>
</div>
<div class="btn-group btn-group-sm w-100 small">
<button class="btn btn-sm btn-warning">-2h</button>
<button class="btn btn-sm btn-warning">-1h</button>
<button class="btn btn-sm btn-warning">-30'</button>
<button class="btn btn-sm btn-warning">-15'</button>
<button class="btn btn-sm btn-success">+15'</button>
<button class="btn btn-sm btn-success">+30'</button>
<button class="btn btn-sm btn-success">+1h</button>
<button class="btn btn-sm btn-success">+2h</button>
</div>
</div>
</div>
<div class="px-1 text-left textTrim flex-fill">
<div class="text-dark" title="Steamware - ORG Personale"><b>St...</b> - OR...</div>
<div class="text-secondary" title="Mail">Mail</div>
<div class="small" title="-">-</div>
</div>
</div>
</div><div class="py-0 small flex-fill border border-info rounded" style="width: 30.36%">
<div class="d-flex">
<div class="dropdown">
<button class="dropbtn px-1 text-center border border-secondary border-top-0 border-bottom-0 border-left-0 btn btn-info btn-sm" style="font-size: 0.72rem;">
<div>08:15</div>
<div>12:30</div>
<div class="badge badge-dark">4h 15'</div>
</button><div class="dropdown-content border border-dark table-dark text-light rounded p-2">
<div class="row">
<div class="col-9 pr-0">
<div class="text-light text-left"><b>SteamSW</b> - <span class="small">GPW</span></div>
<div class="text-info text-left" title="sviluppo">sviluppo</div>
</div>
<div class="col-3">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="switch-87131" title="Modifica Fine" value="">
<label class="custom-control-label small" for="switch-87131">Fine</label>
</div>
</div>
</div>
<div class="btn-group btn-group-sm w-100 py-2">
<button class="btn btn-sm btn-info"><i class="fas fa-pencil-alt"></i> Edit</button>
<button class="btn btn-sm btn-primary"><i class="far fa-copy"></i> Copy</button>
<button class="btn btn-sm btn-danger"><i class="fas fa-trash-alt"></i> Delete</button>
</div>
<div class="btn-group btn-group-sm w-100 small">
<button class="btn btn-sm btn-warning">-2h</button>
<button class="btn btn-sm btn-warning">-1h</button>
<button class="btn btn-sm btn-warning">-30'</button>
<button class="btn btn-sm btn-warning">-15'</button>
<button class="btn btn-sm btn-success">+15'</button>
<button class="btn btn-sm btn-success">+30'</button>
<button class="btn btn-sm btn-success">+1h</button>
<button class="btn btn-sm btn-success">+2h</button>
</div>
</div>
</div>
<div class="px-1 text-left textTrim flex-fill">
<div class="text-dark" title="SteamSW - GPW"><b>SteamSW</b> - GPW</div>
<div class="text-secondary" title="sviluppo">sviluppo</div>
<div class="small" title="Continuo sviluppo editing">Continuo sviluppo editing</div>
</div>
</div>
</div><div class="py-0 small flex-fill " style="width: 10.71%"><div class="d-flex"><div class="px-1 small textTrim"><button class="px-1 text-center btn btn-lg btn-outline-success"><i class="fas fa-plus-circle"></i></button></div></div></div><div class="py-0 small flex-fill border border-info rounded" style="width: 44.64%">
<div class="d-flex">
<div class="dropdown">
<button class="dropbtn px-1 text-center border border-secondary border-top-0 border-bottom-0 border-left-0 btn btn-info btn-sm" style="font-size: 0.72rem;">
<div>14:00</div>
<div>20:15</div>
<div class="badge badge-dark">6h 15'</div>
</button><div class="dropdown-content border border-dark table-dark text-light rounded p-2">
<div class="row">
<div class="col-9 pr-0">
<div class="text-light text-left"><b>SteamSW</b> - <span class="small">GPW</span></div>
<div class="text-info text-left" title="sviluppo">sviluppo</div>
</div>
<div class="col-3">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="switch-87143" title="Modifica Fine" value="">
<label class="custom-control-label small" for="switch-87143">Fine</label>
</div>
</div>
</div>
<div class="btn-group btn-group-sm w-100 py-2">
<button class="btn btn-sm btn-info"><i class="fas fa-pencil-alt"></i> Edit</button>
<button class="btn btn-sm btn-primary"><i class="far fa-copy"></i> Copy</button>
<button class="btn btn-sm btn-danger"><i class="fas fa-trash-alt"></i> Delete</button>
</div>
<div class="btn-group btn-group-sm w-100 small">
<button class="btn btn-sm btn-warning">-2h</button>
<button class="btn btn-sm btn-warning">-1h</button>
<button class="btn btn-sm btn-warning">-30'</button>
<button class="btn btn-sm btn-warning">-15'</button>
<button class="btn btn-sm btn-success">+15'</button>
<button class="btn btn-sm btn-success">+30'</button>
<button class="btn btn-sm btn-success">+1h</button>
<button class="btn btn-sm btn-success">+2h</button>
</div>
</div>
</div>
<div class="px-1 text-left textTrim flex-fill">
<div class="text-dark" title="SteamSW - GPW"><b>SteamSW</b> - GPW</div>
<div class="text-secondary" title="sviluppo">sviluppo</div>
<div class="small" title="Continuo sviluppo editing">Continuo sviluppo editing</div>
</div>
</div>
</div><div class="py-0 small flex-fill " style="width: 5.36%"><div class="d-flex"><div class="px-1 small textTrim"><button class="px-1 text-center btn btn-lg btn-outline-success"><i class="fas fa-plus-circle"></i></button></div></div></div>
</div>
</div>
<div class="p-1 flex-fill text-left">
<div class="d-flex justify-content-between text-center">
<div class="py-0 small flex-fill " style="width: 5.36%">
<div class="d-flex"><div class="px-1 small textTrim"><button class="px-1 text-center btn btn-lg btn-outline-success"><i class="fas fa-plus-circle"></i></button></div></div>
</div>
<div class="py-0 small flex-fill border border-info rounded" style="width: 13.57%">
<div class="d-flex">
<div class="dropdown">
<button class="dropbtn px-1 text-center border border-secondary border-top-0 border-bottom-0 border-left-0 btn btn-info btn-sm" style="font-size: 0.72rem;">
<div>07</div>
<div>45</div>
<div class="badge badge-dark">30'</div>
</button>
<div class="dropdown-content border border-dark table-dark text-light rounded p-2">
<div class="row">
<div class="col-9 pr-0">
<div class="text-light text-left"><b>Steamware</b> - <span class="small">ORG Personale</span></div>
<div class="text-info text-left" title="Mail">Mail</div>
</div>
<div class="col-3">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="switch-87105" title="Modifica Fine" value="">
<label class="custom-control-label small" for="switch-87105">Fine</label>
</div>
</div>
</div>
<div class="btn-group btn-group-sm w-100 py-2">
<button class="btn btn-sm btn-info"><i class="fas fa-pencil-alt"></i> Edit</button>
<button class="btn btn-sm btn-primary"><i class="far fa-copy"></i> Copy</button>
<button class="btn btn-sm btn-danger"><i class="fas fa-trash-alt"></i> Delete</button>
</div>
<div class="btn-group btn-group-sm w-100 small">
<button class="btn btn-sm btn-warning">-2h</button>
<button class="btn btn-sm btn-warning">-1h</button>
<button class="btn btn-sm btn-warning">-30'</button>
<button class="btn btn-sm btn-warning">-15'</button>
<button class="btn btn-sm btn-success">+15'</button>
<button class="btn btn-sm btn-success">+30'</button>
<button class="btn btn-sm btn-success">+1h</button>
<button class="btn btn-sm btn-success">+2h</button>
</div>
</div>
</div>
<div class="px-1 text-left textTrim flex-fill">
<div class="text-dark" title="Steamware - ORG Personale"><b>St...</b> - OR...</div>
<div class="text-secondary" title="Mail">Mail</div>
<div class="small" title="-">-</div>
</div>
</div>
</div>
<div class="py-0 small flex-fill border border-info rounded" style="width: 30.36%; z-index:1; position: relative; left: -5%; top: 10px;">
<div class="d-flex">
<div class="dropdown">
<button class="dropbtn px-1 text-center border border-secondary border-top-0 border-bottom-0 border-left-0 btn btn-info btn-sm" style="font-size: 0.72rem;">
<div>08:15</div>
<div>12:30</div>
<div class="badge badge-dark">4h 15'</div>
</button><div class="dropdown-content border border-dark table-dark text-light rounded p-2">
<div class="row">
<div class="col-9 pr-0">
<div class="text-light text-left"><b>SteamSW</b> - <span class="small">GPW</span></div>
<div class="text-info text-left" title="sviluppo">sviluppo</div>
</div>
<div class="col-3">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="switch-87131" title="Modifica Fine" value="">
<label class="custom-control-label small" for="switch-87131">Fine</label>
</div>
</div>
</div>
<div class="btn-group btn-group-sm w-100 py-2">
<button class="btn btn-sm btn-info"><i class="fas fa-pencil-alt"></i> Edit</button>
<button class="btn btn-sm btn-primary"><i class="far fa-copy"></i> Copy</button>
<button class="btn btn-sm btn-danger"><i class="fas fa-trash-alt"></i> Delete</button>
</div>
<div class="btn-group btn-group-sm w-100 small">
<button class="btn btn-sm btn-warning">-2h</button>
<button class="btn btn-sm btn-warning">-1h</button>
<button class="btn btn-sm btn-warning">-30'</button>
<button class="btn btn-sm btn-warning">-15'</button>
<button class="btn btn-sm btn-success">+15'</button>
<button class="btn btn-sm btn-success">+30'</button>
<button class="btn btn-sm btn-success">+1h</button>
<button class="btn btn-sm btn-success">+2h</button>
</div>
</div>
</div>
<div class="px-1 text-left textTrim flex-fill bg-light">
<div class="text-dark" title="SteamSW - GPW"><b>SteamSW</b> - GPW</div>
<div class="text-secondary" title="sviluppo">sviluppo</div>
<div class="small" title="Continuo sviluppo editing">Continuo sviluppo editing</div>
</div>
</div>
</div><div class="py-0 small flex-fill " style="width: 10.71%"><div class="d-flex"><div class="px-1 small textTrim"><button class="px-1 text-center btn btn-lg btn-outline-success"><i class="fas fa-plus-circle"></i></button></div></div></div><div class="py-0 small flex-fill border border-info rounded" style="width: 44.64%">
<div class="d-flex">
<div class="dropdown">
<button class="dropbtn px-1 text-center border border-secondary border-top-0 border-bottom-0 border-left-0 btn btn-info btn-sm" style="font-size: 0.72rem;">
<div>14:00</div>
<div>20:15</div>
<div class="badge badge-dark">6h 15'</div>
</button><div class="dropdown-content border border-dark table-dark text-light rounded p-2">
<div class="row">
<div class="col-9 pr-0">
<div class="text-light text-left"><b>SteamSW</b> - <span class="small">GPW</span></div>
<div class="text-info text-left" title="sviluppo">sviluppo</div>
</div>
<div class="col-3">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="switch-87143" title="Modifica Fine" value="">
<label class="custom-control-label small" for="switch-87143">Fine</label>
</div>
</div>
</div>
<div class="btn-group btn-group-sm w-100 py-2">
<button class="btn btn-sm btn-info"><i class="fas fa-pencil-alt"></i> Edit</button>
<button class="btn btn-sm btn-primary"><i class="far fa-copy"></i> Copy</button>
<button class="btn btn-sm btn-danger"><i class="fas fa-trash-alt"></i> Delete</button>
</div>
<div class="btn-group btn-group-sm w-100 small">
<button class="btn btn-sm btn-warning">-2h</button>
<button class="btn btn-sm btn-warning">-1h</button>
<button class="btn btn-sm btn-warning">-30'</button>
<button class="btn btn-sm btn-warning">-15'</button>
<button class="btn btn-sm btn-success">+15'</button>
<button class="btn btn-sm btn-success">+30'</button>
<button class="btn btn-sm btn-success">+1h</button>
<button class="btn btn-sm btn-success">+2h</button>
</div>
</div>
</div>
<div class="px-1 text-left textTrim flex-fill">
<div class="text-dark" title="SteamSW - GPW"><b>SteamSW</b> - GPW</div>
<div class="text-secondary" title="sviluppo">sviluppo</div>
<div class="small" title="Continuo sviluppo editing">Continuo sviluppo editing</div>
</div>
</div>
</div><div class="py-0 small flex-fill " style="width: 5.36%"><div class="d-flex"><div class="px-1 small textTrim"><button class="px-1 text-center btn btn-lg btn-outline-success"><i class="fas fa-plus-circle"></i></button></div></div></div>
</div>
</div>*@
<style>
.containerTest {
width: 100%;
height: 6rem;
position: relative;
margin: 0px;
}
.box {
height: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 1;
}
.overlay {
z-index: 5;
}
.overlay:hover {
z-index: +100;
opacity: 1;
}
</style>
<div class="containerTest table-secondary">
<div class="box bg-primary overlay" style="width: 35%;">Testo 1</div>
<div class="box bg-secondary overlay" style="width: 25%; left: 20%; top: 10%;">Testo 2</div>
<div class="box bg-primary overlay" style="width: 20%; left: 40%; top: 0%;">Testo 3</div>
<div class="box bg-secondary overlay" style="width: 25%; left: 55%; top: 10%;">Testo 4</div>
</div>
@*<div class="card">
<div class="card-header table-primary pb-0 mb-0">
<h2>Fasi</h2>
</div>
<div class="card-body">
@if (ListRecords == null)
{
<LoadingData></LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-warning text-center display-4">No Record Found</div>
}
else
{
<div class="row">
<div class="col-12">
<table class="table table-sm table-striped">
<thead>
<tr>
<th>ID</th>
<th>Cod</th>
<th>Nome</th>
<th class="text-right">Descrizione</th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr>
<td>
<span>P<b>@record.IdxProgetto</b> | @record.IdxFase (&larr; @record.IdxFaseAncest)</span>
</td>
<td>
<span><b>@record.CodFase</b></span>
</td>
<td>
<span>@record.NomeFase</span>
</td>
<td class="text-right">
@record.DescrizioneFase
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
</div>
<div class="card-footer p-1">
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>*@
-167
View File
@@ -1,167 +0,0 @@
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.UI;
using GPW.CORE.UI.Shared;
using GPW.CORE.UI.Components;
using GPW.CORE.Data.DbModels;
using GPW.CORE.UI.Data;
namespace GPW.CORE.UI.Pages
{
public partial class Test : ComponentBase, IDisposable
{
#region Private Fields
private List<AnagFasiModel> ListRecords = null!;
private List<AnagFasiModel> SearchRecords = null!;
#endregion Private Fields
#region Private Properties
private int _currPage { get; set; } = 1;
private int _numRecord { get; set; } = 10;
private int currPage
{
get => _currPage;
set
{
if (_currPage != value)
{
_currPage = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
private bool isLoading { get; set; } = false;
private int IdxDipSel = 0;
[Inject]
private NavigationManager NavManager { get; set; } = null!;
private int numRecord
{
get => _numRecord;
set
{
if (_numRecord != value)
{
_numRecord = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
#endregion Private Properties
#region Protected Properties
[Inject]
protected MessageService AppMService { get; set; } = null!;
[Inject]
protected GpwDataService DataService { get; set; } = null!;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
protected int totalCount
{
get
{
int answ = 0;
if (SearchRecords != null)
{
answ = SearchRecords.Count;
}
return answ;
}
}
protected List<chartJsData.chartJsTSerie> getTsData()
{
List<chartJsData.chartJsTSerie> answ = new List<chartJsData.chartJsTSerie>();
DateTime dtCurs = DateTime.Now.AddDays(-120);
Random rnd = new Random();
for (int i = 0; i < 60; i++)
{
answ.Add(new chartJsData.chartJsTSerie() { x = dtCurs, y = (decimal)(360 + rnd.Next(-5, 12)) / 10 });
dtCurs = dtCurs.AddDays(rnd.Next(1,4));
}
return answ;
}
#endregion Protected Properties
#region Private Methods
private async Task ReloadData()
{
isLoading = true;
SearchRecords = await DataService.AnagFasiAll();
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
isLoading = false;
}
#endregion Private Methods
#region Protected Methods
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
}
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
protected void ResetData()
{
//DataService.rollBackEdit(currRecord);
}
protected void Select(DipendentiModel selRecord)
{
IdxDipSel = selRecord.IdxDipendente;
//// rimando a remnants
//NavManager.NavigateTo($"Remnants");
}
#endregion Protected Methods
#region Public Methods
public void Dispose()
{
//AppMService.EA_SearchUpdated -= OnSeachUpdated;
}
#endregion Public Methods
}
}
-10
View File
@@ -1,10 +0,0 @@
@page "/"
@namespace GPW.CORE.UI.Pages
@using Microsoft.AspNetCore.Authorization
@attribute [AllowAnonymous]
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_Layout";
}
<component type="typeof(App)" render-mode="ServerPrerendered" />
-38
View File
@@ -1,38 +0,0 @@
@using Microsoft.AspNetCore.Components.Web
@namespace GPW.CORE.UI.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="it-it">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="~/" />
<link rel="stylesheet" href="lib/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet"href="css/site.css" />
<link rel="stylesheet"href="lib/font-awesome/css/all.css" />
<link rel="stylesheet"href="GPW.CORE.UI.styles.css" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
@RenderBody()
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.server.js"></script>
<script src="lib/Chart.js/chart.js"></script>
<script src="lib/luxon/luxon.js"></script>
<script src="lib/chartjs-adapter-luxon/chartjs-adapter-luxon.js"></script>
<script src="lib/chartBoot.js"></script>
</body>
</html>
-53
View File
@@ -1,53 +0,0 @@
using GPW.CORE.UI.Data;
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy.
options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddStackExchangeRedisCache(options =>
{
options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions() { KeepAlive = 180, DefaultDatabase = 15, EndPoints = { { "localhost", 6379 } } };
options.InstanceName = "GPW-CORE:";
});
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<GpwDataService>();
builder.Services.AddSingleton<LicenseService>();
builder.Services.AddScoped<MessageService>();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>e4229ee4-ed4f-4507-8058-b01dc3ca1b28</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://IIS01.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/GPW/CORE.WRKLOG</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
<UserName>jenkins</UserName>
<_SavePWD>True</_SavePWD>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>e4229ee4-ed4f-4507-8058-b01dc3ca1b28</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://IIS02.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/GPW/CORE.WRKLOG</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
<UserName>jenkins</UserName>
<_SavePWD>True</_SavePWD>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AllowUntrustedCertificate>true</AllowUntrustedCertificate>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>https://office.egalware.com/GPW/CORE.WRKLOG</SiteUrlToLaunchAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>e4229ee4-ed4f-4507-8058-b01dc3ca1b28</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://office.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>office.egalware.com/GPW/CORE.WRKLOG</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<EnableMsDeployAppOffline>True</EnableMsDeployAppOffline>
<UserName>jenkins</UserName>
<_SavePWD>True</_SavePWD>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
@@ -1,28 +0,0 @@
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:46448",
"sslPort": 44369
}
},
"profiles": {
"GPW.CORE.UI": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7211;http://localhost:5211",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
-170
View File
@@ -1,170 +0,0 @@
@using CORE.Data.DbModels
@using UI.Data
@using Microsoft.AspNetCore.Identity
@inject MessageService AppMServ
@inject LicenseService LicServ
@inject GpwDataService GDataServ
@inject AuthenticationStateProvider AuthenticationStateProvider
<AuthorizeView>
<div class="d-flex">
<div class="px-1"><b>@userName</b></div>
<div class="px-1">
<button class="btn btn-sm btn-outline-dark" @onclick="() => DoReloadUtente()">
<i class="fas fa-user @cssActive" title="Attivazione Utente"></i>
</button>
</div>
<div class="px-1">
<button class="btn btn-sm btn-outline-dark" @onclick="() => DoVerifyActiv()">
<i class="fas fa-address-card @cssLicOk" title="Licenza assegnata"></i>
</button>
</div>
</div>
</AuthorizeView>
@code {
[Inject]
private NavigationManager NavManager { get; set; } = null!;
private string userName = "";
protected override async Task OnInitializedAsync()
{
//effettuo eventuale recupero dati dipendente
if (AppMServ.RigaDip == null)
{
await LoadUtente();
}
// verifica attivazione
await VerifyActiv();
}
protected async Task DoReloadUtente()
{
AppMServ.RigaDip = null;
await Task.Delay(250);
await LoadUtente();
// verifico attivazione dipendente...
await checkUserLicense();
}
protected async Task DoVerifyActiv()
{
AppMServ.PayloadOk = false;
await Task.Delay(250);
await VerifyActiv();
}
protected async Task LoadUtente()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
// verifico se ho utente loggato...
if (user.Identity != null && user.Identity.IsAuthenticated)
{
userName = $"{user.Identity.Name}";
// cerco su DB
var listaDip = await GDataServ.DipendentiGetAll();
DipendentiModel? rigaDip = listaDip
.Where(x => $"{x.Dominio}\\{x.Utente}".ToLower() == userName.ToLower())
.FirstOrDefault();
if (rigaDip != null)
{
// salvo riga info dipendente
AppMServ.RigaDip = rigaDip;
userName = $"{rigaDip.Cognome} {rigaDip.Nome}";
}
}
else
{
userName = "N.A.";
}
}
protected async Task VerifyActiv()
{
// preliminarmente verifica shared info
await checkSharedInfo();
// refresh attivazioni se necessario
await checkActivations();
// verifico e salvo dati attivazione dipendente...
await checkUserLicense();
}
/// <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 = GDataServ.CodApp;
// effettuo lettura dati preliminari da AKV (eventualmente in cache...)
List<AnagKeyValueModel> rawAkvList = await GDataServ.AKVList();
if (rawAkvList != null)
{
LicServ.AKVList = rawAkvList;
allOk = LicServ.InitAkv();
}
}
await Task.Delay(1);
return allOk;
}
/// <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 info specifiche utente
/// </summary>
/// <returns></returns>
protected async Task<bool> checkUserLicense()
{
bool answ = false;
// verifico utente attivo
answ = AppMServ.IsActive;
if (answ)
{
var rawActList = LicServ.ActivList;
// recupero hash utente
string hashImpiego = AppMServ.HashDip;
// confronto con elenco attivazioni dello shared service...
var foundRec = rawActList.Where(x => x.CodImpiego == hashImpiego);
answ = foundRec.Count() > 0;
// salvo status payloadOk
AppMServ.PayloadOk = answ;
}
await Task.Delay(1);
return answ;
}
protected string cssActive
{
get => AppMServ.IsActive ? "text-success" : "text-danger";
}
protected string cssLicOk
{
get => AppMServ.PayloadOk ? "text-success" : "text-danger";
}
}
-23
View File
@@ -1,23 +0,0 @@
@inherits LayoutComponentBase
<PageTitle>GPW.CORE.UI</PageTitle>
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4 auth">
<AuthorizeView>
<LoginDisplay />
</AuthorizeView>
</div>
<article class="content pt-1">
@Body
</article>
<div class="fixed-bottom bottom-row px-2">
<CmpFooter></CmpFooter>
</div>
</main>
</div>
-77
View File
@@ -1,77 +0,0 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 20%, #3aa6ff 90%);
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a, .top-row .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
}
.top-row a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
.bottom-row {
color: #dedede;
background-color: #000000;
height: 2rem;
align-items: center;
}
@media (max-width: 640.98px) {
.top-row:not(.auth) {
display: none;
}
.top-row.auth {
justify-content: space-between;
}
.top-row a, .top-row .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
-49
View File
@@ -1,49 +0,0 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">GPW.CORE.UI</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="FastRec">
<span class="fas fa-thumbtack pr-3" aria-hidden="true"></span> Fast Rec
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="Planner">
<span class="oi oi-media-play" aria-hidden="true"></span> Planner
</NavLink>
</div>
@*<div class="nav-item px-3">
<NavLink class="nav-link" href="ActivityLog">
<span class="oi oi-list" aria-hidden="true"></span> Activity Log
</NavLink>
</div>*@
<div class="nav-item px-3">
<NavLink class="nav-link" href="ForceReset">
<span class="fas fa-sync-alt pr-3" aria-hidden="true"></span> Reset
</NavLink>
</div>
</nav>
</div>
@code {
private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
-62
View File
@@ -1,62 +0,0 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.25);
color: white;
}
.nav-item ::deep a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}
-11
View File
@@ -1,11 +0,0 @@
@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.UI
@using GPW.CORE.UI.Shared
@using GPW.CORE.UI.Components

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