Compare commits

...

112 Commits

Author SHA1 Message Date
Samuele Locatelli d8978f84f3 Merge branch 'Release/UpdateOdlStatsModal' 2022-10-14 17:42:54 +02:00
Samuele Locatelli 946f157cff Pulizia codice 2022-10-14 17:41:50 +02:00
Samuele Locatelli 47f1ae5cb2 Completo fix plot ODL x chiusura modale 2022-10-14 17:35:56 +02:00
Samuele Locatelli a428ecb4ab Fix overlay donught 2022-10-14 17:27:55 +02:00
zaccaria.majid c4b6f289af modifiche grafiche richieste 2022-10-14 16:54:41 +02:00
zaccaria.majid 1cc90d2459 minor fix 2022-10-14 13:08:32 +02:00
zaccaria.majid e438fa3930 minor fix 2022-10-14 12:47:13 +02:00
zaccaria.majid 6c88e2687a fix plot odl + modifiche grafiche 2022-10-14 12:39:43 +02:00
zaccaria.majid fba6eca9cc Minor fix 2022-10-13 09:30:43 +02:00
zaccaria.majid 330e208866 Minor fix 2022-10-12 15:27:10 +02:00
zaccaria.majid 013b21e055 Fix serializzazione valori edit 2022-10-12 11:48:51 +02:00
Samuele Locatelli 8e763e52a4 update metodo DTO da testare 2022-10-12 06:26:04 +02:00
Samuele Locatelli d5f5cf9b11 FluxLogDTO:
- Update modello dati x gestione nuovo DTO
- bozza udpatre DB e servizio
2022-10-12 06:20:54 +02:00
Samuele Locatelli a4810826f8 Aggiunta metodo x copiare ODL in SEND + trad valori 2022-10-11 20:56:51 +02:00
zaccaria.majid 7f3a73ba0e bozza Metodo Update 2022-10-11 17:34:02 +02:00
zaccaria.majid d108b74f7d test grafico x valori modificati 2022-10-11 16:52:11 +02:00
zaccaria.majid 16278b6ae0 pescaggio e clonazione flusso scelto 2022-10-11 13:03:56 +02:00
zaccaria.majid 1f10e8537d Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-11 09:16:42 +02:00
Samuele E. Locatelli a6408ba2af Merge tag 'UpdateMain221010' into develop
Update di riallineamento
2022-10-11 08:02:06 +02:00
Samuele E. Locatelli 924a5017f5 Merge branch 'release/UpdateMain221010' 2022-10-11 08:01:04 +02:00
zaccaria.majid 5bcc32023a fix plot 2022-10-10 17:55:53 +02:00
zaccaria.majid e87d14bd8a Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-10 17:14:39 +02:00
zaccaria.majid cbaa16a850 Merge branch 'FeatureODLPlot' into develop 2022-10-10 17:12:27 +02:00
zaccaria.majid cc272cac29 Plot ODL 2022-10-10 17:12:09 +02:00
zaccaria.majid b032b6bbb9 Primo ODL PLOT da fixare 2022-10-10 13:15:42 +02:00
Samuele Locatelli 91174a2f67 Merge remote-tracking branch 'origin/develop' into develop 2022-10-10 12:05:20 +02:00
Samuele Locatelli 2a96b63f17 PODL:
- aggiunto chiamate x syncDbData post delete o update
2022-10-10 12:05:11 +02:00
Samuele Locatelli 08634b5656 Aggiunta servizio x chiamate API REST ad MP-IO 2022-10-10 11:54:03 +02:00
zaccaria.majid 5d63c41cf8 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-10 10:11:40 +02:00
zaccaria.majid de3ce0f114 inizio odl Plot 2022-10-10 10:11:02 +02:00
Samuele Locatelli 2ec29bbe68 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-10 09:55:42 +02:00
Samuele Locatelli 7416f6e7b5 Bozza dettaglio stat con modale 2022-10-10 09:55:39 +02:00
zaccaria.majid a604e5741b minor fix 2022-10-10 09:03:32 +02:00
Samuele Locatelli 923094054b fix key model 2022-10-10 08:40:34 +02:00
Samuele Locatelli c28dae0c8d SPEC, statistiche ODL:
-aggiunta model e controllo x recupero stat da stored
2022-10-08 17:47:47 +02:00
Samuele Locatelli 6fb9cbe085 update displayODL 2022-10-07 18:50:08 +02:00
Samuele Locatelli 4f03661182 Update minori pagina ODL 2022-10-07 18:43:32 +02:00
Samuele Locatelli dd26773590 Merge remote-tracking branch 'origin/develop' into develop 2022-10-07 18:33:10 +02:00
Samuele Locatelli 75894fa3c7 update ordinamento fluxlog 2022-10-07 18:32:56 +02:00
zaccaria.majid 9fc73c5c85 modifiche richieste 2022-10-07 18:30:53 +02:00
Samuele Locatelli 0f9c01ae82 Update grafico e calcolo durata ODL 2022-10-07 17:20:35 +02:00
Samuele Locatelli ea60e785f9 Update fix x ODL con filtri nuovi 2022-10-07 16:58:33 +02:00
Samuele Locatelli 1849101028 inizio modifica pagina ODL x SPEC 2022-10-07 16:14:29 +02:00
Samuele Locatelli a1f9a958b3 Fix errore compilaizone stats 2022-10-07 16:14:22 +02:00
zaccaria.majid fd585aee93 modifiche richieste 2022-10-07 15:14:57 +02:00
zaccaria.majid 4ecd647b1b modifiche richieste 2022-10-07 14:43:00 +02:00
zaccaria.majid 8aace3fb82 Minor fix 2022-10-07 12:00:37 +02:00
zaccaria.majid 4acf2a2970 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-07 11:16:41 +02:00
zaccaria.majid 9b6c449354 Fix grafici richiesti 2022-10-07 11:16:02 +02:00
Samuele Locatelli c11e05123d Fix display label x filtro parametri 2022-10-07 08:41:45 +02:00
zaccaria.majid 862960bae4 minor fix 2022-10-06 17:47:40 +02:00
zaccaria.majid 4cdf0033cd fix index 2022-10-06 17:32:32 +02:00
zaccaria.majid 25b75101e9 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-06 17:24:49 +02:00
zaccaria.majid 50dbe7691f minor fix 2022-10-06 17:24:43 +02:00
Samuele Locatelli 9c762969ac Merge remote-tracking branch 'origin/develop' into develop 2022-10-06 16:30:59 +02:00
Samuele Locatelli 09b2008f25 Update classe dossier 2022-10-06 16:30:54 +02:00
zaccaria.majid baa42fbd2f Merge branch 'FeatureParametersFilter' into develop 2022-10-06 16:28:14 +02:00
zaccaria.majid 90d4a46087 Fine fix filtri params e dossier 2022-10-06 16:27:49 +02:00
zaccaria.majid 5b12ac47d3 update Filter 2022-10-06 13:10:12 +02:00
zaccaria.majid 81fd2820df Params filter con dots INIZIO 2022-10-05 17:39:51 +02:00
Samuele Locatelli 624d6d3411 minor refresh x display trad articolo/macchina 2022-10-05 16:46:56 +02:00
zaccaria.majid 21fa81f09c fix grafico filtri Dossier 2022-10-05 16:34:22 +02:00
zaccaria.majid 0795cae1d5 Aggiunta filtro per articolo
+ fix lettura da redis dossiers
2022-10-05 15:46:59 +02:00
Samuele Locatelli 6a0eeba75f Bozza metodo selezione x articolo 2022-10-05 14:45:29 +02:00
Samuele Locatelli b476829a73 Merge branch 'develop' 2022-10-05 11:13:46 +02:00
Samuele Locatelli 78c90a8e93 Update ODL come PODL 2022-10-05 11:12:51 +02:00
Samuele Locatelli 9515906e20 Merge branch 'master' into develop 2022-10-05 11:04:42 +02:00
Samuele Locatelli c929e3cf65 Merge branch 'Release/FixPodlAndSnapshotBaglietto' 2022-10-05 11:04:31 +02:00
Samuele Locatelli 43f0569fe3 Fix flush + reload home 2022-10-05 11:03:18 +02:00
Samuele Locatelli 2807bd9edc Merge remote-tracking branch 'origin/develop' into develop 2022-10-05 10:59:42 +02:00
Samuele Locatelli c4a682cc24 Gestione snapshot
- anticipo parametricod a tab config
2022-10-05 10:58:49 +02:00
zaccaria.majid 5ef3139bd5 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-05 10:53:30 +02:00
zaccaria.majid 2a679504eb fix selRecord + fix grafico toggle att 2022-10-05 10:53:17 +02:00
Samuele Locatelli 10f9ed08a8 Fix query anticipo a 24h 2022-10-05 10:47:57 +02:00
Samuele Locatelli 374902d5f0 Merge branch 'Feature/AddPodlClone' into develop 2022-10-05 10:24:30 +02:00
Samuele Locatelli 59b43f6005 Update pagina PODL 2022-10-05 10:24:19 +02:00
zaccaria.majid 1ad6222543 Aggiunta selezione data minima in PARAMETERS 2022-09-28 09:10:52 +02:00
Samuele Locatelli b97394b067 Aggiunta duplicazione articoli 2022-09-27 18:47:47 +02:00
Samuele Locatelli 9d35441b07 Merge branch 'develop' into Feature/AddPodlClone 2022-09-27 18:28:28 +02:00
Samuele Locatelli f71ec80c16 Aggiunta duplicazione riga 2022-09-27 18:27:46 +02:00
Samuele Locatelli d1b6c804be Aggiunta editing note 2022-09-27 18:14:40 +02:00
Samuele Locatelli 391078dd06 Aggiunto edit numpz e TCiclo 2022-09-27 18:08:17 +02:00
zaccaria.majid 55c6790d7b update per takesnapshotList 2022-09-27 18:03:36 +02:00
zaccaria.majid 66642032bf Merge branch 'develop' 2022-09-27 16:40:09 +02:00
Samuele Locatelli da76bc96f8 Update display dati dossier 2022-09-27 16:19:40 +02:00
zaccaria.majid 23fbacba87 Fix lettura da cache 2022-09-27 14:27:24 +02:00
Samuele Locatelli b9d67616cb Merge branch 'develop' 2022-09-27 12:01:32 +02:00
Samuele Locatelli 79da055771 Fix filtraggio record ODL 2022-09-27 12:01:25 +02:00
Samuele Locatelli 7e879fe2f6 Merge tag 'UpdateDossierHistSnapshot' into develop
Fix dossier management:
- delete dossiers
- possibilità snapshot valori apssati
2022-09-27 11:43:58 +02:00
Samuele Locatelli 95e83f7d56 Merge branch 'Release/UpdateDossierHistSnapshot' 2022-09-27 11:43:40 +02:00
Samuele Locatelli 0efe322f7a Pagine con molti record nascoste (footer):
- Update cards x avere margine mb-5
2022-09-27 11:43:04 +02:00
zaccaria.majid 3bc3746a9d Fix scomparsa bottone snapshot fatto 2022-09-27 11:36:51 +02:00
Samuele Locatelli 08901bcebc Riduzione numero chiamate x update parametri 2022-09-27 11:03:55 +02:00
Samuele Locatelli 4d481699a1 Ok selezione e filtraggio parametri 2022-09-27 10:57:45 +02:00
Samuele Locatelli 3efeb994cf Fix selezione data max x filtro parametri 2022-09-27 10:34:24 +02:00
Samuele Locatelli 5014bb1ecb Inizio gestione filtro parametri con data max 2022-09-27 09:47:41 +02:00
Samuele Locatelli 523b1683d9 Metodi cancellazione dossier (2 test) 2022-09-27 08:20:40 +02:00
Samuele Locatelli 35c0f2856d Prima bozza con salvataggio live e storico... 2022-09-26 20:03:05 +02:00
Samuele Locatelli 77457df40a Update numero maxRecord gestiti (fino a 5000) 2022-09-26 19:35:26 +02:00
Samuele Locatelli add4fe13fa Inizio update selezione parametri 2022-09-26 19:31:55 +02:00
zaccaria.majid b748c76cad fix 2022-09-23 08:33:24 +02:00
Samuele Locatelli 279d2799ae Merge tag 'consolidateNuget220921' into develop
Fix/consolidate nuget pack x progetti MON / STATS
2022-09-21 18:36:21 +02:00
Samuele Locatelli 198d18002b Merge branch 'Release/consolidateNuget220921' 2022-09-21 18:36:10 +02:00
Samuele Locatelli 838ebe55da Fix nuget
- progetti CORE MON/STATS aggiornati
- consolidamenti nuget
2022-09-21 18:35:41 +02:00
Samuele Locatelli f58253341f Merge tag '220921_FixAndNugetUpdate' into develop
Fix vari (es paginazione dossier) + nuget update generale
2022-09-21 14:53:20 +02:00
Samuele Locatelli 4644646fa4 Merge branch 'Release/220921_FixAndNugetUpdate' 2022-09-21 14:53:05 +02:00
Samuele Locatelli c3c5300830 Nuget Update:
- nlog
- newtonsoft json
2022-09-21 14:52:25 +02:00
Samuele Locatelli ebeeab69e1 Nuget Update: dotNet framework 2022-09-21 14:50:56 +02:00
Samuele Locatelli 2a41e8070b CodeMaid
- fix componenti UI
- lasciati invariati in area wwwroot
2022-09-21 14:49:45 +02:00
Samuele Locatelli 3a5b77314a CodeMaid:
- DTO e MOdelli NON riorganizzabili
- refresh globale ordinamenti
- test rebuild
2022-09-21 14:45:57 +02:00
zaccaria.majid 16c7b0bc6b modifiche grafiche + fix paginazione 2022-09-21 14:21:22 +02:00
Samuele Locatelli 46f284ae0c Merge tag 'FirstSpecStableRelease' into develop
Prima release master con fix vari grafici + tutte le funzionalità
2022-09-21 10:36:57 +02:00
120 changed files with 27106 additions and 828 deletions
+6 -6
View File
@@ -9,18 +9,18 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.6">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.6">
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NLog" Version="5.0.1" />
<PackageReference Include="NLog" Version="5.0.4" />
</ItemGroup>
<ItemGroup>
+6 -6
View File
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace MP.Data.Conf
{
@@ -11,9 +7,13 @@ namespace MP.Data.Conf
/// </summary>
public class IobTags
{
#region Public Fields
/// <summary>
/// Oggetto dizionario di configurazione x IOB
/// </summary>
public Dictionary<string, List<TagData>> IobSetup = new Dictionary<string, List<TagData>>();
#endregion Public Fields
}
}
}
+18 -12
View File
@@ -1,37 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data.Conf
namespace MP.Data.Conf
{
/// <summary>
/// Item da mostrare nei blocchi MON degli impianti come override ai dati MSE
/// </summary>
public class TagData
{
#region Public Properties
/// <summary>
/// Indice della colonna (ordine) del dato
/// </summary>
public int ColNum { get; set; } = 0;
/// <summary>
/// Indice della riga del dato
/// </summary>
public int RowNum { get; set; } = 0;
/// <summary>
/// Override CSS (es fontSmall)
/// </summary>
public string TagCss { get; set; } = "";
/// <summary>
/// Etichetta da mostrare
/// </summary>
public string TagName { get; set; } = "";
/// <summary>
/// Indicazione della chiave REDIS dove recuperare il tag indicato (già in formato string)
/// </summary>
public string TagLocation { get; set; } = "";
/// <summary>
/// Etichetta da mostrare
/// </summary>
public string TagName { get; set; } = "";
#endregion Public Properties
#region Public Methods
/// <summary>
/// Clone dell'oggetto
/// </summary>
@@ -40,5 +44,7 @@ namespace MP.Data.Conf
{
return (TagData)this.MemberwiseClone();
}
#endregion Public Methods
}
}
}
+10 -12
View File
@@ -1,21 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data
namespace MP.Data
{
public class Constants
public class Constants
{
#region Public Fields
public static readonly string ACT_BLINK_KEY = $"{BASE_HASH}:Current:Blink";
public static readonly string ACT_MSE_DATA_KEY = $"{BASE_HASH}:Current:MSE";
// dati conf REDIS Cache
public static readonly string BASE_HASH = "MAPO";
// REDIS KEY Dati correnti
public static readonly string CONF_MON_KEY = $"{BASE_HASH}:Conf:MonDispData";
public static readonly string ACT_MSE_DATA_KEY = $"{BASE_HASH}:Current:MSE";
public static readonly string ACT_BLINK_KEY = $"{BASE_HASH}:Current:Blink";
#endregion Public Fields
}
}
}
+199 -49
View File
@@ -1,10 +1,12 @@
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using MP.Data.DatabaseModels;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace MP.Data.Controllers
@@ -27,7 +29,7 @@ namespace MP.Data.Controllers
/// Elenco Gruppi tipo Azienda
/// </summary>
/// <returns></returns>
public List<DatabaseModels.AnagGruppi> AnagGruppiAziende()
public List<AnagGruppi> AnagGruppiAziende()
{
return AnagGruppiGetTipo("AZIENDA");
}
@@ -36,7 +38,7 @@ namespace MP.Data.Controllers
/// Elenco Gruppi tipo Fasi
/// </summary>
/// <returns></returns>
public List<DatabaseModels.AnagGruppi> AnagGruppiFase()
public List<AnagGruppi> AnagGruppiFase()
{
return AnagGruppiGetTipo("FASE");
}
@@ -45,9 +47,9 @@ namespace MP.Data.Controllers
/// Elenco Gruppi
/// </summary>
/// <returns></returns>
public List<DatabaseModels.AnagGruppi> AnagGruppiGetAll()
public List<AnagGruppi> AnagGruppiGetAll()
{
List<DatabaseModels.AnagGruppi> dbResult = new List<DatabaseModels.AnagGruppi>();
List<AnagGruppi> dbResult = new List<AnagGruppi>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -64,9 +66,9 @@ namespace MP.Data.Controllers
/// </summary>
/// <param name="tipoGruppo"></param>
/// <returns></returns>
public List<DatabaseModels.AnagGruppi> AnagGruppiGetTipo(string tipoGruppo)
public List<AnagGruppi> AnagGruppiGetTipo(string tipoGruppo)
{
List<DatabaseModels.AnagGruppi> dbResult = new List<DatabaseModels.AnagGruppi>();
List<AnagGruppi> dbResult = new List<AnagGruppi>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -83,7 +85,7 @@ namespace MP.Data.Controllers
/// Elenco valori ammessi x Stati commessa (es Yacht Baglietto)
/// </summary>
/// <returns></returns>
public List<DatabaseModels.ListValues> AnagStatiComm()
public List<ListValues> AnagStatiComm()
{
return ListValuesFilt("PODL", "StatoComm");
}
@@ -92,7 +94,7 @@ namespace MP.Data.Controllers
/// Elenco valori ammessi x Tipo articoli
/// </summary>
/// <returns></returns>
public List<DatabaseModels.ListValues> AnagTipoArtLV()
public List<ListValues> AnagTipoArtLV()
{
return ListValuesFilt("AnagArticoli", "Tipo");
}
@@ -102,7 +104,7 @@ namespace MP.Data.Controllers
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliDeleteRecord(DatabaseModels.AnagArticoli currRec)
public async Task<bool> ArticoliDeleteRecord(AnagArticoli currRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
@@ -133,9 +135,9 @@ namespace MP.Data.Controllers
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<DatabaseModels.AnagArticoli> ArticoliGetSearch(int numRecord, string searchVal = "")
public List<AnagArticoli> ArticoliGetSearch(int numRecord, string searchVal = "")
{
List<DatabaseModels.AnagArticoli> dbResult = new List<DatabaseModels.AnagArticoli>();
List<AnagArticoli> dbResult = new List<AnagArticoli>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -156,9 +158,9 @@ namespace MP.Data.Controllers
/// <param name="azienda"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<DatabaseModels.AnagArticoli> ArticoliGetSearch(int numRecord, string azienda = "*", string searchVal = "")
public List<AnagArticoli> ArticoliGetSearch(int numRecord, string azienda = "*", string searchVal = "")
{
List<DatabaseModels.AnagArticoli> dbResult = new List<DatabaseModels.AnagArticoli>();
List<AnagArticoli> dbResult = new List<AnagArticoli>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -176,13 +178,13 @@ namespace MP.Data.Controllers
/// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed)
/// </summary>
/// <returns></returns>
public List<DatabaseModels.AnagArticoli> ArticoliGetUsed()
public List<AnagArticoli> ArticoliGetUsed()
{
List<DatabaseModels.AnagArticoli> dbResult = new List<DatabaseModels.AnagArticoli>();
List<AnagArticoli> dbResult = new List<AnagArticoli>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetArticoli
.DbSetArticoli
.FromSqlRaw("EXEC stp_ART_getUsed")
.AsNoTracking()
.ToList();
@@ -190,12 +192,32 @@ namespace MP.Data.Controllers
return dbResult;
}
/// <summary>
/// Statistiche ODL calcolate (da stored stp_STAT_ODL)
/// </summary>
/// <returns></returns>
public async Task<List<StatODLModel>> StatOdl(int IdxOdl)
{
List<StatODLModel> dbResult = new List<StatODLModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
var IdxODL = new SqlParameter("@IdxODL", IdxOdl);
dbResult = await dbCtx
.DbSetStatOdl
.FromSqlRaw("EXEC stp_STAT_ODL @IdxODL", IdxODL)
.AsNoTracking()
.ToListAsync();
}
return dbResult;
}
/// <summary>
/// Update Record
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliUpdateRecord(DatabaseModels.AnagArticoli editRec)
public async Task<bool> ArticoliUpdateRecord(AnagArticoli editRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
@@ -235,9 +257,9 @@ namespace MP.Data.Controllers
/// Elenco da tabella Config
/// </summary>
/// <returns></returns>
public List<DatabaseModels.ConfigModel> ConfigGetAll()
public List<ConfigModel> ConfigGetAll()
{
List<DatabaseModels.ConfigModel> dbResult = new List<DatabaseModels.ConfigModel>();
List<ConfigModel> dbResult = new List<ConfigModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -253,10 +275,10 @@ namespace MP.Data.Controllers
/// Update record config
/// </summary>
/// <returns></returns>
public bool ConfigUpdate(DatabaseModels.ConfigModel updRec)
public bool ConfigUpdate(ConfigModel updRec)
{
bool fatto = false;
DatabaseModels.ConfigModel dbResult = new DatabaseModels.ConfigModel();
ConfigModel dbResult = new ConfigModel();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -277,23 +299,57 @@ namespace MP.Data.Controllers
{
}
/// <summary>
/// Eliminazione di un dossier
/// </summary>
/// <param name="currRec">record dossier da eliminare</param>
/// <returns></returns>
public async Task<bool> DossiersDeleteRecord(Dossiers currRec)
{
bool answ = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var currVal = dbCtx
.DbSetDossiers
.Where(x => x.IdxDossier == currRec.IdxDossier)
.FirstOrDefault();
dbCtx
.DbSetDossiers
.Remove(currVal);
await dbCtx.SaveChangesAsync();
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante DossiersDeleteRecord{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Elenco ultimi n record DOssiers (che contengono ad esempio "salvataggi" di FLuxLog) dato
/// macchina (ordinato x data registrazione)
/// </summary>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
/// <param name="CodArticolo">* = tutti, altrimenti solo x un dato articolo</param>
/// <param name="DtRef">Data di riferimento (Massima) per estrazioen records</param>
/// <param name="MaxRec">numero massimo record da restituire</param>
/// <returns></returns>
public List<DatabaseModels.Dossiers> DossiersGetLastFilt(string IdxMacchina, DateTime DtRef, int MaxRec)
public List<Dossiers> DossiersGetLastFilt(string IdxMacchina, string CodArticolo, DateTime DtRef, int MaxRec)
{
List<DatabaseModels.Dossiers> dbResult = new List<DatabaseModels.Dossiers>();
List<Dossiers> dbResult = new List<Dossiers>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetDossiers
.AsNoTracking()
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && x.DtRif <= DtRef)
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodArticolo == "*" || x.OdlNav.CodArticolo == CodArticolo) && x.DtRif <= DtRef)
.Include(m => m.MachineNav)
.Include(o => o.OdlNav)
.Include(a => a.OdlNav.ArticoloNav)
.OrderByDescending(x => x.DtRif)
.Take(MaxRec)
.ToList();
@@ -301,27 +357,94 @@ namespace MP.Data.Controllers
return dbResult;
}
public bool DossiersTakeParamsSnapshot(string idxMacchina, int maxSec)
/// <summary>
/// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache redis
/// </summary>
/// <param name="idxMacchina">macchina</param>
/// <param name="maxSec">Num massimo secondi per recuperare dati correnti</param>
/// <param name="dtRif">DataOra riferimento x cui prendere valori antecedenti</param>
public bool DossiersTakeParamsSnapshot(string idxMacchina, int maxSec, DateTime dtRif)
{
bool answ = false;
using (var dbCtx = new MoonProContext(_configuration))
{
var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
var pMaxSec = new SqlParameter("@MaxSec", maxSec);
var pDtRif = new SqlParameter("@DtRif", dtRif);
var dbResult = dbCtx
.Database
.ExecuteSqlRaw("EXEC stp_FL_TakeSnapshot @IdxMacchina,@MaxSec", pIdxMacchina, pMaxSec);
.ExecuteSqlRaw("EXEC stp_FL_TakeSnapshot @IdxMacchina,@MaxSec,@DtRif", pIdxMacchina, pMaxSec, pDtRif);
answ = true;
}
return answ;
}
/// <summary>
/// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache redis
/// </summary>
/// <param name="idxMacchina">macchina</param>
/// <param name="dtMin">Data min x selezione</param>
/// <param name="dtMax">Data MAX x selezione</param>
public bool DossiersTakeParamsSnapshotLast(string idxMacchina, DateTime dtMin, DateTime dtMax)
{
bool answ = false;
using (var dbCtx = new MoonProContext(_configuration))
{
var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
var pDtMin = new SqlParameter("@DtMin", dtMin);
var pDtMax = new SqlParameter("@DtMax", dtMax);
var dbResult = dbCtx
.Database
.ExecuteSqlRaw("EXEC stp_FL_TakeSnapshotLast @IdxMacchina,@DtMin,@DtMax", pIdxMacchina, pDtMin, pDtMax);
answ = true;
}
return answ;
}
/// <summary>
/// Update ddel campo VALORE di un dossier (che contiene json flux log serializzati)
/// </summary>
/// <param name="editRec">record dossier da modificare</param>
/// <returns></returns>
public async Task<bool> DossiersUpdateValore(Dossiers editRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var currRec = dbCtx
.DbSetDossiers
.Where(x => x.IdxDossier == editRec.IdxDossier)
.FirstOrDefault();
if (currRec != null)
{
currRec.Valore= editRec.Valore;
dbCtx.Entry(currRec).State = EntityState.Modified;
}
else
{
dbCtx
.DbSetDossiers
.Add(editRec);
}
await dbCtx.SaveChangesAsync();
fatto = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante DossiersUpdateRecord{Environment.NewLine}{exc}");
}
}
return fatto;
}
/// <summary>
/// Elenco valori link (x home e navMenu laterale)
/// </summary>
/// <returns></returns>
public List<DatabaseModels.LinkMenu> ElencoLink()
public List<LinkMenu> ElencoLink()
{
return ListLinkFilt("SpecLink");
}
@@ -329,19 +452,20 @@ namespace MP.Data.Controllers
/// <summary>
/// Elenco ultimi n record flux log dato macchina e flusso (ordinato x data registrazione)
/// </summary>
/// <param name="DtMax">Data massima (recupera eventi antecedenti)</param>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
/// <param name="CodFlux">*=tutti, altrimenti solo selezionato</param>
/// <param name="MaxRec">numero massimo record da restituire</param>
/// <returns></returns>
public List<DatabaseModels.FluxLog> FluxLogGetLastFilt(string IdxMacchina, string CodFlux, int MaxRec)
public List<FluxLog> FluxLogGetLastFilt(DateTime DtMax, string IdxMacchina, string CodFlux, int MaxRec)
{
List<DatabaseModels.FluxLog> dbResult = new List<DatabaseModels.FluxLog>();
List<FluxLog> dbResult = new List<FluxLog>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetFluxLog
.AsNoTracking()
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodFlux == "*" || x.CodFlux == CodFlux))
.Where(x => (x.dtEvento <= DtMax) && (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodFlux == "*" || x.CodFlux == CodFlux))
.OrderByDescending(x => x.dtEvento)
.Take(MaxRec)
.ToList();
@@ -349,9 +473,9 @@ namespace MP.Data.Controllers
return dbResult;
}
public List<DatabaseModels.LinkMenu> ListLinkFilt(string tipoLink)
public List<LinkMenu> ListLinkFilt(string tipoLink)
{
List<DatabaseModels.LinkMenu> dbResult = new List<DatabaseModels.LinkMenu>();
List<LinkMenu> dbResult = new List<LinkMenu>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -370,17 +494,21 @@ namespace MP.Data.Controllers
/// <param name="inCorso">Stato ODL: true=in corso/completato</param>
/// <param name="codArt">Cod articolo</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <param name="startDate">Data inizio</param>
/// <param name="endDate">Data fine</param>
/// <returns></returns>
public List<DatabaseModels.ODLModel> ListODLFilt(bool inCorso, string codArt, string keyRichPart)
public List<ODLModel> ListODLFilt(bool inCorso, string codArt, string keyRichPart, DateTime startDate, DateTime endDate)
{
List<DatabaseModels.ODLModel> dbResult = new List<DatabaseModels.ODLModel>();
List<ODLModel> dbResult = new List<ODLModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetODL
.Where(x => ((inCorso && x.DataFine == null) || (!inCorso && x.DataFine != null)) && (x.KeyRichiesta.Contains(keyRichPart) || keyRichPart == "*") && (codArt == "*" || x.CodArticolo.Contains(codArt)))
.Where(x => ((inCorso && x.DataFine == null) || ((!inCorso && x.DataFine != null) && x.DataInizio >= startDate && x.DataInizio <= endDate)) && (x.KeyRichiesta.Contains(keyRichPart) || keyRichPart == "*") && (codArt == "*" || x.CodArticolo.Contains(codArt)))
.AsNoTracking()
.OrderBy(x => x.IdxOdl)
.Include(m => m.MachineNav)
.Include(a => a.ArticoloNav)
.OrderByDescending(x => x.IdxOdl)
.ToList();
}
return dbResult;
@@ -392,15 +520,17 @@ namespace MP.Data.Controllers
/// <param name="codArt">Cod articolo</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <returns></returns>
public List<DatabaseModels.PODLModel> ListPODLFilt(string codArt, string keyRichPart)
public List<PODLModel> ListPODLFilt(string codArt, string keyRichPart)
{
List<DatabaseModels.PODLModel> dbResult = new List<DatabaseModels.PODLModel>();
List<PODLModel> dbResult = new List<PODLModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetPODL
.Where(x => (x.IdxOdl == 0) && (x.KeyRichiesta.Contains(keyRichPart) || keyRichPart == "*") && (codArt == "*" || x.CodArticolo.Contains(codArt)))
.AsNoTracking()
.Include(m => m.MachineNav)
.Include(a => a.ArticoloNav)
.OrderBy(x => x.InsertDate)
.ToList();
}
@@ -413,9 +543,9 @@ namespace MP.Data.Controllers
/// <param name="tabName"></param>
/// <param name="fieldName"></param>
/// <returns></returns>
public List<DatabaseModels.ListValues> ListValuesFilt(string tabName, string fieldName)
public List<ListValues> ListValuesFilt(string tabName, string fieldName)
{
List<DatabaseModels.ListValues> dbResult = new List<DatabaseModels.ListValues>();
List<ListValues> dbResult = new List<ListValues>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -432,9 +562,9 @@ namespace MP.Data.Controllers
/// Elenco da tabella Macchine
/// </summary>
/// <returns></returns>
public List<DatabaseModels.Macchine> MacchineGetAll()
public List<Macchine> MacchineGetAll()
{
List<DatabaseModels.Macchine> dbResult = new List<DatabaseModels.Macchine>();
List<Macchine> dbResult = new List<Macchine>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -450,15 +580,34 @@ namespace MP.Data.Controllers
/// Elenco id Macchine che abbiano dati FLuxLog
/// </summary>
/// <returns></returns>
public List<string> MacchineWithFlux()
public async Task<List<string>> MacchineWithFlux()
{
List<string> dbResult = new List<string>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = await dbCtx
.DbSetFluxLog
.AsNoTracking()
.Select(i => i.IdxMacchina)
.Distinct()
.ToListAsync();
}
return dbResult;
}
/// <summary>
/// Elenco codice articoli che abbiano dati Dossier
/// </summary>
/// <returns></returns>
public List<string> ArticleWithDossier()
{
List<string> dbResult = new List<string>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetFluxLog
.DbSetDossiers
.AsNoTracking()
.Select(i => i.IdxMacchina)
.Select(i => i.OdlNav.CodArticolo)
.Distinct()
.ToList();
}
@@ -469,9 +618,9 @@ namespace MP.Data.Controllers
/// Elenco da tabella MappaStatoExpl
/// </summary>
/// <returns></returns>
public List<DatabaseModels.MappaStatoExpl> MseGetAll(int maxAge = 2000)
public List<MappaStatoExpl> MseGetAll(int maxAge = 2000)
{
List<DatabaseModels.MappaStatoExpl> dbResult = new List<DatabaseModels.MappaStatoExpl>();
List<MappaStatoExpl> dbResult = new List<MappaStatoExpl>();
using (var dbCtx = new MoonProContext(_configuration))
{
var maxAgeSec = new SqlParameter("@maxAgeSec", maxAge);
@@ -511,7 +660,7 @@ namespace MP.Data.Controllers
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> PODLDeleteRecord(DatabaseModels.PODLModel currRec)
public async Task<bool> PODLDeleteRecord(PODLModel currRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
@@ -541,7 +690,7 @@ namespace MP.Data.Controllers
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> PODLUpdateRecord(DatabaseModels.PODLModel editRec)
public async Task<bool> PODLUpdateRecord(PODLModel editRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
@@ -561,6 +710,7 @@ namespace MP.Data.Controllers
currRec.KeyRichiesta = editRec.KeyRichiesta;
currRec.NumPezzi = editRec.NumPezzi;
currRec.Tcassegnato = editRec.Tcassegnato;
currRec.Note = editRec.Note;
dbCtx.Entry(currRec).State = EntityState.Modified;
}
else
+8 -8
View File
@@ -10,14 +10,6 @@ namespace MP.Data.Controllers
{
public class MpStatsController : IDisposable
{
#region Private Fields
private static IConfiguration _configuration;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Public Constructors
public MpStatsController(IConfiguration configuration)
@@ -326,5 +318,13 @@ namespace MP.Data.Controllers
}
#endregion Public Methods
#region Private Fields
private static IConfiguration _configuration;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
}
}
+9 -1
View File
@@ -5,10 +5,18 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DTO
{
public class DossierFluxLogDTO
{
public List<FluxLog> ODL { get; set; } = new List<FluxLog>();
/// <summary>
/// Elenco valori FluxLogDTO serializzato (compreso valori edit)
/// </summary>
public List<FluxLogDTO> ODL { get; set; } = new List<FluxLogDTO>();
}
}
+23
View File
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data.DTO
{
public class FluxLogDTO
{
public string IdxMacchina { get; set; }
public DateTime dtEvento { get; set; }
public string CodFlux { get; set; }
public string Valore { get; set; }
public string ValoreEdit { get; set; }
}
}
+3 -1
View File
@@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
[Table("AnagArticoli")]
+3 -1
View File
@@ -4,7 +4,9 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
[Table("AnagraficaGruppi")]
+3 -1
View File
@@ -2,7 +2,9 @@
using System.Collections.Generic;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class AzioniUL
+4
View File
@@ -2,6 +2,10 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
[Table("Config")]
+3
View File
@@ -4,6 +4,9 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
+30 -8
View File
@@ -2,8 +2,11 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
[Table("Dossiers")]
@@ -11,17 +14,36 @@ namespace MP.Data.DatabaseModels
{
#region Public Properties
[MaxLength(50)]
public string IdxMacchina { get; set; }
public DateTime DtRif { get; set; }
public int IdxODL { get; set; }
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxDossier { get; set; }
[MaxLength(50)]
public string DataType { get; set; }
public string Valore { get; set; }
public DateTime DtRif { get; set; }
[MaxLength(50)]
public string IdxMacchina { get; set; } = "";
[MaxLength(50)]
public string CodArticolo { get; set; } = "";
public int IdxODL { get; set; } = 0;
public string Valore { get; set; } = "";
/// <summary>
/// Navigazione oggetto Machine
/// </summary>
[ForeignKey("IdxMacchina")]
public virtual Macchine MachineNav { get; set; } = null!;
/// <summary>
/// Navigazione oggetto ODL
/// </summary>
[ForeignKey("IdxODL")]
public virtual ODLModel OdlNav { get; set; } = null!;
#endregion Public Properties
}
+4 -1
View File
@@ -2,8 +2,11 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
[Table("FluxLog")]
+4 -1
View File
@@ -3,8 +3,11 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
[Table("LinkMenuJQM")]
+4 -1
View File
@@ -1,8 +1,11 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
[Table("ListValues")]
+4 -1
View File
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class Macchine
+4
View File
@@ -1,6 +1,10 @@
using System;
using System.Collections.Generic;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class MappaStatoExpl
+35 -1
View File
@@ -3,8 +3,11 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
[Table("ODL")]
@@ -30,6 +33,37 @@ namespace MP.Data.DatabaseModels
[MaxLength(50)]
public string CodCli { get; set; } = "";
[NotMapped]
public string DurataMinuti
{
get
{
string answ = "";
DateTime end = DataFine != null ? (DateTime)DataFine : DateTime.Now;
var tsDurata = (end).Subtract((DateTime)DataInizio);
if (tsDurata.TotalDays < 1)
{
answ = $"{tsDurata.Hours:00}h {tsDurata.Minutes:00}'";
}
else
{
answ = $"{tsDurata.Days}gg {tsDurata.Hours:00}h";
}
return answ;
}
}
/// <summary>
/// Navigazione oggetto Machine
/// </summary>
[ForeignKey("IdxMacchina")]
public virtual Macchine MachineNav { get; set; } = null!;
/// <summary>
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
#endregion Public Properties
}
}
+15 -1
View File
@@ -3,8 +3,11 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
[Table("PromesseODL")]
@@ -52,6 +55,17 @@ namespace MP.Data.DatabaseModels
}
}
/// <summary>
/// Navigazione oggetto Machine
/// </summary>
[ForeignKey("IdxMacchina")]
public virtual Macchine MachineNav { get; set; } = null!;
/// <summary>
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
#endregion Public Properties
}
}
+4 -1
View File
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class ResControlli
+4 -1
View File
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class ResScarti
+26
View File
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class StatODLModel
{
#region Public Properties
[Key]
public int IdxStato { get; set; }
public string Descrizione { get; set; } = "";
public string Semaforo { get; set; }
public string Css { get; set; }
public double TotDurata { get; set; }
#endregion Public Properties
}
}
+4 -1
View File
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class StatsAnagArticoli
+4 -1
View File
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class StatsODL
+4 -1
View File
@@ -3,8 +3,11 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class TurniOee
+4 -1
View File
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
#nullable disable
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class UserActionLog
+6 -6
View File
@@ -12,14 +12,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.7">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.7" />
<PackageReference Include="NLog" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.9" />
<PackageReference Include="NLog" Version="5.0.4" />
</ItemGroup>
</Project>
+46 -50
View File
@@ -1,29 +1,11 @@
using NLog;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data
{
public class MessagePipe
{
#region Private Fields
private bool enableLog = false;
private IConnectionMultiplexer redis;
private IDatabase? redisDb;
#endregion Private Fields
#region Protected Fields
protected static Logger Log = LogManager.GetCurrentClassLogger();
#endregion Protected Fields
#region Public Constructors
public MessagePipe(IConnectionMultiplexer redisConn, string channelName, bool enableLog = false)
@@ -44,37 +26,6 @@ namespace MP.Data
#endregion Public Events
#region Private Properties
/// <summary>
/// Canale associato al gestore pipeline messaggi
/// </summary>
private string _channel { get; set; } = "";
#endregion Private Properties
#region Private Methods
private void setupSubscriber()
{
ISubscriber sub = redis.GetSubscriber();
//Subscribe to the channel named messages
sub.Subscribe(_channel, (channel, message) =>
{
Log.Trace($"ch {channel} | {message}");
// messaggio
PubSubEventArgs mea = new PubSubEventArgs(message);
// se qualcuno ascolta sollevo evento nuovo valore...
if (EA_NewMessage != null)
{
EA_NewMessage(this, mea);
}
});
Log.Info($"Subscribed {_channel}");
}
#endregion Private Methods
#region Public Methods
public bool saveAndSendMessage(string memKey, string message)
@@ -108,6 +59,51 @@ namespace MP.Data
#endregion Public Methods
#region Protected Fields
protected static Logger Log = LogManager.GetCurrentClassLogger();
#endregion Protected Fields
#region Private Fields
private bool enableLog = false;
private IConnectionMultiplexer redis;
private IDatabase? redisDb;
#endregion Private Fields
#region Private Properties
/// <summary>
/// Canale associato al gestore pipeline messaggi
/// </summary>
private string _channel { get; set; } = "";
#endregion Private Properties
#region Private Methods
private void setupSubscriber()
{
ISubscriber sub = redis.GetSubscriber();
//Subscribe to the channel named messages
sub.Subscribe(_channel, (channel, message) =>
{
Log.Trace($"ch {channel} | {message}");
// messaggio
PubSubEventArgs mea = new PubSubEventArgs(message);
// se qualcuno ascolta sollevo evento nuovo valore...
if (EA_NewMessage != null)
{
EA_NewMessage(this, mea);
}
});
Log.Info($"Subscribed {_channel}");
}
#endregion Private Methods
/// <summary>
/// Invio messaggio sul canale + salvataggio in cache REDIS
/// </summary>
@@ -132,4 +128,4 @@ namespace MP.Data
#endregion Public Properties
}
}
}
+4 -6
View File
@@ -6,7 +6,9 @@ using MP.Data.DatabaseModels;
using NLog;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data
{
public partial class MoonProContext : DbContext
@@ -46,6 +48,7 @@ namespace MP.Data
public virtual DbSet<PODLModel> DbSetPODL { get; set; }
public virtual DbSet<FluxLog> DbSetFluxLog { get; set; }
public virtual DbSet<Dossiers> DbSetDossiers { get; set; }
public virtual DbSet<StatODLModel> DbSetStatOdl { get; set; }
#endregion Public Properties
@@ -294,11 +297,6 @@ namespace MP.Data
{
entity.HasKey(e => new { e.IdxMacchina, e.dtEvento, e.CodFlux });
});
modelBuilder.Entity<Dossiers>(entity =>
{
entity.HasKey(e => new { e.IdxMacchina, e.DtRif });
});
OnModelCreatingPartial(modelBuilder);
+3 -1
View File
@@ -6,7 +6,9 @@ using MP.Data.DatabaseModels;
using NLog;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data
{
public partial class MoonPro_STATSContext : DbContext
+65 -23
View File
@@ -3,13 +3,26 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data
{
public class Utils
{
#region Public Properties
public static string redKeyArtUsed
{
get => RedHash($"CACHE:CheckArtUsed");
}
public static string redKeyTabCheckArt
{
get => RedHash($"CACHE:TabCheckArt");
}
#endregion Public Properties
#region Public Methods
public static string ConvMinToTime(double minutes)
@@ -28,41 +41,70 @@ namespace MP.Data
return answ;
}
public static async Task SaveToCsv<T>(List<T> reportData, string path)
{
var lines = new List<string>();
IEnumerable<PropertyDescriptor> props = TypeDescriptor.GetProperties(typeof(T)).OfType<PropertyDescriptor>();
var header = string.Join(";", props.ToList().Select(x => x.Name));
lines.Add(header);
var valueLines = reportData.Select(row => string.Join(";", header.Split(';').Select(a => row.GetType().GetProperty(a).GetValue(row, null))));
lines.AddRange(valueLines);
await Task.Run(() => File.WriteAllLines(path, lines.ToArray()));
}
public static string redKeyArtUsed
{
get => RedHash($"CACHE:CheckArtUsed");
}
public static string redKeyTabCheckArt
{
get => RedHash($"CACHE:TabCheckArt");
}
/// <summary>
/// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da funzionalita' DbConfig) + keyName richiesto...
/// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da
/// funzionalita' DbConfig) + keyName richiesto...
/// </summary>
public static string RedHash(string keyName)
{
string answ = keyName;
try
{
answ =$"MP:Data:{keyName}";
answ = $"MP:Data:{keyName}";
}
catch
{ }
return answ;
}
/// <summary>
/// Effettua salvataggio in file di un generico oggetto in formato CSV
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reportData"></param>
/// <param name="path"></param>
/// <param name="separator">Separatore da impiegare</param>
/// <returns></returns>
public static async Task SaveToCsv<T>(List<T> reportData, string path, char separator)
{
var lines = new List<string>();
IEnumerable<PropertyDescriptor> props = TypeDescriptor.GetProperties(typeof(T)).OfType<PropertyDescriptor>();
var header = string.Join(";", props.ToList().Select(x => x.Name));
lines.Add(header);
var valueLines = reportData.Select(row => string.Join(separator, header.Split(separator).Select(a => row.GetType().GetProperty(a).GetValue(row, null))));
//var valueLines = reportData.Select(row => string.Join(";", header.Split(';').Select(a => row.GetType().GetProperty(a).GetValue(row, null))));
lines.AddRange(valueLines);
await Task.Run(() => File.WriteAllLines(path, lines.ToArray()));
}
/// <summary>
/// Inizializzazione con periodo e arrotondamento
/// </summary>
/// <param name="minRound"></param>
/// <returns></returns>
public static DateTime InitDatetime(DateTime dtRif, int minRound)
{
TimeSpan DayElapsed = dtRif.Subtract(dtRif.Date);
int minDay = (int)Math.Ceiling((double)(DayElapsed.TotalMinutes / minRound)) * minRound;
DateTime endRounded = DateTime.Today.AddMinutes(minDay);
return endRounded;
}
public static string FormDurata(double durataMinuti)
{
string answ = "";
TimeSpan tsDurata = TimeSpan.FromMinutes(durataMinuti);
if (tsDurata.TotalDays < 1)
{
answ = $"{tsDurata.Hours:00}h {tsDurata.Minutes:00}'";
}
else
{
answ = $"{tsDurata.Days}gg {tsDurata.Hours:00}h";
}
return answ;
}
#endregion Public Methods
}
}
+5 -5
View File
@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>MP.Land</RootNamespace>
<Version>6.15.2209.1212</Version>
<Version>6.16.2209.2118</Version>
</PropertyGroup>
<ItemGroup>
@@ -45,14 +45,14 @@
<ItemGroup>
<PackageReference Include="DiffMatchPatch" Version="1.0.3" />
<PackageReference Include="Majorsoft.Blazor.Components.Debounce" Version="1.5.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.6">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.6" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.6" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.9" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.0.0" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.1.4" />
<PackageReference Include="RestSharp" Version="107.1.2" />
</ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo gestione Programmi MAPO</i>
<h4>Versione: 6.15.2209.1212</h4>
<h4>Versione: 6.16.2209.2118</h4>
<br />
Note di rilascio:
<ul>
+1 -1
View File
@@ -1 +1 @@
6.15.2209.1212
6.16.2209.2118
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.15.2209.1212</version>
<version>6.16.2209.2118</version>
<url>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+3 -3
View File
@@ -4,7 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>6.15.2209.1411</Version>
<Version>6.16.2209.2118</Version>
</PropertyGroup>
<ItemGroup>
@@ -30,8 +30,8 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NLog" Version="5.0.1" />
<PackageReference Include="StackExchange.Redis" Version="2.6.48" />
<PackageReference Include="NLog" Version="5.0.4" />
<PackageReference Include="StackExchange.Redis" Version="2.6.66" />
</ItemGroup>
<ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MON MAPO</i>
<h4>Versione: 6.15.2209.1411</h4>
<h4>Versione: 6.16.2209.2118</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.15.2209.1411
6.16.2209.2118
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.15.2209.1411</version>
<version>6.16.2209.2118</version>
<url>https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.Mon.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+1
View File
@@ -0,0 +1 @@
<canvas id="@Id"></canvas>
@@ -0,0 +1,59 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data;
using static System.Net.Mime.MediaTypeNames;
namespace MP.SPEC.Components.Chart
{
public partial class Doughnut
{
[Inject]
private IJSRuntime JSRuntime { get; set; } = null!;
public enum ChartType
{
Pie,
Bar,
Doughnut
}
//[Parameter]
public string Id { get; set; } = "myChart";
[Parameter]
public ChartType Type { get; set; }
[Parameter]
public double[] Data { get; set; }
[Parameter]
public string[] BackgroundColor { get; set; }
[Parameter]
public string[] Labels { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
var config = new
{
Type = Type.ToString().ToLower(),
Options = new
{
Responsive = true,
},
Data = new
{
Datasets = new[]
{
new { Data = Data, BackgroundColor = BackgroundColor
}
},
Labels = Labels
}
};
await JSRuntime.InvokeVoidAsync("setup", Id, config);
}
}
}
+1
View File
@@ -0,0 +1 @@
<canvas id="@Id"></canvas>
+162
View File
@@ -0,0 +1,162 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data;
namespace MP.SPEC.Components.Chart
{
public partial class Line
{
#region Public Properties
[Parameter]
public double AspRatio { get; set; } = 0;
[Parameter]
public List<string> backColor { get; set; } = new List<string>();
[Parameter]
public string ChartId
{
get
{
return Id;
}
set
{
Id = value;
}
}
[Parameter]
public List<chartJsData.chartJsTSerie> DataTS
{
get
{
return _DataTS;
}
set
{
_DataTS = value;
//var pUpd = Task.Run(async () => await renderChart());
//pUpd.Wait();
}
}
[Parameter]
public List<string> Labels { get; set; } = new List<string>();
[Parameter]
public List<string> lineColor { get; set; } = new List<string>();
[Parameter]
public int lTens { get; set; } = 0;
[Parameter]
public string MaxValue { get; set; } = "0";
[Parameter]
public string MinValue { get; set; } = "0";
[Parameter]
public List<string> pointColor { get; set; } = new List<string>();
[Parameter]
public string Title { get; set; } = "Demo Line";
#endregion Public Properties
#region Protected Properties
protected string Id { get; set; } = "CurrId";
#endregion Protected Properties
#region Protected Methods
/// <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)
{
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,
position = "right",
ticks = new
{
maxTicksLimit = 10
},
suggestedMin = MinValue != MaxValue ? MinValue : "auto",
suggestedMax = MinValue != MaxValue ? MaxValue : "auto"
},
xAxes = new
{
type = "time",
distribution = "linear",
}
},
plugins = new
{
legend = new
{
display = false
},
},
Animation = false,
AspectRatio = AspRatio == 0 ? "auto" : $"{AspRatio}"
},
data = new
{
labels = Labels,
datasets = new[]{new
{
data = DataTS, pointBorderColor = backColor, borderColor = lineColor, backgroundColor = backColor, fill = true, PointRadius = 2, BorderWidth = 1, lineTension = lTens, stepped = false, label = Title
}
}
}
}
;
await JSRuntime.InvokeVoidAsync("setup", Id, config);
}
#endregion Protected Methods
#region Private Properties
private List<chartJsData.chartJsTSerie> _DataTS { get; set; } = null!;
[Inject]
private IJSRuntime JSRuntime { get; set; } = null!;
#endregion Private Properties
}
}
+4 -4
View File
@@ -33,15 +33,15 @@ namespace MP.SPEC.Components
aTimer.Start();
}
#endregion Public Methods
#region Protected Methods
protected override void OnInitialized()
{
version = typeof(Program).Assembly.GetName().Version;
}
#endregion Public Methods
#region Protected Methods
#endregion Protected Methods
#region Private Fields
+10 -6
View File
@@ -23,12 +23,6 @@ namespace MP.SPEC.Components
}
}
}
public async Task resetCurrPage()
{
await Task.Delay(1);
currPage = 1;
}
[Parameter]
public EventCallback<int> numPageChanged { get; set; }
@@ -82,6 +76,16 @@ namespace MP.SPEC.Components
#endregion Public Properties
#region Public Methods
public async Task resetCurrPage()
{
await Task.Delay(1);
currPage = 1;
}
#endregion Public Methods
#region Protected Fields
protected bool _showLoading = false;
+49 -68
View File
@@ -1,73 +1,54 @@
<div class="d-flex justify-content-between">
<div class="px-0 py-1">
</div>
<div class="px-0 col-6">
<div class="">
@*@if (showEditPar)
{
<div class="px-0 input-group py-1" id="basic-addon1">
<button class="btn btn-primary" @onclick="() => toggleParams()"> <i class="fa-solid fa-arrow-right"></i></button>
<label class="input-group-text" for="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati"><i class="fa-solid fa-clock"></i></label>
<select @bind="@selTempoAgg" class="form-select" id="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati">
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
</select>
<label class="input-group-text" for="maxRecord" title="Selezionare il numero massimo di record da visualizzare"><i class="fa-solid fa-list-ol"></i></label>
<select @bind="@selMaxRecord" class="form-select" id="maxRecord" title="Selezionare il numero massimo di record da visualizzare">
<option value="50">50</option>
<option value="100">100</option>
<option value="150">150</option>
<option value="200">200</option>
<option value="250">250</option>
<option value="300">300</option>
<option value="350">350</option>
<option value="400">400</option>
<option value="450">450</option>
<option value="500">500</option>
</select>
</div>
}
else
{
<div class="px-2 py-1">
<button class="btn btn-primary" @onclick="() => toggleParams()"><i class="fa-solid fa-arrow-left"></i></button>
</div>
}*@
<div class="px-0 py-1">
<div class="px-2 input-group" id="basic-addon1">
<label class="input-group-text" for="macchina" title="Selezionare la macchina"><i class="fa-solid fa-hard-drive"></i></label>
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare la macchina">
<option value="*">--- Tutti ---</option>
@if (ListMacchine != null)
<div class="d-flex justify-content-end">
<a class="pt-2 text-dark" data-bs-toggle="offcanvas" data-bs-target="#paramsFilterExample" aria-controls="paramsFilterExample">
<i class="fa-solid fa-bars"></i>
</a>
<div class="offcanvas offcanvas-end" tabindex="-1" id="paramsFilterExample" aria-labelledby="paramsFilterExampleLabel">
<div class="offcanvas-header">
<h3 class="offcanvas-title" id="paramsFilterExampleLabel"><b>FILTRI</b></h3>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div>
Seleziona i filtri per:
</div>
<div class="input-group p-2">
<label class="input-group-text" for="macchina" title="Selezionare l'articolo"><i class="fa-solid fa-file"></i></label>
<select @bind="@selArticolo" class="form-select" id="macchina" title="Selezionare la macchina">
<option value="*">--- Tutti ---</option>
@if (ListArticoli != null)
{
foreach (var item in ListArticoli)
{
foreach (var item in ListMacchine)
{
<option value="@item">@item</option>
}
<option value="@item">@item</option>
}
</select>
<label class="input-group-text" for="DtRef" title="Selezionare il tipo di flusso"><i class="fa-solid fa-calendar-check"></i></label>
<input @bind="@selDtRef" id="DtRef" class="form-control" type="datetime-local" />
</div>
}
</select>
</div>
<div class="input-group p-2">
<label class="input-group-text" for="macchina" title="Selezionare la macchina"><i class="fa-solid fa-hard-drive"></i></label>
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare la macchina">
<option value="*">--- Tutti ---</option>
@if (ListMacchine != null)
{
foreach (var item in ListMacchine)
{
<option value="@item">@item</option>
}
}
</select>
</div>
<div class="input-group p-2">
<label class="input-group-text" for="DtMin" title="Selezionare la data da visualizzare"><i class="fa-solid fa-calendar-check"></i></label>
<input @bind="@selDtRef" id="DtMin" class="form-control" type="datetime-local" title="Selezionare la data minima da visualizzare" />
</div>
<div class="input-group p-2">
<label class="input-group-text" for="maxRecord" title="Selezionare il numero massimo di record da visualizzare"><i class="fa-solid fa-list-ol"></i></label>
<select @bind="@selMaxRecord" class="form-select" id="maxRecord" title="Selezionare il numero massimo di record da visualizzare">
<option value="50">50</option>
<option value="100">100</option>
<option value="250">250</option>
<option value="500">500</option>
</select>
</div>
</div>
</div>
+49 -45
View File
@@ -1,21 +1,5 @@
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 MP.SPEC;
using MP.SPEC.Shared;
using MP.SPEC.Components;
using MP.SPEC.Data;
using MP.Data.DatabaseModels;
namespace MP.SPEC.Components
{
@@ -31,28 +15,23 @@ namespace MP.SPEC.Components
#endregion Public Properties
#region Protected Fields
#endregion Protected Fields
#region Protected Properties
[Inject]
protected MpDataService MDService { get; set; } = null!;
protected string selMacchina
protected string selArticolo
{
get
{
return SelFilterDossier.IdxMacchina;
return SelFilterDossier.CodArticolo;
}
set
{
if (!SelFilterDossier.IdxMacchina.Equals(value))
if (!SelFilterDossier.CodArticolo.Equals(value))
{
SelFilterDossier.CurrPage = 1;
SelFilterDossier.IdxMacchina = value;
SelFilterDossier.CodArticolo = value;
StateHasChanged();
Task.Delay(1);
reportChange();
@@ -60,24 +39,6 @@ namespace MP.SPEC.Components
}
}
protected int selMaxRecord
{
get
{
return SelFilterDossier.MaxRecord;
}
set
{
if (!SelFilterDossier.MaxRecord.Equals(value))
{
SelFilterDossier.MaxRecord = value;
reportChange();
}
}
}
protected DateTime selDtRef
{
get
@@ -95,6 +56,44 @@ namespace MP.SPEC.Components
}
}
protected string selMacchina
{
get
{
return SelFilterDossier.IdxMacchina;
}
set
{
if (!SelFilterDossier.IdxMacchina.Equals(value))
{
SelFilterDossier.CurrPage = 1;
SelFilterDossier.IdxMacchina = value;
StateHasChanged();
Task.Delay(1);
reportChange();
}
}
}
protected int selMaxRecord
{
get
{
return SelFilterDossier.MaxRecord;
}
set
{
if (!SelFilterDossier.MaxRecord.Equals(value))
{
SelFilterDossier.MaxRecord = value;
reportChange();
}
}
}
protected bool showParam { get; set; } = false;
#endregion Protected Properties
#region Protected Methods
@@ -103,7 +102,7 @@ namespace MP.SPEC.Components
{
SelFilterDossier = new SelectDossierParams();
ListMacchine = await MDService.MacchineWithFlux();
ListDossier = await MDService.DossiersGetLastFilt(selMacchina, selDtRef, selMaxRecord);
ListArticoli = await MDService.ArticleWithDossier();
await FilterChanged.InvokeAsync(SelFilterDossier);
}
@@ -116,7 +115,7 @@ namespace MP.SPEC.Components
#region Private Fields
private List<Dossiers>? ListDossier = null;
private List<string>? ListArticoli = null;
private List<string>? ListMacchine = null;
#endregion Private Fields
@@ -134,6 +133,11 @@ namespace MP.SPEC.Components
FilterChanged.InvokeAsync(SelFilterDossier);
}
private void toggleShowParams()
{
showParam = !showParam;
}
#endregion Private Methods
}
}
+33 -10
View File
@@ -19,10 +19,13 @@ else
<th>
<button @onclick="() => unToggleTableFlux()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
</th>
<th><i class="fa-solid fa-file"></i> Articolo</th>
<th><i class="fa-solid fa-screwdriver-wrench"></i> Fase</th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th><i class="fa-regular fa-calendar-days"></i> Data</th>
<th><i class="fa-regular fa-calendar-days"></i> Data Snap</th>
<th><i class="fa-solid fa-sliders"></i> ODL</th>
<th><i class="fa-solid fa-sliders"></i> DATA TYPE</th>
@*<th><i class="fa-solid fa-circle-info"></i> DATA TYPE</th>*@
<th></th>
</tr>
</thead>
<tbody>
@@ -32,8 +35,16 @@ else
<td>
<button class="btn btn-primary btn-sm" @onclick="() => selRecord(record)"><i class="fa-solid fa-magnifying-glass"></i></button>
</td>
<td>
@record.OdlNav.CodArticolo
<div class="small textConsensed text-secondary">@record.OdlNav.ArticoloNav.DescArticolo</div>
</td>
<td>
@tradFase(record.OdlNav.KeyRichiesta)
</td>
<td>
@record.IdxMacchina
<div class="small textConsensed text-secondary">@record.MachineNav.Descrizione</div>
</td>
<td>
@record.DtRif
@@ -41,8 +52,11 @@ else
<td>
@record.IdxODL
</td>
@*<td>
@record.DataType
</td>*@
<td>
@record.DataType
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
</td>
</tr>
}
@@ -61,17 +75,26 @@ else
<table class="table table-light table-sm table-striped small mb-0">
<thead>
<tr>
<th></th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th><i class="fa-regular fa-calendar-days"></i> Data</th>
<th><i class="fa-solid fa-sliders"></i> ODL</th>
<th class="d-flex justify-content-between"><i class="fa-solid fa-sliders"></i> Valore <button class="btn btn-primary btn-sm py-0" @onclick="() => unToggleTableFlux()"><i class="fa-solid fa-xmark"></i></button></th>
@*<th class="d-flex justify-content-end"><button class="btn btn-primary btn-sm py-0" @onclick="() => unToggleTableFlux()"><i class="fa-solid fa-xmark"></i></button></th>*@
<th><i class="fa-solid fa-sliders"></i> Data Type</th>
<th>
<div class="d-flex justify-content-between col-12">
<span class="col-11" style="text-align: right;"> Valore </span>
<button class="btn btn-primary btn-sm py-0" @onclick="() => unToggleTableFlux()"><i class="fa-solid fa-xmark"></i></button>
</div>
</th>
</tr>
</thead>
<tbody>
@foreach (var record in listaFlux)
{
<tr>
<td>
<button @onclick="() => editRecord(record)" class="btn btn-primary btn-sm" title="Modifica Record"><i class="bi bi-pencil-square"></i></button>
</td>
<td>
@record.IdxMacchina
</td>
@@ -82,17 +105,15 @@ else
@record.CodFlux
</td>
<td style="text-align: right;">
<b>@record.Valore</b>
<div><span class="small text-dark">Modificato: </span><b>@record.ValoreEdit</b></div>
<div class="small text-secondary"><span class="small text-dark">Originale: </span><i>@record.Valore</i></div>
</td>
@* <td>
</td>*@
</tr>
}
</tbody>
</table>
</div>
}
}
</div>
</div>
@@ -101,3 +122,5 @@ else
+75 -24
View File
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using MP.SPEC.Data;
namespace MP.SPEC.Components
@@ -12,6 +13,9 @@ namespace MP.SPEC.Components
[Parameter]
public EventCallback<Dossiers> RecordSel { get; set; }
[Parameter]
public EventCallback<FluxLogDTO> RecordSelFlux { get; set; }
[Parameter]
public SelectDossierParams SelFilter { get; set; } = null!;
@@ -37,20 +41,6 @@ namespace MP.SPEC.Components
return answ;
}
public async Task reloadData(bool setChanged)
{
isLoading = true;
SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelDtRef, MaxRecord);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
if (setChanged)
{
await InvokeAsync(() => StateHasChanged());
}
isLoading = false;
}
#endregion Public Methods
#region Protected Properties
@@ -68,14 +58,47 @@ namespace MP.SPEC.Components
#region Protected Methods
/// <summary>
/// Eliminazione record selezionato (previa conferma)
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
protected async Task deleteRecord(Dossiers selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Eliminazione Dossier: sei sicuro di voler procedere?"))
return;
await Task.Delay(1);
var done = await MDService.DossiersDeleteRecord(selRec);
currRecord = null;
await reloadData(true);
visualizzaFlux = true;
await Task.Delay(1);
}
protected async Task editRecord(FluxLogDTO selRec)
{
// indico record selezionato
await RecordSelFlux.InvokeAsync(selRec);
}
protected string findRec(FluxLog record)
{
string answ = "";
#if false
if (ListRecordsMod != null)
{
answ = ListRecordsMod.Where(l => l.IdxMacchina == record.IdxMacchina && l.CodFlux == record.CodFlux).Select(x => x.Valore).SingleOrDefault();
}
#endif
return answ;
}
protected override async Task OnInitializedAsync()
{
MessageService.EA_PageUpdated += MessageService_EA_PageUpdated;
MessageService.EA_SearchUpdated += OnSeachUpdated;
ListRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelDtRef, MaxRecord);
await reloadData();
ListStati = await MDService.AnagStatiComm();
await reloadData(true);
}
protected async void OnSeachUpdated()
@@ -91,7 +114,7 @@ namespace MP.SPEC.Components
{
currRecord = selRec;
await RecordSel.InvokeAsync(selRec);
listaFlux = MDService.convertToFluxLog(selRec.Valore);
listaFlux = MDService.getFluxLog(selRec.Valore);
await toggleTableFlux();
}
@@ -106,8 +129,13 @@ namespace MP.SPEC.Components
#region Private Fields
private int _totalCount = 0;
private Dossiers? currRecord = null;
private FluxLogDTO? currRecordFlux;
private List<Dossiers>? ListRecords;
private List<ListValues>? ListStati;
private List<Dossiers>? SearchRecords;
#endregion Private Fields
@@ -121,7 +149,8 @@ namespace MP.SPEC.Components
}
private bool isLoading { get; set; } = false;
private List<FluxLog>? listaFlux { get; set; } = null;
private List<FluxLogDTO>? listaFlux { get; set; } = null;
private int MaxRecord
{
@@ -134,6 +163,11 @@ namespace MP.SPEC.Components
set => MessageService.numRecord = value;
}
private string SelArticolo
{
get => SelFilter.CodArticolo;
}
private DateTime SelDtRef
{
get => SelFilter.DtRef;
@@ -165,17 +199,20 @@ namespace MP.SPEC.Components
private async void MessageService_EA_PageUpdated()
{
await reloadData();
await reloadData(true);
}
private async Task reloadData()
private async Task reloadData(bool setChanged)
{
isLoading = true;
SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelDtRef, MaxRecord);
SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelArticolo, SelDtRef, MaxRecord);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
if (setChanged)
{
await InvokeAsync(() => StateHasChanged());
}
isLoading = false;
}
@@ -185,6 +222,20 @@ namespace MP.SPEC.Components
await Task.Delay(1);
}
private string tradFase(string codFase)
{
string answ = codFase;
if (ListStati != null && ListStati.Count > 0)
{
var recSel = ListStati.FirstOrDefault(x => x.value == codFase);
if (recSel != null)
{
answ = recSel.label;
}
}
return answ;
}
private async Task unToggleTableFlux()
{
currRecord = null;
+187 -24
View File
@@ -16,53 +16,216 @@ else
<table class="table table-sm table-striped">
<thead>
<tr>
<th>
@*<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>*@
</th>
<th><i class="fa-solid fa-file"></i> Articolo</th>
<th><i class="fa-solid fa-screwdriver-wrench"></i> Fase</th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th># pz</th>
<th><i class="fa-solid fa-clock"></i> T.Ciclo</th>
<th><i class="fa-solid fa-play"></i> Inizio</th>
<th><i class="fa-solid fa-pen-to-square"></i> Note</th>
<th><i class="fa-solid fa-code-pull-request"></i> Richiesta</th>
<th></th>
<th><i class="fa-solid fa-circle-info"></i> Info ciclo</th>
<th><i class="fa-solid fa-calendar-day"></i> Periodo</th>
<th title="Durata in ore:min"><i class="fa-solid fa-clock"></i> Durata</th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.CodArticolo)">
<td>
@*<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>*@
</td>
<tr class="@checkSelect(@record.IdxOdl)">
<td>
@record.CodArticolo
<div class="small textConsensed text-secondary">@record.ArticoloNav.DescArticolo</div>
</td>
<td>
<div>
@tradFase(record.KeyRichiesta)
</div>
@if (record.Note != "")
{
<div class="small textConsensed text-secondary badge text-bg-light border border-secondary rounded">
<b class="text-dark"></b> <span class="text-wrap text-start"> @record.Note </span>
</div>
}
</td>
<td>
@record.IdxMacchina
<div class="small textConsensed text-secondary">@record.MachineNav.Descrizione</div>
</td>
<td>
@record.NumPezzi
<div class="small textConsensed"><b>N° pezzi:</b> @record.NumPezzi</div>
<div class="small textConsensed"><b>T. Ciclo:</b> @record.Tcassegnato.ToString("N3")</div>
</td>
<td>
@record.Tcassegnato.ToString("N3")
<div class="small d-flex justify-content-between">
<div>
<div><b>@($"{@record.DataInizio:yyyy/MM/dd}")</b></div>
<div>@($"{@record.DataInizio:ddd HH:mm:ss}")</div>
</div>
<div class="p-0">
<i class="fa-solid fa-angles-right"></i>
</div>
<div>
@if (@record.DataFine != null)
{
<div><b>@($"{@record.DataFine:yyyy/MM/dd}")</b></div>
<div>@($"{@record.DataFine:ddd HH:mm:ss}")</div>
}
else
{
<div class="text-secondary">
<div><b>@($"{DateTime.Now:yyyy/MM/dd}")</b></div>
<div>@($"{DateTime.Now:ddd HH:mm:ss}")</div>
</div>
}
</div>
</div>
</td>
<td>
<div>@record.DataInizio</div>
</td>
<td>@record.Note</td>
<td>@record.KeyRichiesta</td>
<td>
@*@if (ArticoloDelEnabled(record.CodArticolo))
{
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
}*@
<div>
<b>@record.DurataMinuti</b>
</div>
<div>
<button class="btn btn-sm btn-primary py-0" type="button" @onclick="() => selectRecord(record)" data-bs-toggle="modal" data-bs-target="#staticBackdrop" title="Mostra statistiche"><i class="fa-solid fa-chart-pie"></i></button>
</div>
<!-- Modal -->
</td>
</tr>
}
</tbody>
</table>
<div class="modal fade" id="staticBackdrop" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl">
<div class="modal-content">
<div class="modal-header bg-primary col-12">
@if (currRecord != null)
{
<div class="col-3">
<b class="modal-title fs-1" id="staticBackdropLabel"><b>ODL @currRecord.IdxOdl</b></b>
</div>
<div class="col-6 fs-5">
<b>@currRecord.CodArticolo</b>
<div class="small textConsensed text-light">@currRecord.ArticoloNav.DescArticolo</div>
</div>
<div class="col-2 fs-5">
<b>@currRecord.IdxMacchina</b>
<div class="small textConsensed text-light">@currRecord.MachineNav.Descrizione</div>
</div>
}
<div class="col-1 text-end">
<button type="button" class="btn btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
</div>
<div class="modal-body col-12">
@if (currRecord != null)
{
<div class="d-flex justify-content-between">
<div class="col-8">
<div>
<table class="table">
<tbody>
<tr>
<td style="width: 270px">
<div class="small textConsensed"><b>N° pezzi:</b> @currRecord.NumPezzi</div>
<div class="small textConsensed"><b>T. Ciclo:</b> @currRecord.Tcassegnato.ToString("N3")</div>
</td>
<td style="width: 300px">
<div class="small d-flex justify-content-between">
<div>
<div><b>@($"{@currRecord.DataInizio:yyyy/MM/dd}")</b></div>
<div>@($"{@currRecord.DataInizio:ddd HH:mm:ss}")</div>
</div>
<div class="p-0">
<i class="fa-solid fa-angles-right"></i>
</div>
<div>
@if (@currRecord.DataFine != null)
{
<div><b>@($"{@currRecord.DataFine:yyyy/MM/dd}")</b></div>
<div>@($"{@currRecord.DataFine:ddd HH:mm:ss}")</div>
}
else
{
<div class="text-secondary">
<div><b>@($"{DateTime.Now:yyyy/MM/dd}")</b></div>
<div>@($"{DateTime.Now:ddd HH:mm:ss}")</div>
</div>
}
</div>
</div>
</td>
<td>
<!-- Modal -->
</td>
</tr>
</tbody>
</table>
</div>
<div>
<table class="table">
<tbody>
<tr>
<td>
<div>
@tradFase(currRecord.KeyRichiesta)
</div>
@if (currRecord.Note != "")
{
<div class="small textConsensed text-secondary badge text-bg-light border border-secondary rounded">
<b class="text-dark"></b> <span class="text-wrap text-start"> @currRecord.Note </span>
</div>
}
</td>
</tr>
</tbody>
</table>
</div>
<div>
@if (currRecord != null)
{
@if (ListOdlStats != null)
{
@foreach (var statRecord in ListOdlStats)
{
<div class="p-1">
<div class="d-flex justify-content-between">
<div class="text-uppercase">
@statRecord.Descrizione
</div>
<div>
<b>@(formDurata(statRecord.TotDurata))</b>
</div>
</div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" style="width: @Math.Round(calcolaPerc(statRecord.TotDurata),0)%; background-color:@statRecord.Css;" aria-valuemax="100">@($"{calcolaPerc(statRecord.TotDurata):N1}%")</div>
</div>
</div>
}
}
}
</div>
</div>
<div class="col-4 dcContainer">
@if (currRecord != null)
{
<div class="dcBox">
<ODLPlot SelectedOdl="@currRecord.IdxOdl"></ODLPlot>
</div>
<div class="dcBox dcOverlay">
<b class="fs-3">@currRecord.DurataMinuti</b>
</div>
}
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
</div>
}
<style>
</style>
+78 -33
View File
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
@@ -9,36 +10,27 @@ namespace MP.SPEC.Components
{
#region Public Properties
[Parameter]
public SelectOdlParams currFilter { get; set; } = null!;
[Parameter]
public EventCallback<bool> PagerResetReq { get; set; }
[Parameter]
public string StatoSel
{
get => _statoSel;
set
{
if (_statoSel != value)
{
_statoSel = value;
var pUpd = Task.Run(async () => await reloadData());
pUpd.Wait();
}
}
}
public EventCallback<int> updateRecordCount { get; set; }
#endregion Public Properties
#region Public Methods
public string checkSelect(string CodArticolo)
public string checkSelect(int IdxOdl)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.CodArticolo == CodArticolo) ? "table-info" : "";
answ = (currRecord.IdxOdl == IdxOdl) ? "table-info" : "";
}
catch
{ }
@@ -46,6 +38,11 @@ namespace MP.SPEC.Components
return answ;
}
public string formDurata(double durataMin)
{
return Utils.FormDurata(durataMin);
}
#endregion Public Methods
#region Protected Properties
@@ -65,8 +62,11 @@ namespace MP.SPEC.Components
protected override async Task OnInitializedAsync()
{
MessageService.EA_PageUpdated += MessageService_EA_PageUpdated;
MessageService.EA_SearchUpdated += OnSeachUpdated;
ListStati = await MDService.AnagStatiComm();
}
protected override async Task OnParametersSetAsync()
{
await reloadData();
}
@@ -81,9 +81,23 @@ namespace MP.SPEC.Components
});
}
protected async Task selectRecord(ODLModel? currRec)
{
await Task.Delay(1);
currRecord = currRec;
if (currRec != null)
{
ListOdlStats = await MDService.StatOdl(currRec.IdxOdl);
}
else
{
ListOdlStats = null;
}
}
protected async Task UpdateData()
{
currRecord = null;
await selectRecord(null);
await reloadData();
}
@@ -91,12 +105,12 @@ namespace MP.SPEC.Components
#region Private Fields
private string _statoSel = "*";
private ODLModel? currRecord = null;
private List<StatODLModel>? ListOdlStats;
private List<double>? ListOdlStatsData = new List<double>();
private List<string>? ListOdlStatsLabels = new List<string>();
private List<ODLModel>? ListRecords;
private List<ListValues>? ListStati;
private List<ODLModel>? SearchRecords;
#endregion Private Fields
@@ -117,21 +131,37 @@ namespace MP.SPEC.Components
set => MessageService.numRecord = value;
}
private string SearchVal
{
get => string.IsNullOrEmpty(MessageService.SearchVal) ? "*" : MessageService.SearchVal;
}
private int totalCount
{
get => MessageService.totalCount;
set => MessageService.totalCount = value;
}
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
private double calcolaPerc(double durata)
{
double answ = 0;
double tot = 0;
if (ListOdlStats != null)
{
foreach (var item in ListOdlStats)
{
tot += item.TotDurata;
}
double perc = (durata / tot) * 100;
if (perc > 1)
{
answ = Math.Round(perc, 2);
}
else
{
answ = Math.Round(perc, 4);
}
}
return answ;
}
private async void MessageService_EA_PageUpdated()
{
await reloadData();
@@ -140,14 +170,29 @@ namespace MP.SPEC.Components
private async Task reloadData()
{
isLoading = true;
SearchRecords = await MDService.ListODLFilt(true, SearchVal, StatoSel);
SearchRecords = await MDService.ListODLFilt(currFilter.IsActive, currFilter.SearchVal, currFilter.CodStato, currFilter.DtStart, currFilter.DtEnd);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
await updateRecordCount.InvokeAsync(totalCount);
isLoading = false;
}
private string tradFase(string codFase)
{
string answ = codFase;
if (ListStati != null && ListStati.Count > 0)
{
var recSel = ListStati.FirstOrDefault(x => x.value == codFase);
if (recSel != null)
{
answ = recSel.label;
}
}
return answ;
}
#endregion Private Methods
}
}
+3 -10
View File
@@ -17,21 +17,20 @@ else
<thead>
<tr>
<th>
@*<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>*@
<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
</th>
<th><i class="fa-regular fa-calendar-days"></i> Data</th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th><i class="fa-solid fa-sliders"></i> Parametro</th>
<th style="text-align: right">Valore</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.IdxMacchina)">
<tr class="@checkSelect(@record)">
<td>
@*<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>*@
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-search"></i></button>
</td>
<td>
@record.dtEvento
@@ -45,12 +44,6 @@ else
<td style="text-align: right">
<b>@record.Valore</b>
</td>
<td>
@*@if (ArticoloDelEnabled(record.CodArticolo))
{
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
}*@
</td>
</tr>
}
</tbody>
+45 -8
View File
@@ -13,6 +13,9 @@ namespace MP.SPEC.Components
[Parameter]
public EventCallback<bool> PagerResetReq { get; set; }
[Parameter]
public EventCallback<FluxLog> RecordSel { get; set; }
[Parameter]
public SelectFluxParams SelFilter { get; set; } = null!;
@@ -23,14 +26,14 @@ namespace MP.SPEC.Components
#region Public Methods
public string checkSelect(string IdxMacchina)
public string checkSelect(FluxLog selRecord)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.IdxMacchina == IdxMacchina) ? "table-info" : "";
answ = (currRecord.IdxMacchina == selRecord.IdxMacchina && currRecord.dtEvento == selRecord.dtEvento && currRecord.CodFlux == selRecord.CodFlux) ? "table-info" : "";
}
catch
{ }
@@ -38,6 +41,20 @@ namespace MP.SPEC.Components
return answ;
}
protected override async Task OnParametersSetAsync()
{
await Task.Delay(1);
// se sono cambiati --> rileggo...
if (LastFilter==null || !SelFilter.Equals(LastFilter))
{
await reloadData(false);
LastFilter = SelFilter;
}
}
public SelectFluxParams? LastFilter = null;
public void Dispose()
{
aTimer.Elapsed -= ElapsedTimer;
@@ -73,7 +90,12 @@ namespace MP.SPEC.Components
public async Task reloadData(bool setChanged)
{
isLoading = true;
SearchRecords = await MDService.FluxLogGetLastFilt(SelMacchina, SelFlux, MaxRecord);
DateTime limitData = DateTime.Now;
if (SelDtMax != null)
{
limitData = (DateTime)SelDtMax;
}
SearchRecords = await MDService.FluxLogGetLastFilt(limitData, SelMacchina, SelFlux, MaxRecord);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
@@ -86,11 +108,9 @@ namespace MP.SPEC.Components
public void StartTimer()
{
//int.TryParse(Configuration["ReloadStatusTimer"], out tOutPeriod);
aTimer = new System.Timers.Timer(RefreshPeriod);
aTimer.Elapsed += ElapsedTimer;
aTimer.Enabled = true;
//aTimer.AutoReset = true;
aTimer.Start();
}
@@ -111,7 +131,6 @@ namespace MP.SPEC.Components
{
get => SelFilter.TempoAgg;
}
//protected int RefreshPeriod { get; set; } = 5000;
#endregion Protected Properties
@@ -122,10 +141,10 @@ namespace MP.SPEC.Components
MessageService.EA_PageUpdated += MessageService_EA_PageUpdated;
MessageService.EA_SearchUpdated += OnSeachUpdated;
StartTimer();
await reloadData(true);
}
//protected int RefreshPeriod { get; set; } = 5000;
protected async void OnSeachUpdated()
{
await InvokeAsync(() =>
@@ -137,6 +156,20 @@ namespace MP.SPEC.Components
});
}
protected async Task resetSel()
{
currRecord = null;
await RecordSel.InvokeAsync(null);
}
protected async Task selRecord(FluxLog selRec)
{
currRecord = selRec;
SelFilter.IdxMacchina = selRec.IdxMacchina;
await reloadData(false);
await RecordSel.InvokeAsync(selRec);
}
protected async Task UpdateData()
{
currRecord = null;
@@ -191,6 +224,10 @@ namespace MP.SPEC.Components
{
get => SelFilter.IdxMacchina;
}
private DateTime? SelDtMax
{
get => SelFilter.dtMax;
}
private int totalCount
{
+31 -10
View File
@@ -22,33 +22,54 @@ else
<th><i class="fa-solid fa-file"></i> Articolo</th>
<th><i class="fa-solid fa-screwdriver-wrench"></i> Fase</th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
<th># pz</th>
<th><i class="fa-solid fa-clock"></i> T.Ciclo</th>
<th><i class="fa-solid fa-pen-to-square"></i> Note</th>
<th><i class="fa-solid fa-circle-info"></i> Info ciclo</th>
@*<th><i class="fa-solid fa-pen-to-square"></i> Note</th>*@
<th title="Attivabile"><i class="fa-regular fa-square-check"></i> Att</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.CodArticolo)">
<td>
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>
<tr class="@checkSelect(@record)">
<td class="text-nowrap">
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm" title="Modifica Record"><i class="bi bi-pencil-square"></i></button>
<button @onclick="() => cloneRecord(record)" class="btn btn-info btn-sm" title="Duplica Record"><i class="bi bi-clipboard-check"></i></button>
</td>
<td>
@record.CodArticolo
<div class="small textConsensed text-secondary">@record.ArticoloNav.DescArticolo</div>
</td>
<td>
<div>
@tradFase(record.KeyRichiesta)
</div>
@if (record.Note != "")
{
<div class="small textConsensed text-secondary badge text-bg-light border border-primary rounded">
<b class="text-dark">Note:</b> @record.Note
</div>
}
</td>
<td>@tradFase(record.KeyRichiesta)</td>
<td>
@record.IdxMacchina
<div class="small textConsensed text-secondary">@record.MachineNav.Descrizione</div>
</td>
<td>
@record.NumPezzi
<div class="small textConsensed"><b>N° pezzi:</b> @record.NumPezzi</div>
<div class="small textConsensed"><b>T. Ciclo:</b> @record.Tcassegnato.ToString("N3")</div>
</td>
@*<td>@record.Note</td>*@
<td>
@record.Tcassegnato.ToString("N3")
@if (@record.Attivabile)
{
<i class="fa-regular fa-square-check text-success"></i>
}
else
{
<i class="fa-regular fa-square text-secondary"></i>
}
</td>
<td>@record.Note</td>
<td>
@if (POdlDelEnabled(record.IdxOdl))
{
+101 -54
View File
@@ -2,6 +2,7 @@
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
using MP.SPEC.Services;
namespace MP.SPEC.Components
{
@@ -12,22 +13,24 @@ namespace MP.SPEC.Components
[Parameter]
public EventCallback<bool> PagerResetReq { get; set; }
[Parameter]
public EventCallback<PODLModel> RecordSel { get; set; }
[Parameter]
public EventCallback<int> updateRecordCount { get; set; }
#endregion Public Properties
#region Public Methods
public string checkSelect(string CodArticolo)
public string checkSelect(PODLModel record)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.CodArticolo == CodArticolo) ? "table-info" : "";
answ = ((currRecord.IdxMacchina == record.IdxMacchina) && (currRecord.CodArticolo == record.CodArticolo) && (currRecord.CodFase == record.CodFase)) ? "table-info" : "";
}
catch
{ }
@@ -35,38 +38,6 @@ namespace MP.SPEC.Components
return answ;
}
protected async Task resetSel()
{
await RecordSel.InvokeAsync(null);
}
protected bool POdlDelEnabled(int idxOdl)
{
return idxOdl == 0;
}
protected async Task selRecord(PODLModel selRec)
{
await RecordSel.InvokeAsync(selRec);
}
/// <summary>
/// Eliminazione record selezioanto (previa conferma)
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
protected async Task deleteRecord(PODLModel selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Eliminazione Record: sei sicuro di voler procedere?"))
return;
await Task.Delay(1);
var done = await MDService.PODLDeleteRecord(selRec);
currRecord = null;
await reloadData();
await Task.Delay(1);
}
#endregion Public Methods
#region Protected Properties
@@ -77,6 +48,9 @@ namespace MP.SPEC.Components
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected IOApiService MpIoApiCall { get; set; }
[Inject]
protected MessageService MsgService { get; set; } = null!;
@@ -84,12 +58,59 @@ namespace MP.SPEC.Components
#region Protected Methods
protected async Task cloneRecord(PODLModel selRec)
{
// creo record duplicato...
PODLModel newRec = new PODLModel()
{
Attivabile = selRec.Attivabile,
CodArticolo = selRec.CodArticolo,
CodCli = selRec.CodCli,
CodGruppo = selRec.CodGruppo,
DueDate = selRec.DueDate,
IdxMacchina = selRec.IdxMacchina,
IdxOdl = selRec.IdxOdl,
IdxPromessa = 0,
InsertDate = selRec.InsertDate,
KeyBCode = selRec.KeyBCode,
KeyRichiesta = selRec.KeyRichiesta,
Note = $"DUPLICATED - {selRec.Note}",
NumPezzi = selRec.NumPezzi,
Priorita = selRec.Priorita,
PzPallet = selRec.PzPallet,
Tcassegnato = selRec.Tcassegnato
};
currRecord = selRec;
await RecordSel.InvokeAsync(newRec);
}
/// <summary>
/// Eliminazione record selezionato (previa conferma)
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
protected async Task deleteRecord(PODLModel selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Eliminazione Record: sei sicuro di voler procedere?"))
return;
await Task.Delay(1);
var done = await MDService.PODLDeleteRecord(selRec);
await callSyncDb(selRec);
currRecord = null;
await reloadData();
await Task.Delay(1);
}
protected override async Task OnInitializedAsync()
{
MsgService.EA_PageUpdated += MessageService_EA_PageUpdated;
MsgService.EA_SearchUpdated += OnSeachUpdated;
MsgService.EA_StatoSearch += MsgService_EA_StatoSearch;
ListStati = await MDService.AnagStatiComm();
}
protected override async Task OnParametersSetAsync()
{
await reloadData();
}
@@ -104,6 +125,23 @@ namespace MP.SPEC.Components
});
}
protected bool POdlDelEnabled(int idxOdl)
{
return idxOdl == 0;
}
protected async Task resetSel()
{
currRecord = null;
await RecordSel.InvokeAsync(null);
}
protected async Task selRecord(PODLModel selRec)
{
currRecord = selRec;
await RecordSel.InvokeAsync(selRec);
}
protected async Task UpdateData()
{
currRecord = null;
@@ -118,6 +156,8 @@ namespace MP.SPEC.Components
private List<PODLModel>? ListRecords;
private List<ListValues>? ListStati;
private List<PODLModel>? SearchRecords;
#endregion Private Fields
@@ -149,16 +189,25 @@ namespace MP.SPEC.Components
set => MsgService.StateSel = value;
}
private int totalCount
{
get => MsgService.totalCount;
set => MsgService.totalCount = value;
}
private int totalCount { get; set; } = 0;
#endregion Private Properties
#region Private Methods
/// <summary>
/// Chiama metodo x chiedere sync DB
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
private async Task callSyncDb(PODLModel selRec)
{
// chiamo aggiunta task SyncDb...
string idxMacc = selRec.IdxMacchina;
string restUrl = $"IOB/addTask2Exe/{idxMacc}?taskName=syncDbData&taskVal=";
var response = await MpIoApiCall.callMpIoUrlGet(restUrl);
}
private async void MessageService_EA_PageUpdated()
{
await reloadData();
@@ -175,6 +224,18 @@ namespace MP.SPEC.Components
});
}
private async Task reloadData()
{
isLoading = true;
SearchRecords = await MDService.ListPODLFilt(SearchVal, StatoSel);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
await updateRecordCount.InvokeAsync(totalCount);
isLoading = false;
}
private string tradFase(string codFase)
{
string answ = codFase;
@@ -189,20 +250,6 @@ namespace MP.SPEC.Components
return answ;
}
private List<ListValues>? ListStati;
private async Task reloadData()
{
isLoading = true;
SearchRecords = await MDService.ListPODLFilt(SearchVal, StatoSel);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
isLoading = false;
}
#endregion Private Methods
}
}
+13
View File
@@ -0,0 +1,13 @@
@if (@SelectedOdl != -1)
{
<div class="px-1 flex-fill">
@if (isLoading)
{
<LoadingDataSmall></LoadingDataSmall>
}
else
{
<MP.SPEC.Components.Chart.Doughnut Type="@Chart.Doughnut.ChartType.Doughnut" Data="@Data.ToArray()" BackgroundColor="@colors.ToArray()"></MP.SPEC.Components.Chart.Doughnut>
}
</div>
}
+77
View File
@@ -0,0 +1,77 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class ODLPlot
{
#region Public Properties
public int OdlId
{
get => _selParam;
}
[Parameter]
public int SelectedOdl
{
get => _selParam;
set => _selParam = value;
}
#endregion Public Properties
#region Protected Properties
//protected DataLogFilter _SelFilter { get; set; } = new DataLogFilter();
protected int _selParam { get; set; } = -1;
#endregion Protected Properties
#region Protected Methods
private bool isLoading { get; set; } = false;
protected override async Task OnInitializedAsync()
{
isLoading = true;
await Task.Delay(1);
}
private List<StatODLModel>? ListRecords = null;
protected override async Task OnParametersSetAsync()
{
await ReloadData();
await Task.Delay(1);
}
public List<double> Data = new List<double>();
public List<string> Labels = new List<string>();
public List<string> colors = new List<string>();
protected async Task ReloadData()
{
Data.Clear();
Labels.Clear();
colors.Clear();
ListRecords = await MDService.StatOdl(SelectedOdl);
foreach (var record in ListRecords)
{
Data.Add(record.TotDurata);
Labels.Add($"{record.Descrizione} - {record.TotDurata:N1}min");
colors.Add(record.Css);
}
await Task.Delay(1);
isLoading = false;
}
[Inject]
protected MpDataService MDService { get; set; } = null!;
#endregion Protected Methods
}
}
+112 -96
View File
@@ -1,110 +1,126 @@
<div class="d-flex justify-content-between">
<div class="px-0 py-1">
<div class="d-flex justify-content-between">
<div class="px-2">
<div class="d-flex justify-content-between pt-1 mb-1">
<div class="px-2">
@if (!liveUpdate)
{
<button class="btn btn-secondary" type="button" @onclick="() => toggleUpdate()">
<small>@lastUpdate</small>
</button>
}
else
{
<button class="btn btn-primary" type="button" @onclick="() => toggleUpdate()">
<span class="spinner-grow spinner-grow-sm" role="status" aria-hidden="true"></span>
Valori live
</button>
}
</div>
<div class="px-2">
@if (selMacchina != "*")
{
<button class="btn btn-warning" type="button" @onclick="() => takeSnapshot()">
<i class="fa-solid fa-camera"></i>
Registra
</button>
}
</div>
</div>
</div>
<div class="px-0">
<div class="d-flex justify-content-end">
@if (showEditPar)
@if (!liveUpdate)
{
<div class="px-0 input-group py-1" id="basic-addon1">
<button class="btn btn-primary" @onclick="() => toggleParams()"> <i class="fa-solid fa-arrow-right"></i></button>
<label class="input-group-text" for="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati"><i class="fa-solid fa-clock"></i></label>
<select @bind="@selTempoAgg" class="form-select" id="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati" style="width: 3em;">
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
</select>
<label class="input-group-text" for="maxRecord" title="Selezionare il numero massimo di record da visualizzare"><i class="fa-solid fa-list-ol"></i></label>
<select @bind="@selMaxRecord" class="form-select" id="maxRecord" title="Selezionare il numero massimo di record da visualizzare">
<option value="50">50</option>
<option value="100">100</option>
<option value="150">150</option>
<option value="200">200</option>
<option value="250">250</option>
<option value="300">300</option>
<option value="350">350</option>
<option value="400">400</option>
<option value="450">450</option>
<option value="500">500</option>
</select>
</div>
<button class="btn btn-secondary" type="button" @onclick="() => toggleUpdate()" title="Click per tornare a Valori Live">
<small>@lastUpdate</small>
</button>
}
else
{
<div class="px-2 py-1">
<button class="btn btn-primary" @onclick="() => toggleParams()"><i class="fa-solid fa-arrow-left"></i></button>
</div>
<button class="btn btn-primary" type="button" @onclick="() => toggleUpdate()">
<span class="spinner-grow spinner-grow-sm" role="status" aria-hidden="true"></span>
Valori live
</button>
}
<div class="px-0 py-1">
<div class="px-2 input-group" id="basic-addon1">
<label class="input-group-text" for="macchina" title="Selezionare la macchina"><i class="fa-solid fa-hard-drive"></i></label>
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare la macchina">
<option value="*">--- Tutti ---</option>
@if (ListMacchine != null)
</div>
<div class="px-2">
@if (selMacchina != "*")
{
<button class="btn btn-warning" type="button" @onclick="() => takeSnapshot()">
<i class="fa-solid fa-camera"></i>
@snapMode
</button>
}
</div>
<div class="px-2">
@if (snapshotDone)
{
<button class="btn btn-success" type="button" @onclick="() => navDossier()">
<div class="spinner-border spinner-border-sm" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<i class="fa-solid fa-camera"></i>
Fatto! Mostra Dossier
</button>
}
</div>
</div>
<a class="pt-2" data-bs-toggle="offcanvas" data-bs-target="#paramsFilterExample" aria-controls="paramsFilterExample" @onclick="setDtMax">
<i class="fa-solid fa-bars text-dark"></i>
</a>
<div class="offcanvas offcanvas-end" tabindex="-1" id="paramsFilterExample" aria-labelledby="paramsFilterExampleLabel">
<div class="offcanvas-header">
<h3 class="offcanvas-title" id="paramsFilterExampleLabel"><b>FILTRI</b></h3>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="small">
<label class="px-2" for="macchina" title="Selezionare impianto">Impianto</label>
</div>
<div class="px-2 input-group">
<label class="input-group-text" for="macchina" title="Selezionare impianto"><i class="fa-solid fa-hard-drive"></i></label>
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare impianto">
<option value="*">--- Tutti ---</option>
@if (ListMacchine != null)
{
foreach (var item in ListMacchine)
{
foreach (var item in ListMacchine)
{
<option value="@item">@item</option>
}
<option value="@item">@item</option>
}
</select>
<label class="input-group-text" for="flusso" title="Selezionare il tipo di flusso"><i class="fa-solid fa-sliders"></i></label>
<select @bind="@selFlux" class="form-select" id="flusso" title="Selezionare il tipo di flusso">
<option value="*">--- Tutti ---</option>
@if (ListFlux != null)
}
</select>
</div>
<div class="small mt-2">
<label class="px-2" for="flusso" title="Selezionare il parametro">Parametro</label>
</div>
<div class="px-2 input-group">
<label class="input-group-text" for="flusso" title="Selezionare il parametro"><i class="fa-solid fa-sliders"></i></label>
<select @bind="@selFlux" class="form-select" id="flusso" title="Selezionare il parametro">
<option value="*">--- Tutti ---</option>
@if (ListFlux != null)
{
foreach (var item in ListFlux)
{
foreach (var item in ListFlux)
{
<option value="@item">@item</option>
}
<option value="@item">@item</option>
}
</select>
</div>
}
</select>
</div>
<div class="small mt-2">
<label class="px-2" for="dtMin" title="Selezionare inizio periodo">Inizio Periodo</label>
</div>
<div class="px-2 input-group">
<label class="input-group-text" for="dtMin" title="Selezionare inizio periodo"><i class="fa-regular fa-calendar-minus"></i></label>
<input class="form-control" @bind="@selDtMin" id="dtMin" type="datetime-local" title="Data minima eventi da visualizzare">
</div>
<div class="small mt-2">
<label class="px-2" for="dtMax" title="Selezionare fine periodo">Fine Periodo</label>
</div>
<div class="px-2 input-group">
<label class="input-group-text" for="dtMax" title="Selezionare fine periodo"><i class="fa-regular fa-calendar-plus"></i></label>
<input class="form-control" @bind="@selDtMax" id="dtMax" type="datetime-local" title="Selezionare fine periodo">
</div>
<div class="small mt-2">
<label class="px-2" for="tempoAgg" title="Selezionare refresh rate (sec) periodo">Refresh rate (sec)</label>
</div>
<div class="px-2 input-group">
<label class="input-group-text" for="tempoAgg" title="Selezionare refresh rate (sec)"><i class="fa-solid fa-clock"></i></label>
<select @bind="@selTempoAgg" class="form-select" id="tempoAgg" title="Selezionare refresh rate (sec)" style="width: 3em;">
<option value="2">2</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="30">30</option>
<option value="60">60</option>
</select>
</div>
<div class="small mt-2">
<label class="px-2" for="maxRecord" title="Numero massimo record da mostrare">Max Record</label>
</div>
<div class="px-2 input-group">
<label class="input-group-text" for="maxRecord" title="Numero massimo record da mostrare"><i class="fa-solid fa-list-ol"></i></label>
<select @bind="@selMaxRecord" class="form-select" id="maxRecord" title="Numero massimo record da mostrare">
<option value="50">50</option>
<option value="100">100</option>
<option value="250">250</option>
<option value="500">500</option>
<option value="1000">1000</option>
<option value="2500">2500</option>
<option value="5000">5000</option>
</select>
</div>
</div>
</div>
+154 -20
View File
@@ -3,7 +3,7 @@ using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class ParamsFilter
public partial class ParamsFilter : IDisposable
{
#region Public Properties
@@ -15,7 +15,45 @@ namespace MP.SPEC.Components
#endregion Public Properties
#region Protected Fields
#region Public Methods
/// <summary>
/// Inizializzazione con periodo e arrotondamento
/// </summary>
/// <param name="minRound"></param>
/// <returns></returns>
public static DateTime RoundDatetime(int minRound)
{
TimeSpan DayElapsed = DateTime.Now.Subtract(DateTime.Today);
int minDay = (int)Math.Ceiling((double)(DayElapsed.TotalMinutes / minRound)) * minRound;
DateTime endRounded = DateTime.Today.AddMinutes(minDay);
return endRounded;
}
public void Dispose()
{
aTimer.Elapsed -= ElapsedTimer;
aTimer.Stop();
aTimer.Dispose();
}
public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
{
snapshotDone = false;
aTimer.Stop();
aTimer.Enabled = false;
//reportChange();
var pUpd = Task.Run(async () =>
{
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
});
pUpd.Wait();
}
#endregion Public Methods
#region Protected Properties
protected string lastUpdate
{
@@ -23,10 +61,6 @@ namespace MP.SPEC.Components
set => SelFilter.lastUpdate = value;
}
#endregion Protected Fields
#region Protected Properties
protected bool liveUpdate
{
get => SelFilter.LiveUpdate;
@@ -65,13 +99,11 @@ namespace MP.SPEC.Components
}
}
}
protected bool showParam { get; set; } = false;
protected bool selDt { get; set; } = false;
protected string selMacchina
{
get
{
return SelFilter.IdxMacchina;
}
get => SelFilter.IdxMacchina;
set
{
if (!SelFilter.IdxMacchina.Equals(value))
@@ -126,17 +158,72 @@ namespace MP.SPEC.Components
#region Protected Methods
protected async Task navDossier()
{
await Task.Delay(1);
// rimando alla home
NavManager.NavigateTo("DOSS", true);
}
protected override async Task OnInitializedAsync()
{
SelFilter = new SelectFluxParams();
ListMacchine = await MDService.MacchineWithFlux();
ListFlux = await MDService.ParametriGetFilt(selMacchina);
var configData = await MDService.ConfigGetAll();
var currRec = configData.FirstOrDefault(x => x.Chiave == "numOreAnticipoSnapshot");
if (currRec != null)
{
int.TryParse(currRec.Valore, out numOreAnticipoSnapshot);
}
await FilterChanged.InvokeAsync(SelFilter);
}
protected void setDtMax()
{
// copio il filtro
var currFilt = SelFilter;
// fermo update
//currFilt.LiveUpdate = false;
currFilt.CurrPage = 0;
currFilt.lastUpdate = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
currFilt.dtMax = RoundDatetime(5);
currFilt.dtMin = RoundDatetime(5).AddHours(-numOreAnticipoSnapshot);
SelFilter = currFilt;
}
protected void startTimer()
{
aTimer = new System.Timers.Timer(5000);
aTimer.Elapsed += ElapsedTimer;
aTimer.Enabled = true;
aTimer.Start();
}
protected async Task takeSnapshot()
{
// fermo udpate
liveUpdate = false;
// se non ho data rif uso adesso...
DateTime dtMax = selDtMax == null ? RoundDatetime(5) : (DateTime)selDtMax;
DateTime dtMin = selDtMin == null ? RoundDatetime(5).AddHours(-numOreAnticipoSnapshot) : (DateTime)selDtMin;
// aggiungo 2 sec
dtMax = dtMax.AddSeconds(15);
//dtMin = dtMin.AddMinutes(-30);
await MDService.DossiersTakeParamsSnapshotLast(selMacchina, dtMin, dtMax);
lastUpdate = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
// indico snapshot fatto
snapshotDone = true;
startTimer();
}
protected void toggleParams()
{
showEditPar = !showEditPar;
selDtMax = null;
}
protected async Task toggleUpdate()
@@ -145,31 +232,78 @@ namespace MP.SPEC.Components
await Task.Delay(1);
if (!liveUpdate)
{
lastUpdate = $"Last Snapshot: {DateTime.Now:yyyy/MM/dd HH:mm:ss}";
lastUpdate = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
}
else
{
selDtMax = null;
}
}
protected async Task takeSnapshot()
{
// fermo udpate
liveUpdate = false;
await MDService.DossiersTakeParamsSnapshot(selMacchina, 10);
lastUpdate = $"Last Snapshot: {DateTime.Now:yyyy/MM/dd HH:mm:ss}";
}
#endregion Protected Methods
#region Private Fields
private static System.Timers.Timer aTimer = new System.Timers.Timer();
private List<string>? ListFlux = null;
private List<string>? ListMacchine = null;
private int numOreAnticipoSnapshot = 5;
private bool snapshotDone = false;
#endregion Private Fields
#region Private Properties
[Inject]
private NavigationManager NavManager { get; set; } = null!;
private DateTime? selDtMax
{
get => SelFilter.dtMax;
set
{
if (SelFilter.dtMax != value)
{
// copio il filtro
var currFilt = SelFilter;
// fermo update
currFilt.LiveUpdate = false;
currFilt.CurrPage = 0;
currFilt.lastUpdate = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
currFilt.dtMax = value;
SelFilter = currFilt;
reportChange();
}
}
}
private DateTime? selDtMin
{
get => SelFilter.dtMin;
set
{
if (SelFilter.dtMin != value)
{
// copio il filtro
var currFilt = SelFilter;
// fermo update
currFilt.LiveUpdate = false;
currFilt.CurrPage = 0;
currFilt.lastUpdate = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
currFilt.dtMin = value;
SelFilter = currFilt;
reportChange();
}
}
}
private bool showEditPar { get; set; } = false;
private string snapMode
{
get => SelFilter.dtRif == null ? "Realtime Rec" : $"Rec {SelFilter.dtRif:yyyy/MM/dd HH:mm:ss}";
}
#endregion Private Properties
#region Private Methods
+12
View File
@@ -0,0 +1,12 @@
<div class="input-group input-group-sm">
<div class="input-group-text">
<span class="me-1 @leftStringCSS">@leftString</span>
<div class="form-check form-check-sm form-switch py-1" title="Parameter View Mode (RealTime / LogData)">
<input class="form-check-input" type="checkbox" id="mySwitch" name="setupAlarms" checked @onclick="() => toggle()">
</div>
<span class="@rightStringCSS">@rightString</span>
</div>
</div>
+127
View File
@@ -0,0 +1,127 @@
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 MP.SPEC;
using MP.SPEC.Shared;
using MP.SPEC.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class ToggleMode
{
[Parameter]
public EventCallback<SelectGlobalToggle> FilterChanged { get; set; }
[Parameter]
public SelectGlobalToggle SelFilter { get; set; } = new SelectGlobalToggle();
protected bool isActive
{
get => SelFilter.isActive;
set
{
if (SelFilter.isActive != value)
{
SelFilter.isActive = value;
reportChange();
}
}
}
protected string leftString
{
get => SelFilter.leftString;
set
{
if (SelFilter.leftString != value)
{
SelFilter.leftString = value;
reportChange();
}
}
}
protected string leftStringCSS
{
get => SelFilter.leftStringCSS;
set
{
if (SelFilter.leftStringCSS != value)
{
SelFilter.leftStringCSS = value;
reportChange();
}
}
}
protected string rightString
{
get => SelFilter.rightString;
set
{
if (SelFilter.rightString != value)
{
SelFilter.rightString = value;
reportChange();
}
}
}
protected string rightStringCSS
{
get => SelFilter.rightStringCSS;
set
{
if (SelFilter.rightStringCSS != value)
{
SelFilter.rightStringCSS = value;
reportChange();
}
}
}
protected void toggle()
{
var currFilt = SelFilter;
currFilt.isActive = !currFilt.isActive;
SelFilter = currFilt;
if (isActive)
{
rightStringCSS = "fw-bold";
leftStringCSS = "text-secondary";
}
else
{
leftStringCSS = "fw-bold";
rightStringCSS = "text-secondary";
}
}
protected override async Task OnInitializedAsync()
{
if (isActive)
{
rightStringCSS = "fw-bold";
leftStringCSS = "text-secondary";
}
else
{
leftStringCSS = "fw-bold";
rightStringCSS = "text-secondary";
}
await FilterChanged.InvokeAsync(SelFilter);
}
private void reportChange()
{
FilterChanged.InvokeAsync(SelFilter);
}
}
}
+206 -30
View File
@@ -274,12 +274,67 @@ namespace MP.SPEC.Data
return await Task.FromResult(dbController.ConfigUpdate(updRec));
}
public List<FluxLog> convertToFluxLog(string Valore)
public List<FluxLogDTO> getFluxLog(string Valore)
{
//string valStriped = Valore.Substring(7, Valore.Length - 8);
//var result = JsonConvert.DeserializeObject<List<FluxLog>>(valStriped);
var result = JsonConvert.DeserializeObject<DossierFluxLogDTO>(Valore);
return result.ODL;
List<FluxLogDTO> answ = new List<FluxLogDTO>();
DossierFluxLogDTO? result = JsonConvert.DeserializeObject<DossierFluxLogDTO>(Valore);
if (result != null)
{
if (result.ODL != null)
{
answ = result
.ODL
.OrderBy(x => x.CodFlux)
.ToList();
// inizializzo SE necessario
foreach (var item in answ)
{
item.ValoreEdit = String.IsNullOrEmpty(item.ValoreEdit) ? item.Valore : item.ValoreEdit;
}
}
}
return answ;
}
public async Task<bool> updateDossierValue(Dossiers currDoss, FluxLogDTO editFL)
{
bool answ = false;
// recupero intero set valori dossier deserializzando...
var fluxLogList = getFluxLog(currDoss.Valore);
await Task.Delay(1);
// se tutto ok
if (fluxLogList != null)
{
// da provare...!!!!
// elimino vecchio record
var currRec = fluxLogList.FirstOrDefault(x => x.CodFlux == editFL.CodFlux && x.dtEvento == editFL.dtEvento);
if (currRec != null)
{
fluxLogList.Remove(currRec);
// aggiungo nuovo
fluxLogList.Add(editFL);
}
// serializzo nuovamente valore
DossierFluxLogDTO? result = new DossierFluxLogDTO();
var ODLflux = result.ODL.ToList();
foreach (var item in fluxLogList)
{
ODLflux.Add(item);
}
DossierFluxLogDTO updatedResult = new DossierFluxLogDTO(){ODL = ODLflux};
string rawVal = JsonConvert.SerializeObject(updatedResult);
currDoss.Valore = rawVal;
// aggiorno record sul DB
await dbController.DossiersUpdateValore(currDoss);
}
return answ;
}
public void Dispose()
@@ -289,6 +344,26 @@ namespace MP.SPEC.Data
redisConn.Dispose();
}
/// <summary>
/// Eliminazione di un dossier
/// </summary>
/// <param name="selRecord">record dossier da eliminare</param>
/// <returns></returns>
public async Task<bool> DossiersDeleteRecord(Dossiers selRecord)
{
bool result = false;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
result = await dbController.DossiersDeleteRecord(selRecord);
// elimino cache redis...
RedisValue pattern = new RedisValue($"{redisDossByMac}:*");
bool answ = await ExecFlushRedisPattern(pattern);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"DossiersDeleteRecord | IdxMacchina {selRecord.IdxMacchina} | DtRif {selRecord.DtRif} | IdxODL {selRecord.IdxODL} | {ts.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco ultimi n record DOssiers (che contengono ad esempio "salvataggi" di FLuxLog) dato
/// macchina (ordinato x data registrazione)
@@ -297,13 +372,13 @@ namespace MP.SPEC.Data
/// <param name="DtRef">Data di riferimento (Massima) per estrazione records</param>
/// <param name="MaxRec">numero massimo record da restituire</param>
/// <returns></returns>
public async Task<List<Dossiers>> DossiersGetLastFilt(string IdxMacchina, DateTime DtRef, int MaxRec)
public async Task<List<Dossiers>> DossiersGetLastFilt(string IdxMacchina, string CodArticolo, DateTime DtRef, int MaxRec)
{
List<Dossiers>? result = new List<Dossiers>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = $"{redisDossByMac}:{IdxMacchina}";
string currKey = $"{redisDossByMac}:{IdxMacchina}:{CodArticolo}:{DtRef}:{MaxRec}";
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
@@ -313,7 +388,7 @@ namespace MP.SPEC.Data
}
else
{
result = await Task.FromResult(dbController.DossiersGetLastFilt(IdxMacchina, DtRef, MaxRec));
result = await Task.FromResult(dbController.DossiersGetLastFilt(IdxMacchina, CodArticolo, DtRef, MaxRec));
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5));
@@ -332,14 +407,36 @@ namespace MP.SPEC.Data
/// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache redis
/// </summary>
/// <param name="IdxMacchina">macchina</param>
/// <param name="maxSec">NUm massimo secondi per recuperare dati correnti</param>
/// <param name="MaxSec">NUm massimo secondi per recuperare dati correnti</param>
/// <param name="DtRif">DataOra riferimento x cui prendere valori antecedenti</param>
/// <returns></returns>
public async Task<bool> DossiersTakeParamsSnapshot(string IdxMacchina, int MaxSec)
public async Task<bool> DossiersTakeParamsSnapshot(string IdxMacchina, int MaxSec, DateTime DtRif)
{
bool answ = false;
await Task.Delay(1);
// chiamo stored x salvare parametri
dbController.DossiersTakeParamsSnapshot(IdxMacchina, MaxSec);
dbController.DossiersTakeParamsSnapshot(IdxMacchina, MaxSec, DtRif);
// svuoto cache redis x macchina
string currKey = $"{redisDossByMac}:{IdxMacchina}";
redisDb.StringSet(currKey, "", TimeSpan.FromSeconds(1));
currKey = $"{redisDossByMac}:*";
redisDb.StringSet(currKey, "", TimeSpan.FromSeconds(1));
return answ;
}
/// <summary>
/// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache redis
/// </summary>
/// <param name="IdxMacchina">macchina</param>
/// <param name="MaxSec">NUm massimo secondi per recuperare dati correnti</param>
/// <param name="DtRif">DataOra riferimento x cui prendere valori antecedenti</param>
/// <returns></returns>
public async Task<bool> DossiersTakeParamsSnapshotLast(string IdxMacchina, DateTime dtMin, DateTime dtMax)
{
bool answ = false;
await Task.Delay(1);
// chiamo stored x salvare parametri
dbController.DossiersTakeParamsSnapshotLast(IdxMacchina, dtMin, dtMax);
// svuoto cache redis x macchina
string currKey = $"{redisDossByMac}:{IdxMacchina}";
redisDb.StringSet(currKey, "", TimeSpan.FromSeconds(1));
@@ -357,6 +454,16 @@ namespace MP.SPEC.Data
return Task.FromResult(dbController.AnagGruppiAziende());
}
/// <summary>
/// Statistiche ODL calcolate (da stored stp_STAT_ODL)
/// </summary>
/// <returns></returns>
public Task<List<StatODLModel>> StatOdl(int IdxOdl)
{
return dbController.StatOdl(IdxOdl);
}
/// <summary>
/// Restitusice elenco fasi
/// </summary>
@@ -374,36 +481,24 @@ namespace MP.SPEC.Data
public async Task<bool> FlushRedisCache()
{
await Task.Delay(1);
bool answ = false;
var listEndpoints = redisConnAdmin.GetEndPoints();
var server = redisConnAdmin.GetServer(listEndpoints[0]);
RedisValue pattern = new RedisValue($"{redisBaseAddr}*");
if (server != null)
{
var keyList = server.Keys(redisDb.Database, pattern);
foreach (var item in keyList)
{
await redisDb.KeyDeleteAsync(item);
}
// brutalmente rimuovo intero contenuto DB... DANGER
//await server.FlushDatabaseAsync();
answ = true;
}
bool answ = await ExecFlushRedisPattern(pattern);
return answ;
}
/// <summary>
/// Elenco ultimi n record flux log dato macchina e flusso (ordinato x data registrazione)
/// </summary>
/// <param name="DtMax">Data massima (recupera eventi antecedenti)</param>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
/// <param name="CodFlux">*=tutti, altrimenti solo selezionato</param>
/// <param name="MaxRec">numero massimo record da restituire</param>
/// <returns></returns>
public async Task<List<FluxLog>> FluxLogGetLastFilt(string IdxMacchina, string CodFlux, int MaxRec)
public async Task<List<FluxLog>> FluxLogGetLastFilt(DateTime DtMax, string IdxMacchina, string CodFlux, int MaxRec)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
var results = await Task.FromResult(dbController.FluxLogGetLastFilt(IdxMacchina, CodFlux, MaxRec));
var results = await Task.FromResult(dbController.FluxLogGetLastFilt(DtMax, IdxMacchina, CodFlux, MaxRec));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"FluxLogGetLastFilt | Read from DB: {ts.TotalMilliseconds}ms");
@@ -443,9 +538,9 @@ namespace MP.SPEC.Data
/// <param name="codArt">Cod articolo</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <returns></returns>
public async Task<List<ODLModel>> ListODLFilt(bool inCorso, string codArt, string keyRichPart)
public async Task<List<ODLModel>> ListODLFilt(bool inCorso, string codArt, string keyRichPart, DateTime startDate, DateTime endDate)
{
return await Task.FromResult(dbController.ListODLFilt(inCorso, codArt, keyRichPart));
return await Task.FromResult(dbController.ListODLFilt(inCorso, codArt, keyRichPart, startDate, endDate));
}
/// <summary>
@@ -514,7 +609,7 @@ namespace MP.SPEC.Data
}
else
{
result = await Task.FromResult(dbController.MacchineWithFlux());
result = await dbController.MacchineWithFlux();
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
@@ -529,6 +624,42 @@ namespace MP.SPEC.Data
return result;
}
/// <summary>
/// Elenco Codice articolo con dati dossier gestiti
/// </summary>
/// <returns></returns>
public async Task<List<string>> ArticleWithDossier()
{
List<string>? result = new List<string>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = redisArtByDossier;
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
readType = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ArticleWithDossier());
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<string>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ArticleWithDossier | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco di tutti i parametri filtrati x macchina
/// </summary>
@@ -611,15 +742,27 @@ namespace MP.SPEC.Data
#region Private Fields
private const string redisBaseAddr = "MP:";
private const string redisConfKey = redisBaseAddr + "SPEC:Cache:Config";
private const string redisDossByMac = redisBaseAddr + "SPEC:Cache:DossByMac";
private const string redisFluxByMac = redisBaseAddr + "SPEC:Cache:FluxByMac";
private const string redisMacByFlux = redisBaseAddr + "SPEC:Cache:MacByFlux";
private const string redisArtByDossier = redisBaseAddr + "SPEC:Cache:ArtByDossier";
private const string redisMacList = redisBaseAddr + "SPEC:Cache:MacList";
private const string redisStatoCom = redisBaseAddr + "SPEC:Cache:StatoCom";
private const string redisTipoArt = redisBaseAddr + "SPEC:Cache:TipoArt";
private static IConfiguration _configuration = null!;
private static ILogger<MpDataService> _logger = null!;
private static Logger Log = LogManager.GetCurrentClassLogger();
/// <summary>
@@ -640,5 +783,38 @@ namespace MP.SPEC.Data
private int redisLongTimeCache = 5;
#endregion Private Fields
#region Private Methods
/// <summary>
/// Esegue flush memoria redis dato pattern
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
private async Task<bool> ExecFlushRedisPattern(RedisValue pattern)
{
bool answ = false;
var listEndpoints = redisConnAdmin.GetEndPoints();
foreach (var endPoint in listEndpoints)
{
//var server = redisConnAdmin.GetServer(listEndpoints[0]);
var server = redisConnAdmin.GetServer(endPoint);
if (server != null)
{
var keyList = server.Keys(redisDb.Database, pattern);
foreach (var item in keyList)
{
await redisDb.KeyDeleteAsync(item);
}
// brutalmente rimuovo intero contenuto DB... DANGER
//await server.FlushDatabaseAsync();
answ = true;
}
}
return answ;
}
#endregion Private Methods
}
}
+22 -16
View File
@@ -11,13 +11,26 @@
#region Public Properties
public int CurrPage { get; set; } = 1;
public DateTime DtRef { get; set; } = InitDatetime(5);
public string IdxMacchina { get; set; } = "*";
public string CodArticolo { get; set; } = "*";
public int MaxRecord { get; set; } = 100;
#endregion Public Properties
#region Public Methods
/// <summary>
        /// Inizializzazione con periodo e arrotondamento
        /// </summary>
        /// <param name="minRound"></param>
        /// <param name="numDayPrev"></param>
        /// <returns></returns>
        public static DateTime Init(int minRound)
