Ancora spostamento
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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 "bloccato" (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 >= 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; }
|
||||
}
|
||||
}
|
||||
@@ -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!;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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> </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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<h3>WeekPlanner</h3>
|
||||
|
||||
@code {
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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};";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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:
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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 (← @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>*@
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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" />
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user