/// Inizializzazione con periodo e arrotondamento
/// </summary>
/// <param name="minRound"></param>
/// <returns></returns>
public static DateTime InitDatetime(int minRound)
{
TimeSpan DayElapsed = DateTime.Now.Subtract(DateTime.Today);
int minDay = (int)Math.Ceiling((double)(DayElapsed.TotalMinutes / minRound)) * minRound;
@@ -25,16 +38,6 @@
return endRounded;
}
public string IdxMacchina { get; set; } = "*";
public int MaxRecord { get; set; } = 100;
public DateTime DtRef { get; set; } = Init(5);
public int CurrPage { get; set; } = 1;
#endregion Public Properties
#region Public Methods
public override bool Equals(object obj)
{
if (!(obj is SelectDossierParams item))
@@ -43,6 +46,9 @@
if (IdxMacchina != item.IdxMacchina)
return false;
if (CodArticolo != item.CodArticolo)
return false;
if (MaxRecord != item.MaxRecord)
return false;
+6 -3
View File
@@ -12,13 +12,16 @@
#region Public Properties
public string CodFlux { get; set; } = "*";
public int CurrPage { get; set; } = 1;
public DateTime? dtRif { get; set; } = null;
public DateTime? dtMax { get; set; } = null;
public DateTime? dtMin { get; set; } = null;
public string IdxMacchina { get; set; } = "*";
public string lastUpdate { get; set; } = "-";
public bool LiveUpdate { get; set; } = true;
public int MaxRecord { get; set; } = 100;
public int TempoAgg { get; set; } = 2000;
public int CurrPage { get; set; } = 1;
public string lastUpdate { get; set; } = "-";
public int TempoAgg { get; set; } = 10000;
#endregion Public Properties
+74
View File
@@ -0,0 +1,74 @@
namespace MP.SPEC.Data
{
public class SelectGlobalToggle
{
#region Public Constructors
public SelectGlobalToggle()
{ }
#endregion Public Constructors
#region Public Properties
/// <summary>
/// Bool: indica se il toggle è attivo
/// </summary>
public bool isActive { get; set; } = true;
/// <summary>
/// string: stringa da mostrare a sinistra (disattivo onInitialize)
/// </summary>
public string leftString { get; set; } = "";
/// <summary>
/// string: stringa da mostrare a destra (attivo onInitialize)
/// </summary>
public string rightString { get; set; } = "";
/// <summary>
/// string: stile stringa da mostrare a sinistra (disattivo onInitialize)
/// </summary>
public string leftStringCSS { get; set; } = "";
/// <summary>
/// string: stile stringa da mostrare a destra (attivo onInitialize)
/// </summary>
public string rightStringCSS { get; set; } = "";
#endregion Public Properties
#region Public Methods
public override bool Equals(object obj)
{
if (!(obj is SelectGlobalToggle item))
return false;
if (isActive != item.isActive)
return false;
if (leftString != item.leftString)
return false;
if (rightString != item.rightString)
return false;
if (leftStringCSS != item.leftStringCSS)
return false;
if (rightStringCSS != item.rightStringCSS)
return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion Public Methods
}
}
+68
View File
@@ -0,0 +1,68 @@
using MP.Data;
namespace MP.SPEC.Data
{
public class SelectOdlParams
{
#region Public Constructors
public SelectOdlParams()
{ }
#endregion Public Constructors
#region Public Properties
public string CodStato { get; set; } = "*";
public int CurrPage { get; set; } = 1;
public int NumRec { get; set; } = 10;
public DateTime DtEnd { get; set; } = Utils.InitDatetime(DateTime.Now, 5);
public DateTime DtStart { get; set; } = Utils.InitDatetime(DateTime.Now, 5).AddDays(-7);
public int MaxRecord { get; set; } = 100;
public bool IsActive { get; set; } = true;
public string SearchVal { get; set; } = "*";
#endregion Public Properties
#region Public Methods
public override bool Equals(object obj)
{
if (!(obj is SelectOdlParams item))
return false;
if (IsActive != item.IsActive)
return false;
if (CodStato != item.CodStato)
return false;
if (MaxRecord != item.MaxRecord)
return false;
if (NumRec != item.NumRec)
return false;
if (DtStart != item.DtStart)
return false;
if (DtEnd != item.DtEnd)
return false;
if (CurrPage != item.CurrPage)
return false;
if (SearchVal != item.SearchVal)
return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion Public Methods
}
}
+13 -7
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP.SPEC</RootNamespace>
<Version>6.16.2209.2110</Version>
<Version>6.16.2210.1417</Version>
</PropertyGroup>
<ItemGroup>
@@ -14,15 +14,21 @@
<ItemGroup>
<None Include="compilerconfig.json" />
<None Include="wwwroot\lib\Chart.js\chart.esm.js" />
<None Include="wwwroot\lib\Chart.js\chart.esm.min.js" />
<None Include="wwwroot\lib\Chart.js\chart.js" />
<None Include="wwwroot\lib\Chart.js\chart.min.js" />
<None Include="wwwroot\lib\Chart.js\helpers.esm.js" />
<None Include="wwwroot\lib\Chart.js\helpers.esm.min.js" />
<None Include="wwwroot\lib\chartjs-adapter-luxon\chartjs-adapter-luxon.esm.js" />
<None Include="wwwroot\lib\chartjs-adapter-luxon\chartjs-adapter-luxon.esm.min.js" />
<None Include="wwwroot\lib\chartjs-adapter-luxon\chartjs-adapter-luxon.js" />
<None Include="wwwroot\lib\chartjs-adapter-luxon\chartjs-adapter-luxon.min.js" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.6" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\lib\" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup>
+4 -3
View File
@@ -3,7 +3,7 @@
@using MP.SPEC.Components
@using MP.SPEC.Data
<div class="card">
<div class="card mb-5">
<div class="card-header table-primary">
<div class="d-flex justify-content-between">
<div class="px-0">
@@ -35,7 +35,7 @@
{
<div class="row">
<div class="col-12">
<div class="card">
<div class="card mb-5">
<div class="card-header bg-primary text-light">Modifica</div>
<div class="card-body">
@@ -135,7 +135,8 @@
{
<tr class="@checkSelect(@record.CodArticolo)">
<td>
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm" title="Modifica Record"><i class="bi bi-pencil-square"></i></button>
<button @onclick="() => cloneRecord(record)" class="btn btn-info btn-sm" title="Duplica Record"><i class="bi bi-clipboard-check"></i></button>
</td>
<td>
<div>@record.CodArticolo</div>
+20 -1
View File
@@ -97,7 +97,7 @@ namespace MP.SPEC.Pages
}
/// <summary>
/// Eliminazione record selezioanto (previa conferma)
/// Eliminazione record selezionato (previa conferma)
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
@@ -136,6 +136,10 @@ namespace MP.SPEC.Pages
}
ListAziende = await MDService.ElencoAziende();
ListTipoArt = await MDService.AnagTipoArtLV();
}
protected override async Task OnParametersSetAsync()
{
await reloadData();
}
@@ -155,6 +159,21 @@ namespace MP.SPEC.Pages
currRecord = selRec;
await Task.Delay(1);
}
protected async Task cloneRecord(AnagArticoli selRec)
{
// creo record duplicato...
AnagArticoli newRec = new AnagArticoli()
{
Azienda = selRec.Azienda,
CodArticolo = selRec.CodArticolo,
DescArticolo = $"CLONE - { selRec.DescArticolo }",
Disegno = selRec.Disegno,
Tipo=selRec.Tipo
};
currRecord = newRec;
await Task.Delay(1);
}
protected async Task update(AnagArticoli selRec)
{
+65 -10
View File
@@ -1,6 +1,6 @@
@page "/DOSS"
<div class="card">
<div class="card mb-5">
<div class="card-header table-primary">
<div class="d-flex">
<div class="px-0 py-1">
@@ -14,24 +14,79 @@
}
else
{
<DossiersFilter FilterChanged="updateFilter"></DossiersFilter>
}
</div>
</div>
</div>
<div class="card-body">
@if (isLoading)
@if (currDetFluxLogRecord != null)
{
<LoadingData></LoadingData>
}
else
{
<ListDossiers SelFilter="@currFilter" TotRecordChanged="updateTotal"></ListDossiers>
<div class="row">
<div class="col-12">
<div class="card mb-5">
<div class="card-header bg-primary text-light">Modifica Parametro</div>
<div class="card-body">
<div class="row">
<div class="col-3 pe-0">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">MACCHINA</span>
<input type="text" class="form-control" disabled aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@currDetFluxLogRecord.IdxMacchina">
</div>
</div>
<div class="col-3 pe-0">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">DATA</span>
<input type="text" class="form-control" disabled aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@currDetFluxLogRecord.dtEvento">
</div>
</div>
<div class="col-3 pe-0">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">DATA TYPE</span>
<input type="text" class="form-control" disabled aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@currDetFluxLogRecord.CodFlux">
</div>
</div>
<div class="col-3 pe-0">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">VALORE</span>
<input type="text" class="form-control" aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@currDetFluxLogRecord.ValoreEdit">
</div>
</div>
</div>
<div class="row pt-4">
<div class="col-3 pe-0">
</div>
<div class="col-3 pe-0">
</div>
<div class="col-3 pe-0">
<div class="d-grid gap-2">
<button @onclick="() => cancel()" class="btn btn-warning">Annulla <i class="bi bi-x-circle"></i></button>
</div>
</div>
<div class="col-3 pe-0">
<div class="d-grid gap-2">
<button @onclick="() => update(currDetFluxLogRecord)" class="btn btn-success">Save <i class="bi bi-save"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
</div>
<div class="card-footer py-1">
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" totalCount="totalCount" showLoading="isLoading" />
</div>
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
<ListDossiers SelFilter="@currFilter" RecordSel="@selRecordDoss" RecordSelFlux="@selRecordFlux" TotRecordChanged="updateTotal"></ListDossiers>
}
</div>
<div class="card-footer py-1">
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
</div>
+61
View File
@@ -1,4 +1,7 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using MP.SPEC.Components;
using MP.SPEC.Data;
@@ -14,6 +17,12 @@ namespace MP.SPEC.Pages
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MsgService { get; set; } = null!;
@@ -21,11 +30,23 @@ namespace MP.SPEC.Pages
#region Protected Methods
protected async Task cancel()
{
currDetFluxLogRecord = null;
await Task.Delay(1);
}
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
StateHasChanged();
}
protected override async Task OnInitializedAsync()
{
isLoading = true;
@@ -42,6 +63,33 @@ namespace MP.SPEC.Pages
isFiltering = false;
}
protected async Task selRecordDoss(Dossiers selDoss)
{
currRecordDoss = selDoss;
await Task.Delay(1);
}
protected async Task selRecordFlux(FluxLogDTO selRec)
{
currDetFluxLogRecord = selRec;
await Task.Delay(1);
}
protected async Task update(FluxLogDTO selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi di voler salvare le modifiche? queste saranno parte del dossier inviato all'impianto"))
return;
await Task.Delay(1);
if (currRecordDoss != null)
{
// METODO PER UPDATE FLUX
await MDService.updateDossierValue(currRecordDoss, selRec);
}
currDetFluxLogRecord = null;
await Task.Delay(1);
}
protected void updateTotal(int newTotCount)
{
totalCount = newTotCount;
@@ -49,8 +97,20 @@ namespace MP.SPEC.Pages
#endregion Protected Methods
#region Private Fields
private FluxLogDTO? _currDetFluxLogRecord = null;
#endregion Private Fields
#region Private Properties
private FluxLogDTO? currDetFluxLogRecord
{
get => _currDetFluxLogRecord;
set { _currDetFluxLogRecord = value; }
}
private SelectDossierParams currFilter { get; set; } = new SelectDossierParams();
private int currPage
@@ -59,6 +119,7 @@ namespace MP.SPEC.Pages
set => MsgService.currPage = value;
}
private Dossiers? currRecordDoss { get; set; } = null;
private bool isFiltering { get; set; } = false;
private bool isLoading { get; set; } = true;
+21 -5
View File
@@ -8,20 +8,36 @@ namespace MP.SPEC.Pages
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private readonly ILogger<ErrorModel> _logger;
#region Public Constructors
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
#endregion Public Constructors
#region Public Properties
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
#endregion Public Properties
#region Public Methods
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
#endregion Public Methods
#region Private Fields
private readonly ILogger<ErrorModel> _logger;
#endregion Private Fields
}
}
+3 -2
View File
@@ -2,7 +2,7 @@
<PageTitle>Index</PageTitle>
<div class="card">
<div class="card mb-5">
<div class="card-header bg-dark text-light">
<div class="d-flex justify-content-between">
<div class="p-2">
@@ -18,7 +18,7 @@
</div>
<div class="card-body text-center">
<div class="shortcuts my-5 py-5">
<div class="shortcuts my-3 py-3">
<div class="row">
<div class="col-12">
@if (ElencoLink == null)
@@ -33,6 +33,7 @@
}
else
{
foreach (var item in ElencoLink)
{
<a href="@item.NavigateUrl" class="shortcut">
+69 -17
View File
@@ -1,30 +1,82 @@
@page "/ODL"
<div class="card">
<div class="card-header table-primary">
<div class="d-flex justify-content-between">
<div class="px-1">
<h3><b>ODL</b></h3>
<div class="card mb-5">
<div class="card-header table-primary ">
<div class="d-flex justify-content-between col-12">
<div class="px-1 col-4">
<div>
<h3><b>ODL</b></h3>
</div>
</div>
<div class="px-2">
<div class="input-group input-group">
<label class="input-group-text" for="maxRecord" title="Selezionare la fase da visualizzare"><i class="fa-solid fa-screwdriver-wrench"></i></label>
<select @bind="@selStato" class="form-select"title="Selezionare la fase da visualizzare">
<option value="*">--- Tutti ---</option>
@if (ListStati != null)
<div class="col-4">
<div class="input-group input-group-sm">
<div class="input-group-text">
<span class="me-1 @leftStringCSS">Completati</span>
<span class="form-check form-check-sm form-switch py-1" title="ODL Chiusi / Correnti">
<input class="form-check-input" type="checkbox" id="switchActive" @bind="@isActive">
</span>
<span class="@rightStringCSS">In Corso</span>
</div>
</div>
</div>
<div class="d-flex justify-content-end">
<a class="pt-2 text-dark" data-bs-toggle="offcanvas" data-bs-target="#paramsFilterExample" aria-controls="paramsFilterExample" @onclick="setDtMax">
<i class="fa-solid fa-bars"></i>
</a>
<div class="offcanvas offcanvas-end" tabindex="-1" id="paramsFilterExample" aria-labelledby="paramsFilterExampleLabel">
<div class="offcanvas-header">
<h3 class="offcanvas-title" id="paramsFilterExampleLabel"><b>FILTRI</b></h3>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div>
<div>
Seleziona i filtri per:
</div>
</div>
<div>
<div class="small mt-2">
<label class="px-2" for="macchina" title="Selezionare inizio periodo">Macchina</label>
</div>
<div class="input-group px-2">
<label class="input-group-text" for="macchina" title="Selezionare la fase da visualizzare"><i class="fa-solid fa-screwdriver-wrench"></i></label>
<select @bind="@selStato" id="macchina" class="form-select" title="Selezionare la fase da visualizzare">
<option value="*">--- Tutti ---</option>
@if (ListStati != null)
{
foreach (var item in ListStati)
{
<option value="@item.value">@item.label</option>
}
}
</select>
</div>
</div>
@if (!isActive)
{
foreach (var item in ListStati)
{
<option value="@item.value">@item.label</option>
}
<div class="small mt-2">
<label class="px-2" for="dtMin" title="Selezionare inizio periodo">Inizio Periodo</label>
</div>
<div class="px-2 input-group">
<label class="input-group-text" for="dtMin" title="Selezionare inizio periodo"><i class="fa-regular fa-calendar-minus"></i></label>
<input class="form-control" @bind="@selDtStart" id="dtMin" type="datetime-local" title="Data minima eventi da visualizzare">
</div>
<div class="small mt-2">
<label class="px-2" for="dtMax" title="Selezionare fine periodo">Fine Periodo</label>
</div>
<div class="px-2 input-group">
<label class="input-group-text" for="dtMax" title="Selezionare fine periodo"><i class="fa-regular fa-calendar-plus"></i></label>
<input class="form-control" @bind="@selDtEnd" id="dtMax" type="datetime-local" title="Selezionare fine periodo">
</div>
}
</select>
</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<ListODL StatoSel="@selStato" PagerResetReq="pgResetReq"></ListODL>
<ListODL PagerResetReq="pgResetReq" updateRecordCount="UpdateTotCount" currFilter="@currFilter"></ListODL>
</div>
<div class="card-footer py-1">
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
+77 -17
View File
@@ -7,6 +7,23 @@ namespace MP.SPEC.Pages
{
public partial class ODL
{
#region Public Methods
/// <summary>
/// Inizializzazione con periodo e arrotondamento
/// </summary>
/// <param name="minRound"></param>
/// <returns></returns>
public static DateTime RoundDatetime(int minRound)
{
TimeSpan DayElapsed = DateTime.Now.Subtract(DateTime.Today);
int minDay = (int)Math.Ceiling((double)(DayElapsed.TotalMinutes / minRound)) * minRound;
DateTime endRounded = DateTime.Today.AddMinutes(minDay);
return endRounded;
}
#endregion Public Methods
#region Protected Fields
protected DataPager pagerODL;
@@ -15,6 +32,12 @@ namespace MP.SPEC.Pages
#region Protected Properties
protected bool isActive
{
get => currFilter.IsActive;
set => currFilter.IsActive = value;
}
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
@@ -24,6 +47,30 @@ namespace MP.SPEC.Pages
[Inject]
protected MessageService MsgService { get; set; } = null!;
protected DateTime selDtEnd
{
get => currFilter.DtEnd;
set
{
if (currFilter.DtEnd != value)
{
currFilter.DtEnd = value;
}
}
}
protected DateTime selDtStart
{
get => currFilter.DtStart;
set
{
if (currFilter.DtStart != value)
{
currFilter.DtStart = value;
}
}
}
#endregion Protected Properties
#region Protected Methods
@@ -44,10 +91,11 @@ namespace MP.SPEC.Pages
MsgService.ShowSearch = true;
// resetto search
MsgService.SearchVal = "";
ListAziende = await MDService.ElencoAziende();
ListStati = await MDService.AnagStatiComm();
#if false
// carico dati
await reloadData();
#endif
}
protected async Task pgResetReq(bool doReset)
@@ -58,20 +106,29 @@ namespace MP.SPEC.Pages
}
}
protected void setDtMax()
{
// copio il filtro
currFilter.DtEnd = RoundDatetime(5);
currFilter.DtStart = RoundDatetime(5).AddDays(-1);
}
protected void UpdateTotCount(int newTotCount)
{
totalCount = newTotCount;
}
#endregion Protected Methods
#region Private Fields
private MP.Data.DatabaseModels.ODLModel? currRecordOdl = null;
private MP.Data.DatabaseModels.PODLModel? currRecordPOdl = null;
private List<MP.Data.DatabaseModels.AnagGruppi>? ListAziende;
private List<MP.Data.DatabaseModels.ListValues>? ListStati;
#endregion Private Fields
#region Private Properties
private string currAzienda { get; set; } = "*";
private SelectOdlParams currFilter { get; set; } = new SelectOdlParams();
private int currPage
{
@@ -81,13 +138,27 @@ namespace MP.SPEC.Pages
private bool isLoading { get; set; } = false;
private string leftStringCSS
{
get => isActive ? "text-secondary" : "text-dark fw-bold";
}
private int numRecord
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
}
private string selStato { get; set; } = "*";
private string rightStringCSS
{
get => isActive ? "text-dark fw-bold" : "text-secondary";
}
private string selStato
{
get => currFilter.CodStato;
set => currFilter.CodStato = value;
}
private int totalCount
{
@@ -96,16 +167,5 @@ namespace MP.SPEC.Pages
}
#endregion Private Properties
#region Private Methods
private async Task reloadData()
{
isLoading = true;
await Task.Delay(1);
isLoading = false;
}
#endregion Private Methods
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
@page "/PARAMS"
<div class="card">
<div class="card mb-5">
<div class="card-header table-primary">
<div class="d-flex">
<div class="px-0 py-1">
@@ -25,7 +25,7 @@
}
else
{
<ListPARAMS SelFilter="@currFilter" TotRecordChanged="@updateTotal"></ListPARAMS>
<ListPARAMS SelFilter="@currFilter" TotRecordChanged="@updateTotal" RecordSel="@detailSel"></ListPARAMS>
}
</div>
<div class="card-footer py-1">
+31 -8
View File
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.SPEC.Components;
using MP.SPEC.Data;
@@ -29,8 +30,12 @@ namespace MP.SPEC.Pages
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
currFilter.lastUpdate= $"Last Snapshot: {DateTime.Now:yyyy/MM/dd HH:mm:ss}";
currFilter.LiveUpdate = (currPage == 1);
DateTime adesso = DateTime.Now.AddSeconds(1);
var updFilter = currFilter;
updFilter.LiveUpdate = (currPage == 1);
updFilter.lastUpdate = updFilter.LiveUpdate ? "-" : $"{adesso:yyyy/MM/dd HH:mm:ss}";
// salvo filtro
currFilter = updFilter;
StateHasChanged();
}
@@ -64,13 +69,31 @@ namespace MP.SPEC.Pages
totalCount = newTotCount;
}
protected async Task detailSel(FluxLog newRec)
{
await Task.Delay(1);
var updFilter = currFilter;
DateTime adesso = DateTime.Now.AddSeconds(1);
updFilter.LiveUpdate = (newRec == null);
// sistemo la data di riferimento x eventuale snapshot nel passato
updFilter.dtRif = newRec != null ? newRec.dtEvento : null;
if (newRec != null)
{
updFilter.lastUpdate = updFilter.lastUpdate == "-" ? $"{adesso:yyyy/MM/dd HH:mm:ss}" : updFilter.lastUpdate;
updFilter.IdxMacchina = newRec.IdxMacchina;
//updFilter.CodFlux = newRec.CodFlux;
}
else
{
updFilter.lastUpdate = "-";
}
// salvo filtro
currFilter = updFilter;
}
#endregion Protected Methods
#region Private Fields
#endregion Private Fields
#region Private Properties
private SelectFluxParams currFilter { get; set; } = new SelectFluxParams();
@@ -81,8 +104,8 @@ namespace MP.SPEC.Pages
set => MsgService.currPage = value;
}
private bool isLoading { get; set; } = true;
private bool isFiltering { get; set; } = false;
private bool isLoading { get; set; } = true;
private int numRecord
{
+32 -5
View File
@@ -1,7 +1,7 @@
@page "/PODL"
<div class="card">
<div class="card mb-5">
<div class="card-header table-primary">
<div class="d-flex justify-content-between">
<div class="col-6">
@@ -42,13 +42,13 @@
</select>
</div>
</div>
</div>
@if (currRecord != null)
{
<div class="row">
<div class="col-12">
<div class="card">
<div class="card mb-5">
<div class="card-header bg-primary text-light">Modifica PODL</div>
<div class="card-body">
<div class="row">
@@ -77,6 +77,12 @@
</div>
</div>
<div class="col-3">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm"># pz</span>
<input type="text" class="form-control" aria-label="Num Pezzi" aria-describedby="inputGroup-sizing-sm" @bind-value="@currRecord.NumPezzi">
<span class="input-group-text" id="inputGroup-sizing-sm">T.Ciclo</span>
<input type="text" class="form-control" aria-label="Tempo Ciclo" aria-describedby="inputGroup-sizing-sm" @bind-value="@currRecord.Tcassegnato">
</div>
</div>
<div class="col-3">
<div class="input-group input-group-sm">
@@ -94,7 +100,6 @@
</div>
</div>
<div class="row mt-2">
<div class="col-3">
<div class="input-group input-group-sm">
<div class="input-group input-group-sm">
@@ -129,6 +134,28 @@
</div>
</div>
</div>
<div class="col-6">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Note</span>
<input type="text" class="form-control" aria-label="Note" aria-describedby="inputGroup-sizing-sm" @bind-value="@currRecord.Note">
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-3">
<div class="input-group input-group-sm d-flex justify-content-between">
<div class="input-group-text" id="inputGroup-sizing-sm">
<div class="pe-3" title="Attivabile">
Attivabile
</div>
<div class="form-check form-check-sm form-switch py-1" title="Attivabile">
<input class="form-check-input" type="checkbox" id="mySwitch" name="setupAlarms" title="Attivabile" @bind="@currRecord.Attivabile">
</div>
</div>
</div>
</div>
<div class="col-3">
</div>
<div class="col-3">
<div class="d-grid gap-2">
<button class="btn btn-warning" @onclick="() => cancel()">Annulla <i class="bi bi-x-circle"></i></button>
@@ -195,7 +222,7 @@
}
else
{
<ListPODL PagerResetReq="pgResetReq" RecordSel="@selRecord"></ListPODL>
<ListPODL PagerResetReq="pgResetReq" RecordSel="@selRecord" updateRecordCount="UpdateTotCount"></ListPODL>
}
</div>
<div class="card-footer py-1">
+30
View File
@@ -3,6 +3,7 @@ using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Components;
using MP.SPEC.Data;
using MP.SPEC.Services;
namespace MP.SPEC.Pages
{
@@ -24,6 +25,9 @@ namespace MP.SPEC.Pages
[Inject]
protected MpDataService MDService { get; set; }
[Inject]
protected IOApiService MpIoApiCall { get; set; }
[Inject]
protected MessageService MsgService { get; set; }
@@ -150,20 +154,31 @@ namespace MP.SPEC.Pages
return;
await Task.Delay(1);
var done = await MDService.POdlUpdateRecord(selRec);
await callSyncDb(selRec);
currRecord = null;
await reloadData();
await Task.Delay(1);
}
protected void UpdateTotCount(int newTotCount)
{
totalCount = newTotCount;
}
#endregion Protected Methods
#region Private Fields
private PODLModel? _currRecord = null;
private List<AnagArticoli>? ListArticoli;
private List<AnagGruppi>? ListAziende;
private List<AnagGruppi>? ListGruppiFase;
private List<Macchine>? ListMacchine;
private List<ListValues>? ListStati;
#endregion Private Fields
@@ -171,6 +186,7 @@ namespace MP.SPEC.Pages
#region Private Properties
private string _artSearch { get; set; } = "";
private string _currAzienda { get; set; } = "*";
private bool addEnabled
@@ -201,6 +217,7 @@ namespace MP.SPEC.Pages
}
private List<ConfigModel>? configData { get; set; } = null;
private string currArticolo { get; set; } = "";
private string currAzienda
@@ -260,6 +277,19 @@ namespace MP.SPEC.Pages
#region Private Methods
/// <summary>
/// Chiama metodo x chiedere sync DB
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
private async Task callSyncDb(PODLModel selRec)
{
// chiamo aggiunta task SyncDb...
string idxMacc = selRec.IdxMacchina;
string restUrl = $"IOB/addTask2Exe/{idxMacc}?taskName=syncDbData&taskVal=";
var response = await MpIoApiCall.callMpIoUrlGet(restUrl);
}
private async Task reloadData()
{
isLoading = true;
+32
View File
@@ -0,0 +1,32 @@
@page "/Test"
<h3>Test</h3>
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample" aria-controls="offcanvasExample">
Button with data-bs-target
</button>
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Offcanvas</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div>
Some text as placeholder. In real life you can have the elements you have chosen. Like, text, images, lists, etc.
</div>
<div class="dropdown mt-3">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown">
Dropdown button
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
</div>
</div>
@code {
}
+1 -1
View File
@@ -5,6 +5,6 @@
<h3>Utils</h3>
<div class="px-2">
<div class="">
<button class="btn btn-primary" @onclick="() => flushCache()"> Flush Cache </button>
</div>
+16 -4
View File
@@ -1,18 +1,30 @@
using Microsoft.AspNetCore.Components;
using MP.SPEC.Data;
using System.Reflection;
namespace MP.SPEC.Pages
{
public partial class Utils
{
[Inject]
protected MpDataService MDService { get; set; }
#region Public Methods
public async Task flushCache()
{
await Task.Delay(1);
await MDService.FlushRedisCache();
// rimando a home
NavManager.NavigateTo("", true);
}
[Inject]
private NavigationManager NavManager { get; set; } = null!;
#endregion Public Methods
#region Protected Properties
[Inject]
protected MpDataService MDService { get; set; } = null!;
#endregion Protected Properties
}
}
}
+16 -11
View File
@@ -30,7 +30,12 @@
<a class="dismiss">🗙</a>
</div>
<script src="lib/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="_framework/blazor.server.js" autostart="false"></script>
<script src="lib/chartjs-adapter-luxon/chartjs-adapter-luxon.js"></script>
<script src="lib/chartBoot.js"></script>
<script src="lib/Chart.js/chart.js"></script>
@*Gestione autoriconnessione: https://github.com/dotnet/aspnetcore/issues/38305 (vedere anche https://docs.microsoft.com/it-it/aspnet/core/blazor/fundamentals/signalr?view=aspnetcore-6.0#modify-the-reconnection-handler-blazor-server)*@
<script>
Blazor.start({
@@ -39,19 +44,19 @@
retryIntervalMilliseconds: 2000
}
}).then(() => {
Object.defineProperty(Blazor.defaultReconnectionHandler, '_reconnectionDisplay', {
get() {
return this.__reconnectionDisplay;
},
set(value) {
this.__reconnectionDisplay = {
show: () => value.show(),
update: (d) => value.update(d),
rejected: (d) => document.location.reload()
}
Object.defineProperty(Blazor.defaultReconnectionHandler, '_reconnectionDisplay', {
get() {
return this.__reconnectionDisplay;
},
set(value) {
this.__reconnectionDisplay = {
show: () => value.show(),
update: (d) => value.update(d),
rejected: (d) => document.location.reload()
}
});
}
});
});
</script>
</body>
</html>
+4
View File
@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using MP.SPEC.Components;
using MP.SPEC.Data;
using MP.SPEC.Services;
using StackExchange.Redis;
var builder = WebApplication.CreateBuilder(args);
@@ -38,6 +39,9 @@ builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
builder.Services.AddSingleton<MpDataService>();
builder.Services.AddScoped<MessageService>();
builder.Services.AddHttpClient();
builder.Services.AddSingleton<IOApiService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
+25 -25
View File
@@ -1,28 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:46815",
"sslPort": 44370
}
},
"profiles": {
"MP.SPEC": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7212;http://localhost:5212",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:46815",
"sslPort": 44370
}
},
"profiles": {
"MP.SPEC": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7212;http://localhost:5212",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 6.16.2209.2110</h4>
<h4>Versione: 6.16.2210.1417</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2209.2110
6.16.2210.1417
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2209.2110</version>
<version>6.16.2210.1417</version>
<url>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+56
View File
@@ -0,0 +1,56 @@
using Microsoft.Extensions.Configuration;
using MP.SPEC.Data;
using System.Text.Json;
namespace MP.SPEC.Services
{
/// <summary>
/// Classe per chiamare metodi da MP-IO
///
/// rif:
/// https://www.ezzylearning.net/tutorial/making-http-requests-in-blazor-server-apps
/// https://wellsb.com/csharp/aspnet/blazor-httpclientfactory-and-web-api/
/// </summary>
public class IOApiService
{
private readonly IHttpClientFactory _clientFactory;
private static ILogger<MpDataService> _logger = null!;
private static IConfiguration _configuration = null!;
private static string MpIoBaseUrl = "";
public IOApiService(IHttpClientFactory clientFactory, IConfiguration configuration, ILogger<MpDataService> logger)
{
_logger = logger;
_logger.LogInformation("Starting IOApiService INIT");
_configuration = configuration;
_clientFactory = clientFactory;
// conf url x chiamate REST
MpIoBaseUrl = _configuration.GetValue<string>("ServerConf:MpIoBaseUrl");
}
/// <summary>
/// Effettua chiamata ad MP-IO
/// </summary>
/// <param name="relUrl">URL metodo relativo alla base path di MP-IO</param>
/// <returns></returns>
public async Task<string> callMpIoUrlGet(string relUrl)
{
string result = "";
var request = new HttpRequestMessage(HttpMethod.Get, $"{MpIoBaseUrl}{relUrl}");
request.Headers.Add("Accept", "application/vnd.github.v3+json");
var client = _clientFactory.CreateClient();
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var stringResponse = await response.Content.ReadAsStringAsync();
result = stringResponse;
}
else
{
result = "NO";
}
return result;
}
}
}
+18 -10
View File
@@ -24,16 +24,16 @@ main {
display: flex;*/
}
.top-row ::deep a,
.top-row .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
}
.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;
}
.top-row a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
.bottom-row {
color: #dedede;
@@ -46,9 +46,11 @@ main {
.top-row:not(.auth) {
display: none;
}
.top-row.auth {
justify-content: space-between;
}
.top-row a,
.top-row .btn-link {
margin-left: 0;
@@ -59,34 +61,40 @@ main {
.page {
flex-direction: row;
}
.sidebar {
width: 15rem;
height: 100vh;
position: sticky;
top: 0;
}
.sidebarSmall {
width: 5rem;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row,
article {
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
}
.bottom-row {
position: fixed;
bottom: 0;
z-index: 1;
}
.main>div {
.main > div {
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
/*padding-left: 2rem !important;
+14 -4
View File
@@ -20,9 +20,14 @@
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-2">
<div class="nav-item px-2 col-12">
<NavLink class="nav-link px-2" href="" Match="NavLinkMatch.All">
<span class="fa-solid fa-house px-2" aria-hidden="true"></span> <span class="@hideText">Home</span>
<div class ="col-2">
<span class="fa-solid fa-house px-2" aria-hidden="true"></span>
</div>
<div>
<span class="@hideText">Home</span>
</div>
</NavLink>
</div>
@if (ElencoLink == null)
@@ -33,9 +38,14 @@
{
foreach (var item in ElencoLink)
{
<div class="nav-item px-2">
<div class="nav-item px-2 col-12">
<NavLink class="nav-link px-2" href="@item.NavigateUrl">
<span class="@item.icona px-2" aria-hidden="true"></span> <span class="@hideText">@item.Testo</span>
<div class="col-2">
<span class="@item.icona px-2" aria-hidden="true"></span>
</div>
<div>
<span class="@hideText">@item.Testo</span>
</div>
</NavLink>
</div>
}
+1 -1
View File
@@ -59,4 +59,4 @@
/* Never collapse the sidebar for wide screens */
display: block;
}
}
}
+6
View File
@@ -12,5 +12,11 @@
"ConnectionStrings": {
"Mp.Data": "Server=localhost\\SQLEXPRESS;Database=MoonPro; User ID=steamware;Password=viadante16; integrated security=False; MultipleActiveResultSets=True; App=Blazor.ServerApp;",
"Redis": "localhost:6379,DefaultDatabase=13,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false"
},
"ServerConf": {
"maxAge": "2000",
"cacheCheckArtUsato": 2,
"redisLongTimeCache": 15,
"MpIoBaseUrl": "http://localhost/MP/IO/"
}
}
+2 -1
View File
@@ -15,6 +15,7 @@
"ServerConf": {
"maxAge": "2000",
"cacheCheckArtUsato": 2,
"redisLongTimeCache": 15
"redisLongTimeCache": 15,
"MpIoBaseUrl": "http://localhost:20967/"
}
}
+16
View File
@@ -81,6 +81,22 @@ a,
.footer {
line-height: 1.8em;
}
.dcContainer {
width: 22rem;
height: 22rem;
position: relative;
}
.dcBox {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.dcOverlay {
z-index: 9;
margin: 8.5rem;
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
+18
View File
@@ -87,6 +87,24 @@ a, .btn-link {
line-height: 1.8em;
}
.dcContainer {
width: 22rem;
height: 22rem;
position: relative;
}
.dcBox {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.dcOverlay {
z-index: 9;
margin: 8.5rem;
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff

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