Compare commits

..

226 Commits

Author SHA1 Message Date
Samuele Locatelli 1cae70c244 Merge branch 'Release/UpdateModuloDoss' 2022-10-20 14:54:22 +02:00
Samuele Locatelli 18ee183b05 Pulizia codice DOSS x spostamento modulo update 2022-10-20 14:54:03 +02:00
Samuele Locatelli d88c4cc2bd Update comportamento edit dossier 2022-10-20 13:16:07 +02:00
zaccaria.majid 67922520b8 fix edit mode label 'PENDING CHANGES' 2022-10-20 11:42:10 +02:00
zaccaria.majid c5b5b54586 fix edit mode 2022-10-20 11:21:01 +02:00
zaccaria.majid ae3864a614 fix salva solo quando finito 2022-10-20 11:08:31 +02:00
zaccaria.majid f878f1c496 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-20 09:42:27 +02:00
zaccaria.majid d453c1d944 modifiche comportamento editing 2022-10-20 09:42:19 +02:00
Samuele Locatelli 921bf52659 Filtro eventi macchina spenta
- preso da semaforo (no idxStato)
2022-10-20 09:31:42 +02:00
Samuele Locatelli e948ae31af Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-19 20:07:36 +02:00
Samuele Locatelli b344180da2 Fix gestione HideSpenta da statistiche 2022-10-19 20:07:33 +02:00
zaccaria.majid 4b885d780c Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-19 17:47:48 +02:00
zaccaria.majid 01e181a4fc inizio modifiche editing 2022-10-19 17:47:07 +02:00
Samuele Locatelli 56f342a488 refresh test 2022-10-19 17:30:26 +02:00
Samuele Locatelli ed72bdfa24 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-19 17:14:20 +02:00
Samuele Locatelli 5e6924f0fe Inizio gestione nascondi spenta 2022-10-19 17:13:43 +02:00
zaccaria.majid cae7e50cbd cleanUp 2022-10-19 17:11:27 +02:00
zaccaria.majid e769227bb3 fix not update if "annulla" 2022-10-19 17:10:56 +02:00
zaccaria.majid 60f757965e CleanUp 2022-10-19 13:07:05 +02:00
zaccaria.majid 603ed3782f Cleanup 2022-10-19 13:02:59 +02:00
zaccaria.majid 71177e04c7 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-19 13:01:28 +02:00
zaccaria.majid 1a211ebca5 delete msgService da PARAMS 2022-10-19 13:01:21 +02:00
zaccaria.majid 591b66b52d delete msgService da dossier 2022-10-19 12:49:13 +02:00
Samuele Locatelli 96f4bb3b4c Merge tag 'UpdateLogCall' into develop
Fix log chaimate MP/IO
2022-10-19 11:02:23 +02:00
Samuele Locatelli f1c295993c Merge branch 'Release/UpdateLogCall' 2022-10-19 11:02:16 +02:00
Samuele Locatelli a293ce825e Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-19 11:01:34 +02:00
Samuele Locatelli e3b67ee6c0 Fix log vari x chiamate MP/IO 2022-10-19 11:01:29 +02:00
zaccaria.majid 0c5e41826e fix recordsel = null in dossier post chiusura 2022-10-19 10:43:45 +02:00
Samuele Locatelli 0d4e1aed88 Merge tag 'FixPAramsDetailAndReload' into develop
Sistemazione reload e params detail
2022-10-18 20:02:34 +02:00
Samuele Locatelli 93f4f09b85 Merge branch 'Release/FixPAramsDetailAndReload' 2022-10-18 20:02:26 +02:00
Samuele Locatelli aebae6b406 Update selezione dossier:
- selezione x periodo
- ancora check ottimizzazione sel distinct
2022-10-18 20:01:53 +02:00
Samuele Locatelli a2bf5f4a8b Ottimizzazioni selezione casi distinct 2022-10-18 19:16:20 +02:00
Samuele Locatelli 759373b5a4 Modifica display valori fluxLog x Dossier 2022-10-18 18:37:26 +02:00
Samuele Locatelli 0ea3ee6341 Merge tag 'FixMemoryLeakError' into develop
Update x gestione condizione errore memory leak (ridotto in test debug)
x gestione dispose componenti
2022-10-18 17:12:23 +02:00
Samuele Locatelli a0ffe1bc6c Merge branch 'Release/FixMemoryLeakError' 2022-10-18 17:12:04 +02:00
Samuele Locatelli 6e75f590bb pulizia codice 2022-10-18 17:11:42 +02:00
Samuele Locatelli 12473b5088 Ancora cleanup di GC x recupero RAM inutilizzata 2022-10-18 17:10:29 +02:00
Samuele Locatelli f6406f833f Ancora memory leak
- diminuito problema di refresh automatico
- inizio gestione dispose oggetti
2022-10-18 16:53:00 +02:00
Samuele Locatelli a21cd16362 FIX PODL
- verifica PODL attrezzabili (=senza OIDL correnti)
2022-10-18 16:32:40 +02:00
Samuele Locatelli d659afacc2 Fix PODL
- paginazione
- cambio num rec
- sel fase
2022-10-18 16:15:59 +02:00
zaccaria.majid 56c3ba4064 Fix loop ram 2022-10-18 15:56:14 +02:00
Samuele Locatelli 8d0292d789 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-18 12:01:06 +02:00
Samuele Locatelli 419863a684 Loop Update:
inizio verifica ODL/PODL
2022-10-18 12:01:04 +02:00
Samuele Locatelli f56a7e5164 Aggiunto btn x forzare syncDb 2022-10-18 11:28:59 +02:00
zaccaria.majid 0cf6ecd38f fix colori 2022-10-18 11:23:27 +02:00
zaccaria.majid 094ce0d181 fix style plot 2022-10-18 11:10:39 +02:00
Samuele Locatelli b4de1c9880 Merge tag 'UpdateGestSelect' into develop
Update grafico
2022-10-18 10:11:26 +02:00
Samuele Locatelli 67f0f74fbe Merge branch 'Release/UpdateGestSelect' 2022-10-18 10:11:16 +02:00
Samuele Locatelli d00b4bbb8b Refresh 2022-10-18 10:09:01 +02:00
Samuele Locatelli dd63bb292d Merge remote-tracking branch 'origin/develop' into develop 2022-10-18 09:56:05 +02:00
zaccaria.majid 57bc790074 Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-18 09:55:37 +02:00
zaccaria.majid 41a00ffa45 fix 2 variabili x statRecord e currRecord 2022-10-18 09:55:29 +02:00
Samuele Locatelli 633b5dda6e Fix cache recupero ODL correnti (3 sec redis) 2022-10-18 09:51:43 +02:00
Samuele Locatelli 5d6bef0fc8 Merge tag 'UpdateGestOdlPodl' into develop
Update gestione ODL/PODL
2022-10-18 09:26:34 +02:00
Samuele Locatelli d24b2ada0c Merge branch 'Release/UpdateGestOdlPodl' 2022-10-18 09:26:27 +02:00
Samuele Locatelli 0a9ccffe28 Fix ODL/PODL x setup ed avvio 2022-10-18 09:26:04 +02:00
Samuele Locatelli 207d305327 Merge tag 'UpdateGestSetupOdl' into develop
Fix x test gesiotne ODL (manca vera gestione SE ODL aperto)
2022-10-18 08:43:44 +02:00
Samuele Locatelli caa4b4f590 Merge branch 'Release/UpdateGestSetupOdl' 2022-10-18 08:43:22 +02:00
Samuele Locatelli e45cb0595e Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-10-18 08:42:56 +02:00
Samuele Locatelli 77e7e39985 Aggiornamento modifiche x chiudere ODL e creare nuovo 2022-10-18 08:41:12 +02:00
Samuele Locatelli b2e9ae76d4 bozza modifiche (da completare) 2022-10-17 20:10:52 +02:00
zaccaria.majid 460eb769dc inizio gestione currRecord dopo chiusura modal 2022-10-17 17:27:39 +02:00
Samuele Locatelli 5e38749c65 Bozza gestione PODL --> ODL 2022-10-17 12:17:11 +02:00
Samuele Locatelli 91083b6c4a Merge remote-tracking branch 'origin/develop' into develop 2022-10-17 12:01:43 +02:00
Samuele Locatelli de562b1287 Update x gestione chiusura ODL 2022-10-17 12:01:33 +02:00
zaccaria.majid 470c9a2191 aggiunta controllo listaStati null 2022-10-17 11:25:05 +02:00
zaccaria.majid 26e36e7124 fix posizionamento label durata 2022-10-17 10:09:16 +02:00
zaccaria.majid bef0ee6000 fix text dark progress bar gialla 2022-10-17 09:22:38 +02:00
zaccaria.majid 9e4822d529 Aggiunta filtro per macchine ODL 2022-10-17 09:09:43 +02:00
Samuele Locatelli 7f9685a007 Merge tag 'UpdateOdlStatsModal' into develop
fix gestione statistiche ODL
2022-10-14 17:43:06 +02:00
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
Samuele Locatelli e945aad224 Merge branch 'Release/FirstSpecStableRelease' 2022-09-21 10:36:40 +02:00
Samuele Locatelli 8510731366 Update home page 2022-09-21 10:36:29 +02:00
Samuele Locatelli 5df4195e6c Completato salvataggio snapshot + refresh 2022-09-21 10:26:09 +02:00
Samuele Locatelli a3dc1e1657 Start ver 6.16 2022-09-21 09:52:54 +02:00
Samuele Locatelli 27149e2131 Fix grafici minori 2022-09-21 09:46:44 +02:00
Samuele Locatelli 91be755781 Fix conf key redis cache:
- era overlapping parametri/dossiers
2022-09-21 09:27:00 +02:00
Samuele Locatelli 84f6730023 Merge remote-tracking branch 'origin/develop' into develop 2022-09-21 09:22:12 +02:00
zaccaria.majid b51c2679e4 aggiunta cache redis 2022-09-21 09:17:28 +02:00
zaccaria.majid 9d7502d1a4 modifiche grafiche e round orario datetime 2022-09-21 09:13:39 +02:00
zaccaria.majid d3b8160634 fix deserializzazione oggetto fluxlog 2022-09-20 17:35:45 +02:00
zaccaria.majid 601c817aa2 Modifiche grafiche 2022-09-20 17:16:42 +02:00
zaccaria.majid d0d30bd1c3 Modifiche per permettere la deserializzazione dei
valori in dossier
2022-09-20 17:16:21 +02:00
zaccaria.majid 0e9e7f3dda Creazione pagina per la visualizzazione Dossier
con relativi filtri
2022-09-20 12:54:46 +02:00
Samuele Locatelli e518c17db2 Aggiunta traccia x pagina dossiers 2022-09-20 09:03:22 +02:00
Samuele Locatelli 0a281827f9 Refresh 2022-09-19 20:01:24 +02:00
Samuele Locatelli 141473ce28 Aggiunta metodi gestione lettura dossiers da DB + refresh 2022-09-19 20:01:13 +02:00
Samuele Locatelli 45af089e3f Aggiunta preliminare modello Dossiers 2022-09-19 20:00:56 +02:00
Samuele Locatelli 4e4387620b Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-09-19 09:58:28 +02:00
Samuele Locatelli 8c2c48a63f Fix procedura di flux dati:
- aggiunta conn tipo admin
- tolta cancellazione intero DB
- ricerca x pattern delle sole chaivi interessate
2022-09-19 09:54:30 +02:00
zaccaria.majid 534a668496 tentativo fix redis Flush 2022-09-19 09:22:29 +02:00
zaccaria.majid eed45695e8 continuo flushCache 2022-09-19 08:43:48 +02:00
zaccaria.majid ff2fbe0c34 modifiche grafiche
inizio pagina utils
2022-09-16 17:37:39 +02:00
Samuele Locatelli 3324c736c6 Minor fix 2022-09-16 16:49:19 +02:00
zaccaria.majid 0a6a0bc5cb modifiche grafiche varie 2022-09-16 16:00:13 +02:00
Samuele Locatelli e18e0ddff3 Fix last update da pagina main 2022-09-16 15:18:56 +02:00
zaccaria.majid 580a498238 tentativo fix lastUpdate 2022-09-16 14:47:31 +02:00
zaccaria.majid c97557722e Modifiche grafiche 2022-09-16 14:22:23 +02:00
zaccaria.majid c17fa17d76 fix filtri aggiunta titles 2022-09-16 12:40:18 +02:00
zaccaria.majid 5b054ee2ec fix last snapshot che non veniva
scritto al primo giro
2022-09-16 11:55:23 +02:00
zaccaria.majid 2771d9957d Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-09-16 11:47:43 +02:00
zaccaria.majid 5893152761 aggiornamento grafico filtri 2022-09-16 11:47:35 +02:00
Samuele Locatelli b7d57e935a COmpletato fix version number 2022-09-16 11:21:03 +02:00
Samuele Locatelli 61b613a8fb Fix proj config x calcolo versione 2022-09-16 11:19:26 +02:00
Samuele Locatelli d2fef81f55 Merge remote-tracking branch 'origin/develop' into develop 2022-09-16 11:17:33 +02:00
Samuele Locatelli cd7a8ccad8 Fix x display numero versione 2022-09-16 11:17:28 +02:00
zaccaria.majid 08079d3e0e Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop 2022-09-16 10:51:19 +02:00
zaccaria.majid 8156828ec3 fix bottone filtri avanzati 2022-09-16 10:44:45 +02:00
Samuele Locatelli 9bb95c5a49 Merge tag 'FixMasterDeploy' into develop
Fix deploy IIS x icone, errore cancellazione, log
2022-09-16 10:37:26 +02:00
Samuele Locatelli 7ba3aeb65d Merge branch 'Release/FixMasterDeploy' 2022-09-16 10:37:10 +02:00
Samuele Locatelli 6ea938a91a Aggiunta web.config x windows auth 2022-09-16 10:36:25 +02:00
Samuele Locatelli 92c196023d fix posizione img home page 2022-09-16 10:33:13 +02:00
Samuele Locatelli 10d9625b6d fix articoli:
- tolto refuso cancellazione csv temp appoggio
2022-09-16 10:33:03 +02:00
Samuele Locatelli 5f955499e2 Fix file favicon e logfolder 2022-09-16 10:32:47 +02:00
Samuele Locatelli 716813abe1 Merge tag 'AddSpecInstaller' into develop
Aggiornamento x generazione installer SPEC su nexus
2022-09-16 09:13:19 +02:00
138 changed files with 29488 additions and 1076 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
}
}
}
+485 -49
View File
@@ -1,6 +1,7 @@
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using MP.Data.DatabaseModels;
using NLog;
using System;
using System.Collections.Generic;
@@ -27,7 +28,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 +37,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 +46,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 +65,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 +84,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,17 +93,36 @@ 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");
}
/// <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
.DbSetDossiers
.AsNoTracking()
.Select(i => i.OdlNav.CodArticolo)
.Distinct()
.ToList();
}
return dbResult;
}
/// <summary>
/// Eliminazione Record
/// </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 +153,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 +176,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 +196,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();
@@ -195,7 +215,7 @@ namespace MP.Data.Controllers
/// </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 +255,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 +273,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,31 +297,199 @@ 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="DtStart">Data minima per estrazione records</param>
/// <param name="DtEnd">Data Massima per estrazione records</param>
/// <returns></returns>
public List<Dossiers> DossiersGetLastFilt(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd)
{
List<Dossiers> dbResult = new List<Dossiers>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetDossiers
.AsNoTracking()
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodArticolo == "*" || x.OdlNav.CodArticolo == CodArticolo) && (x.DtRif >= DtStart && x.DtRif <= DtEnd))
.Include(m => m.MachineNav)
.Include(o => o.OdlNav)
.Include(a => a.OdlNav.ArticoloNav)
.OrderByDescending(x => x.DtRif)
.ToList();
}
return dbResult;
}
/// <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,@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");
}
/// <summary>
/// Aggiunta record EventList
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
public async Task<bool> EvListInsert(EventListModel newRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var currRec = dbCtx
.DbSetEvList
.Add(newRec);
await dbCtx.SaveChangesAsync();
}
catch (Exception exc)
{
Log.Error($"Eccezione durante EvListInsert{Environment.NewLine}{exc}");
}
}
await Task.Delay(1);
return fatto;
}
/// <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();
@@ -309,9 +497,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
@@ -330,17 +518,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, string IdxMacchina, 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 == "*") && (x.IdxMacchina.Contains(IdxMacchina) || IdxMacchina == "*") && (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;
@@ -352,15 +544,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();
}
@@ -373,9 +567,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
@@ -392,9 +586,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
@@ -407,20 +601,23 @@ namespace MP.Data.Controllers
}
/// <summary>
/// Elenco id Macchine che abbiano dati FLuxLog
/// Elenco id Macchine che abbiano dati FLuxLog, nel periodo indicato
/// </summary>
/// <param name="dtStart"></param>
/// <param name="dtEnd"></param>
/// <returns></returns>
public List<string> MacchineWithFlux()
public async Task<List<string>> MacchineWithFlux(DateTime dtStart, DateTime dtEnd)
{
List<string> dbResult = new List<string>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetFluxLog
.AsNoTracking()
.Select(i => i.IdxMacchina)
.Distinct()
.ToList();
dbResult = await dbCtx
.DbSetFluxLog
.AsNoTracking()
.Where(x => x.dtEvento >= dtStart && x.dtEvento <= dtEnd)
.Select(i => i.IdxMacchina)
.Distinct()
.ToListAsync();
}
return dbResult;
}
@@ -429,9 +626,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);
@@ -445,6 +642,147 @@ namespace MP.Data.Controllers
return dbResult;
}
/// <summary>
/// Chiusura ODL con eventuale conferma pezzi
/// </summary>
/// <param name="idxOdl">idx odl da chiudere</param>
/// <param name="idxMacchina">idx macchina</param>
/// <param name="matrOpr">matricola operatore</param>
/// <param name="confPezzi">indica se confermare i pezzi prima di chiudere ODL</param>
/// <param name="confRett">Conferma con rettifica (ev 121) x pezzi lasciati in macchina</param>
/// <param name="modoConfProd">Modo conferma produzione (0=periodo, 1=giorno, 2=turno)</param>
/// <returns></returns>
public async Task<bool> ODLClose(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi, bool confRett, int modoConfProd)
{
bool fatto = false;
if (idxOdl > 0)
{
using (var dbCtx = new MoonProContext(_configuration))
{
DateTime adesso = DateTime.Now;
// preparo i parametri
var IdxODL = new SqlParameter("@IdxODL", idxOdl);
var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
// FARE FIXME TODO !!! da valutare casi setup/autoconferma...
#if false
// controllo se HO pezzi da confermare...
var statoProd = StatoProdMacchina(idxMacchina);
if (statoProd.pezziNonConfermati < 1)
{ }
#endif
// se richiesto confermo produzione
if (confPezzi)
{
var MatrApp = new SqlParameter("@MatrApp", idxMacchina);
/* ----------------------------------
* CONFERMA PEZZI
*
* condizioni da verificare:
* - gestione rettifica (ev121) / pezzi da LASCIARE in macchina
* - conferma a zero pezzi (setup) oppure con i pezzi fatti e non ancora confermati
*
*
*
* */
// recupero i dati dei pezzi da confermare... con DbSetPzProd + exec
// stp_PzProd_getByMacchina 'SIMUL_01'
// stp_ConfermaProduzCompletaFull
/*
* @idxMacchina NVARCHAR(50),
@MatrApp INT,
@dataFrom DATETIME,
@dataTo DATETIME,
@pezziConf INT,
@pezziLasciati INT, -- pezzi lasciati = evento 121 (-) pre conferma e (+) dopo --> da lasciare in macchina post conferma
@pezziScar INT = 0, -- pezzi scartati (registrati da 2016.11.20) DA INDICARE COME VALORE > 0!!! sennò faccio ABS...
@TipoConf INT = 0, -- Tipo intervallo conferma: 0 = periodo intero, 1 = per giorni, 2 = per turni
@DataOraApp DATETIME = NULL, -- di norma GETDATE() nel programma - serve per ricalcolo
@TestConferma BIT = 1 -- TestConferma : 1 = verifica conf. duplicata e inserisci in ElencoConfermeProd, 0 = nessuna verifica e inserimento ( per ricalcolo )
*/
}
// ora chiudo ODL
try
{
var dbResult = await dbCtx
.DbSetStatOdl
.FromSqlRaw("EXEC stp_ODL_fineProd @IdxODL, @IdxMacchina", IdxODL, IdxMacchina)
.AsNoTracking()
.ToListAsync();
}
catch (Exception exc)
{
Log.Error($"Eccezione durante ODLClose{Environment.NewLine}{exc}");
}
}
}
return fatto;
}
/// <summary>
/// Recupero odl data chiave
/// </summary>
/// <param name="idxOdl"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public ODLModel OdlGetByKey(int idxOdl)
{
ODLModel dbResult = new ODLModel();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetODL
.FirstOrDefault(x => x.IdxOdl == idxOdl);
}
return dbResult;
}
/// <summary>
/// Recupero Odl CORRENTI
/// </summary>
/// <returns></returns>
public List<ODLModel> OdlGetCurrent()
{
List<ODLModel> dbResult = new List<ODLModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetODL
.Where(x => x.DataInizio != null && x.DataFine == null)
.ToList();
}
return dbResult;
}
/// <summary>
/// Statistiche ODL calcolate (da stored stp_STAT_ODL)
/// </summary>
/// <returns></returns>
public async Task<List<StatODLModel>> OdlStart(int IdxOdl)
{
List<StatODLModel> dbResult = new List<StatODLModel>();
if (IdxOdl > 0)
{
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>
/// Elenco parametri validi x una data macchina
/// </summary>
@@ -459,19 +797,95 @@ namespace MP.Data.Controllers
.DbSetFluxLog
.AsNoTracking()
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina))
.Take(1000)
.Select(i => i.CodFlux)
.Distinct()
.OrderBy(x => x)
.ToList();
}
return dbResult;
}
/// <summary>
/// Recupero PODL da chiave
/// </summary>
/// <param name="idxPODL"></param>
/// <returns></returns>
public async Task<PODLModel> PODL_getByKey(int idxPODL)
{
PODLModel dbResult = new PODLModel();
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
dbResult = dbCtx
.DbSetPODL
.AsNoTracking()
.Where(x => x.IdxPromessa == idxPODL)
.FirstOrDefault();
}
catch (Exception exc)
{
Log.Error($"Eccezione durante PODL_getByKey{Environment.NewLine}{exc}");
}
}
await Task.Delay(1);
return dbResult;
}
/// <summary>
/// Avvio setup ODL da PODL
/// </summary>
/// <param name="editRec"></param>
/// <param name="matrOpr"></param>
/// <param name="tcRich"></param>
/// <param name="pzPallet"></param>
/// <param name="note"></param>
/// <returns></returns>
public async Task<bool> PODL_startSetup(PODLModel editRec, int matrOpr, double tcRich, int pzPallet, string note)
{
bool answ = false;
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var currRec = dbCtx
.DbSetPODL
.AsNoTracking()
.Where(x => x.IdxPromessa == editRec.IdxPromessa)
.FirstOrDefault();
if (currRec != null)
{
// eseguo stored attrezzaggio
var IdxPromessa = new SqlParameter("@idxPromessa", editRec.IdxPromessa);
var MatrOpr = new SqlParameter("@MatrOpr", matrOpr);
var IdxMacchina = new SqlParameter("@IdxMacchina", editRec.IdxMacchina);
var TCRichAttr = new SqlParameter("@TCRichAttr", tcRich);
var PzPallet = new SqlParameter("@PzPallet", pzPallet);
var Note = new SqlParameter("@Note", note);
var callResult = await dbCtx
.Database
.ExecuteSqlRawAsync("EXEC stp_ODL_inizioSetupPromessa @idxPromessa, @MatrOpr, @IdxMacchina, @TCRichAttr, @PzPallet, @Note", IdxPromessa, MatrOpr, IdxMacchina, TCRichAttr, PzPallet, Note);
answ = true;
}
}
catch (Exception exc)
{
Log.Error($"Eccezione durante PODL_doSetup{Environment.NewLine}{exc}");
}
}
await Task.Delay(1);
return answ;
}
/// <summary>
/// Eliminazione Record
/// </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))
@@ -501,7 +915,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))
@@ -521,6 +935,8 @@ namespace MP.Data.Controllers
currRec.KeyRichiesta = editRec.KeyRichiesta;
currRec.NumPezzi = editRec.NumPezzi;
currRec.Tcassegnato = editRec.Tcassegnato;
currRec.Attivabile = editRec.Attivabile;
currRec.Note = editRec.Note;
dbCtx.Entry(currRec).State = EntityState.Modified;
}
else
@@ -565,6 +981,26 @@ namespace MP.Data.Controllers
return answ;
}
/// <summary>
/// Stato prod macchina
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
public StatoProdModel StatoProdMacchina(string idxMacchina)
{
StatoProdModel dbResult = new StatoProdModel();
using (var dbCtx = new MoonProContext(_configuration))
{
var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
dbResult = dbCtx
.DbSetStatoProd
.FromSqlRaw("EXEC stp_PzProd_getByMacchina @IdxMacchina", IdxMacchina)
.AsNoTracking()
.FirstOrDefault();
}
return dbResult;
}
#endregion Public Methods
#region Private Fields
+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
}
}
+22
View File
@@ -0,0 +1,22 @@
using MP.Data.DatabaseModels;
using System;
using System.Collections.Generic;
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
{
/// <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
{
+50
View File
@@ -0,0 +1,50 @@
using System;
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("Dossiers")]
public partial class Dossiers
{
#region Public Properties
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxDossier { get; set; }
[MaxLength(50)]
public string DataType { 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
}
}
+47
View File
@@ -0,0 +1,47 @@
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
{
[Table("EventList")]
public partial class EventListModel
{
#region Public Properties
[MaxLength(50)]
public string IdxMacchina { get; set; } = "NA";
public DateTime? InizioStato { get; set; } = DateTime.Now;
public int IdxTipo { get; set; } = 0;
[MaxLength(50)]
public string CodArticolo { get; set; } = "";
[MaxLength(250)]
public string Value { get; set; } = "";
public int MatrOpr { get; set; } = 0;
[MaxLength(20)]
public string pallet { get; set; } = "";
/// <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
@@ -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
}
}
+20
View File
@@ -0,0 +1,20 @@
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 StatoProdModel
{
[Key]
public string idxMacchina { get; set; } = "NA";
public int pezziNonConfermati { get; set; } = 0;
public DateTime DataFrom { get; set; } = DateTime.Now;
public DateTime DataTo { get; set; } = DateTime.Now;
}
}
+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
}
}
}
+14 -2
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
@@ -45,6 +47,10 @@ namespace MP.Data
public virtual DbSet<ODLModel> DbSetODL { get; set; }
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; }
public virtual DbSet<StatoProdModel> DbSetStatoProd { get; set; }
public virtual DbSet<EventListModel> DbSetEvList { get; set; }
#endregion Public Properties
@@ -291,7 +297,13 @@ namespace MP.Data
});
modelBuilder.Entity<FluxLog>(entity =>
{
entity.HasKey(e => new { e.IdxMacchina, e.dtEvento, e.CodFlux});
entity.HasKey(e => new { e.IdxMacchina, e.dtEvento, e.CodFlux });
});
modelBuilder.Entity<EventListModel>(entity =>
{
entity.HasKey(e => new { e.IdxMacchina, e.InizioStato, e.IdxTipo});
});
+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 -1
View File
@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>MP.Prog</RootNamespace>
<Version>6.15.2202.2715</Version>
<Version>6.15.2209.1609</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo gestione Programmi MAPO</i>
<h4>Versione: 6.15.2202.2715</h4>
<h4>Versione: 6.15.2209.1609</h4>
<br />
Note di rilascio:
<ul>
+1 -1
View File
@@ -1 +1 @@
6.15.2202.2715
6.15.2209.1609
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.15.2202.2715</version>
<version>6.15.2209.1609</version>
<url>https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+1
View File
@@ -0,0 +1 @@
<canvas id="@Id"></canvas>
@@ -0,0 +1,60 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data;
using MP.SPEC.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 List<DoughnutStyling> 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.Select(x=>x.color), borderColor = BackgroundColor.Select(x=>x.border), borderWidth= 0, offset= 1, borderRadius = 0
}
},
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
}
}
+6 -2
View File
@@ -8,7 +8,7 @@ namespace MP.SPEC.Components
public void Dispose()
{
//aTimer.Elapsed -= ElapsedTimer;
aTimer.Elapsed -= ElapsedTimer;
aTimer.Stop();
aTimer.Dispose();
}
@@ -21,7 +21,6 @@ namespace MP.SPEC.Components
await InvokeAsync(() => StateHasChanged());
});
pUpd.Wait();
//Log.Trace($"Elapsed Timer Footer");
}
public void StartTimer()
@@ -38,6 +37,11 @@ namespace MP.SPEC.Components
#region Protected Methods
protected override void OnInitialized()
{
version = typeof(Program).Assembly.GetName().Version;
}
#endregion Protected Methods
#region Private Fields
+1 -2
View File
@@ -43,7 +43,6 @@
}
private async void MService_EA_ShowSearch()
{
//await forceReload();
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
}
@@ -54,7 +53,7 @@
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
if (user.Identity != null&& user.Identity.IsAuthenticated)
{
userName = $"{user.Identity.Name}";
}
+11 -7
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;
@@ -94,7 +98,7 @@ namespace MP.SPEC.Components
protected int _numRecord { get; set; } = 10;
protected int percLoading { get; set; } = 0;
protected int percLoading { get; set; } = 0;
#endregion Protected Properties
+73
View File
@@ -0,0 +1,73 @@
<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)
{
<option value="@item">@item</option>
}
}
</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="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="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>
</div>
+162
View File
@@ -0,0 +1,162 @@
using Microsoft.AspNetCore.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class DossiersFilter
{
#region Public Properties
[Parameter]
public EventCallback<SelectDossierParams> FilterChanged { get; set; }
[Parameter]
public SelectDossierParams SelFilterDossier { get; set; } = null!;
#endregion Public Properties
#region Protected Properties
[Inject]
protected MpDataService MDService { get; set; } = null!;
protected string selArticolo
{
get
{
return SelFilterDossier.CodArticolo;
}
set
{
if (!SelFilterDossier.CodArticolo.Equals(value))
{
SelFilterDossier.CurrPage = 1;
SelFilterDossier.CodArticolo = value;
StateHasChanged();
Task.Delay(1);
reportChange();
}
}
}
protected DateTime selDtMax
{
get
{
return SelFilterDossier.DtEnd;
}
set
{
if (!SelFilterDossier.DtEnd.Equals(value))
{
SelFilterDossier.DtEnd = value;
reportChange();
}
}
}
protected DateTime selDtMin
{
get
{
return SelFilterDossier.DtStart;
}
set
{
if (!SelFilterDossier.DtStart.Equals(value))
{
SelFilterDossier.DtStart = value;
reportChange();
}
}
}
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
protected override async Task OnInitializedAsync()
{
SelFilterDossier = new SelectDossierParams();
DateTime dtEnd = SelFilterDossier.DtEnd;
DateTime dtStart = dtEnd.Subtract(SelFilterDossier.DtStart).TotalDays < 15 ? SelFilterDossier.DtStart : dtEnd.AddDays(-14);
ListMacchine = await MDService.MacchineWithFlux(dtStart, dtEnd);
ListArticoli = await MDService.ArticleWithDossier();
await FilterChanged.InvokeAsync(SelFilterDossier);
}
protected void toggleParams()
{
showEditPar = !showEditPar;
}
#endregion Protected Methods
#region Private Fields
private List<string>? ListArticoli = null;
private List<string>? ListMacchine = null;
#endregion Private Fields
#region Private Properties
private bool showEditPar { get; set; } = false;
#endregion Private Properties
#region Private Methods
private void reportChange()
{
FilterChanged.InvokeAsync(SelFilterDossier);
}
private void toggleShowParams()
{
showParam = !showParam;
}
#endregion Private Methods
}
}
+211
View File
@@ -0,0 +1,211 @@
@using MP.SPEC.Components
@using MP.SPEC.Data
@if (ListRecords == null)
{
<LoadingData></LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-warning text-center display-4">Nessun record trovato</div>
}
else
{
@if (currFluxLogDto != null)
{
<div class="row">
<div class="col-12">
<div class="card mb-5">
<div class="card-header bg-primary text-light d-flex justify-content-between">
<div>
Modifica Parametro
</div>
<div>
@if (isEditing)
{
<span class="text-light">PENDING CHANGES...</span>
}
</div>
</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="@currFluxLogDto.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="@currFluxLogDto.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="@currFluxLogDto.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="@currFluxLogDto.ValoreEdit" @onclick="()=> enableEditing()">
</div>
</div>
</div>
<div class="row pt-4" style="visibility: @css()">
<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(currFluxLogDto)" class="btn btn-success">Save <i class="bi bi-save"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
<div class="row">
<div class="d-flex justify justify-content-between">
<table class="table table-sm table-striped small">
<thead>
<tr>
<th>
<button @onclick="() => closeTableFlux()" 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 Snap</th>
<th><i class="fa-solid fa-sliders"></i> ODL</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record)">
<td>
@if (isEditing == false)
{
<button class="btn btn-primary btn-sm" @onclick="() => selRecord(record)"><i class="fa-solid fa-magnifying-glass"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm disabled"><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
</td>
<td>
@record.IdxODL
</td>
<td>
@if (isEditing == false)
{
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm disabled"><i class="bi bi-trash-fill"></i></button>
}
</td>
</tr>
}
</tbody>
</table>
@if (!visualizzaFlux)
{
if (listaFlux == null)
{
<div class="alert alert-warning text-center display-4">Nessun record trovato</div>
}
else
{
<div class="table selBlock p-2">
<table class="table table-light table-sm table-striped small mb-0">
<thead>
<tr>
<th>
<button class="btn btn-info" @onclick="() => closeTableFlux()"><i class="fa-solid fa-xmark"></i></button>
</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> Data Type</th>
<th style="text-align: right;">
<span class="col-11"> Valore </span>
</th>
</tr>
</thead>
<tbody>
@foreach (var record in listaFlux)
{
<tr class="@checkSelPar(@record)">
<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>
<td>
@record.dtEvento
</td>
<td>
@record.CodFlux
</td>
<td style="text-align: right;">
@if (record.ValoreEdit != record.Valore)
{
<div title="Valore Modificato"><span class="small text-dark"></span><b>@record.ValoreEdit</b></div>
<div class="small text-secondary" title="Valore Registrato">(<i>@record.Valore</i>)</div>
}
else
{
<div><span class="small text-dark"></span>@record.ValoreEdit</div>
}
</td>
</tr>
}
</tbody>
</table>
</div>
}
}
</div>
</div>
}
+339
View File
@@ -0,0 +1,339 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using MP.SPEC.Data;
using Newtonsoft.Json;
namespace MP.SPEC.Components
{
public partial class ListDossiers : IDisposable
{
#region Public Properties
[Parameter]
public EventCallback<Dossiers> RecordSel { get; set; }
[Parameter]
public EventCallback<FluxLogDTO> RecordSelFlux { get; set; }
[Parameter]
public SelectDossierParams SelFilter { get; set; } = null!;
[Parameter]
public EventCallback<int> TotRecordChanged { get; set; }
#endregion Public Properties
#region Public Methods
private FluxLogDTO? currFluxLogDto = null;
public string checkSelPar(FluxLogDTO recordSel)
{
string answ = "";
if (currFluxLogDto != null)
{
try
{
answ = (currFluxLogDto.CodFlux == recordSel.CodFlux && currFluxLogDto.dtEvento == recordSel.dtEvento) ? "table-info" : "";
}
catch
{ }
}
return answ;
}
public string checkSelect(Dossiers recordSel)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.IdxMacchina == recordSel.IdxMacchina && currRecord.DtRif == recordSel.DtRif) ? "table-info" : "";
}
catch
{ }
}
return answ;
}
public void Dispose()
{
currRecord = null;
SearchRecords = null;
ListRecords = null;
GC.Collect();
}
private SelectDossierParams lastFilter { get; set; } = new SelectDossierParams() { CurrPage = -1 };
protected override async Task OnParametersSetAsync()
{
if (!lastFilter.Equals(SelFilter))
{
lastFilter = SelFilter.clone();
await reloadData(true);
}
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; } = null!;
#endregion Protected Properties
#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)
{
currFluxLogDto = selRec;
// indico record selezionato
await RecordSelFlux.InvokeAsync(selRec);
}
private void enableEditing()
{
isEditing = true;
}
protected async Task cancel()
{
var alert = await JSRuntime.InvokeAsync<bool>("confirm", "Confermi di voler annullare TUTTE le modifiche? i dati saranno ricaricati.");
if (alert)
{
currFluxLogDto = null;
isEditing = false;
await Task.Delay(1);
listaFlux = MDService.getFluxLog(currRecord.Valore);
StateHasChanged();
}
}
protected async Task update(FluxLogDTO selRec)
{
var alert = await JSRuntime.InvokeAsync<bool>("confirm", "Confermi di voler salvare TUTTE le modifiche? queste saranno parte del dossier inviato all'impianto");
if (alert)
{
await Task.Delay(1);
if (currRecord != null)
{
// serializzo valore x flux log...
DossierFluxLogDTO updatedResult = new DossierFluxLogDTO() { ODL = listaFlux };
string newVal = JsonConvert.SerializeObject(updatedResult);
currRecord.Valore = newVal;
// METODO PER UPDATE FLUX
await MDService.DossiersUpdateValore(currRecord);
currFluxLogDto = null;
isEditing = false;
await Task.Delay(1);
StateHasChanged();
}
return;
}
else
{
currFluxLogDto = null;
await Task.Delay(1);
await JSRuntime.InvokeAsync<bool>("location.reload");
}
}
protected override async Task OnInitializedAsync()
{
ListStati = await MDService.AnagStatiComm();
await reloadData(true);
}
protected async void OnSeachUpdated()
{
await InvokeAsync(() =>
{
currPage = 1;
StateHasChanged();
});
}
protected async Task selRecord(Dossiers selRec)
{
currRecord = selRec;
await RecordSel.InvokeAsync(selRec);
listaFlux = MDService.getFluxLog(selRec.Valore);
await toggleTableFlux();
}
protected async Task UpdateData()
{
currRecord = null;
await reloadData(true);
}
private string css()
{
string answ = "";
if (isEditing)
{
answ = "visible";
}
else
{
answ = "hidden";
}
return answ;
}
#endregion Protected Methods
#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
#region Private Properties
private int currPage
{
get => SelFilter.CurrPage;
set => SelFilter.CurrPage = value;
}
private bool isEditing
{
get => SelFilter.isEditing;
set => SelFilter.isEditing = value;
}
private bool isLoading { get; set; } = false;
private List<FluxLogDTO>? listaFlux { get; set; } = null;
private int MaxRecord
{
get => SelFilter.MaxRecord;
}
private int numRecord
{
get => SelFilter.NumRec;
set => SelFilter.NumRec = value;
}
private string SelArticolo
{
get => SelFilter.CodArticolo;
}
private DateTime SelDtEnd
{
get => SelFilter.DtEnd;
}
private DateTime SelDtStart
{
get => SelFilter.DtStart;
}
private string SelMacchina
{
get => SelFilter.IdxMacchina;
}
private int totalCount
{
get => _totalCount;
set
{
if (_totalCount != value)
{
_totalCount = value;
TotRecordChanged.InvokeAsync(value);
}
}
}
private bool visualizzaFlux { get; set; } = true;
#endregion Private Properties
#region Private Methods
private async Task reloadData(bool setChanged)
{
isLoading = true;
SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelArticolo, SelDtStart, SelDtEnd);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
if (setChanged)
{
await InvokeAsync(() => StateHasChanged());
}
isLoading = false;
}
private async Task toggleTableFlux()
{
visualizzaFlux = false;
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 closeTableFlux()
{
currFluxLogDto = null;
currRecord = null;
visualizzaFlux = true;
isEditing = false;
await RecordSelFlux.InvokeAsync(currFluxLogDto);
await Task.Delay(1);
}
#endregion Private Methods
}
}
+220 -22
View File
@@ -12,57 +12,255 @@ else if (totalCount == 0)
else
{
<div class="row">
@if (currRecord != null && !showStats && isCurrOdl)
{
<div class="col-6 col-lg-8">
<button @onclick="() => forceSyncDb()" class="btn btn-success btn-sm btn-">Forza sync dati ODL <i class="bi bi-fast-forward-circle"></i></button>
</div>
<div class="col-6 col-lg-4 text-end">
@*<div class="px-2 input-group" title="Selezionare Data-Ora chiusura ODL">
<label class="input-group-text" for="dtMax"><i class="fa-regular fa-calendar-minus"></i></label>
<input class="form-control" @bind="@selDtFine" id="dtMax" type="datetime-local">
<button @onclick="() => chiudiOdl()" class="btn btn-danger btn-sm btn-">Registra chiusura ODL <i class="far fa-stop-circle"></i></button>
</div>*@
<button @onclick="() => chiudiOdl()" class="btn btn-danger btn-sm btn-">Registra chiusura ODL <i class="far fa-stop-circle"></i></button>
</div>
}
<div class="col-12">
<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>*@
<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
</th>
<th>Articolo</th>
<th>Macchina</th>
<th># pz</th>
<th>T.Ciclo</th>
<th>Inizio</th>
<th>Note</th>
<th>Richiesta</th>
<th></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-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)">
<tr class="@checkSelect(@record.IdxOdl)">
<td>
@*<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>*@
@if (isCurrOdl)
{
<button class="btn btn-primary btn-sm" @onclick="() => selRecord(record)"><i class="fa-solid fa-magnifying-glass"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm disabled"><i class="fa-solid fa-magnifying-glass"></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-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="() => selectStatRecord(record)" data-bs-toggle="modal" data-bs-target="#myModal" title="Mostra statistiche"><i class="fa-solid fa-chart-pie"></i></button>
</div>
<!-- Modal -->
</td>
</tr>
}
</tbody>
</table>
<div class="modal fade" id="myModal" 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 (statRecord != null)
{
<div class="col-3">
<b class="modal-title fs-1" id="staticBackdropLabel"><b>ODL @statRecord.IdxOdl</b></b>
</div>
<div class="col-6 fs-5">
<b>@statRecord.CodArticolo</b>
<div class="small textConsensed text-light">@statRecord.ArticoloNav.DescArticolo</div>
</div>
<div class="col-2 fs-5">
<b>@statRecord.IdxMacchina</b>
<div class="small textConsensed text-light">@statRecord.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 (statRecord != null && showStats)
{
<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> @statRecord.NumPezzi</div>
<div class="small textConsensed"><b>T. Ciclo:</b> @statRecord.Tcassegnato.ToString("N3")</div>
</td>
<td style="width: 300px">
<div class="small d-flex justify-content-between">
<div>
<div><b>@($"{@statRecord.DataInizio:yyyy/MM/dd}")</b></div>
<div>@($"{@statRecord.DataInizio:ddd HH:mm:ss}")</div>
</div>
<div class="p-0">
<i class="fa-solid fa-angles-right"></i>
</div>
<div>
@if (@statRecord.DataFine != null)
{
<div><b>@($"{@statRecord.DataFine:yyyy/MM/dd}")</b></div>
<div>@($"{@statRecord.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>
</tr>
</tbody>
</table>
</div>
<div>
<table class="table">
<tbody>
<tr>
<td>
<div>
@tradFase(statRecord.KeyRichiesta)
</div>
@if (statRecord.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"> @statRecord.Note </span>
</div>
}
</td>
<td>
<div class="input-group input-group-sm">
<div class="input-group-text">
<span class="me-1 @leftStringCSS">Tutti gli Stati</span>
<span class="form-check form-check-sm form-switch py-1" title="Mostra/Nascondi macchina spenta">
<input class="form-check-input" type="checkbox" id="switchSpenta" @onchange="() => toggleSpenta()" value="@hideSpenta">
</span>
<span class="@rightStringCSS">Nascondi Spenta</span>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div>
@if (statRecord != null)
{
@if (ListOdlStatsAct != null)
{
@foreach (var stat in ListOdlStatsAct)
{
<div class="p-1">
<div class="d-flex justify-content-between">
<div class="text-uppercase">
@stat.Descrizione
</div>
<div>
<b>@(formDurata(stat.TotDurata))</b>
</div>
</div>
<div class="progress">
<div class="progress-bar @colorChanger(@stat.Css)" role="progressbar" aria-valuenow="0" aria-valuemin="0" style="width: @Math.Round(calcolaPerc(stat.TotDurata),0)%; background-color:@pbStyle(@stat.Css);" aria-valuemax="100">@($"{calcolaPerc(stat.TotDurata):N1}%")</div>
</div>
</div>
}
}
}
</div>
</div>
<div class="col-4 dcContainer">
@if (statRecord != null && ListOdlStats != null)
{
<div class="dcBox">
<ODLPlot SelectedOdl="@statRecord.IdxOdl" hideSpenta="@hideSpenta"></ODLPlot>
</div>
<div class="dcBox dcOverlay d-flex">
<div class="align-self-center text-center w-100">
<b class="fs-3">@durataFilt</b>
@*<b class="fs-3">@statRecord.DurataMinuti</b>*@
</div>
</div>
}
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
</div>
}
+318 -34
View File
@@ -2,43 +2,36 @@ using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
using MP.SPEC.Services;
using NLog;
namespace MP.SPEC.Components
{
public partial class ListODL
public partial class ListODL : IDisposable
{
#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 +39,23 @@ namespace MP.SPEC.Components
return answ;
}
public void Dispose()
{
currRecord = null;
SearchRecords = null;
ListRecords = null;
ListStati = null;
ListOdlStats = null;
ListOdlStatsNetto = null;
statRecord = null;
GC.Collect();
}
public string formDurata(double durataMin)
{
return MP.Data.Utils.FormDurata(durataMin);
}
#endregion Public Methods
#region Protected Properties
@@ -57,16 +67,68 @@ namespace MP.SPEC.Components
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MessageService { get; set; } = null!;
protected IOApiService MpIoApiCall { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Registra chiusura ODL alla data indicata
/// </summary>
/// <returns></returns>
protected async Task chiudiOdl()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sei sicuro di voler chiudere l'ODL corrente?"))
return;
if (currRecord != null)
{
// effettua chiusura sul DB
await MDService.ODLClose(currRecord.IdxOdl, currRecord.IdxMacchina, 0, true);
Log.Info($"Effettuata chiusura ODL {currRecord.IdxOdl}");
// ricarica...
await selRecord(null);
}
await reloadData();
}
protected string colorChanger(string colorCSS)
{
string answ = "";
if (colorCSS == "yellow")
{
answ = "text-dark";
}
return answ;
}
/// <summary>
/// Richiesta invio sync all'IOB-WIN
/// </summary>
/// <returns></returns>
protected async Task forceSyncDb()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sei sicuro di voler reinviare i dati (Articoli, PODL) all'impianto?"))
return;
if (currRecord != null)
{
await callSyncDb(currRecord.IdxMacchina);
Log.Info($"Richiesto forceSyncDb per idxMacc {currRecord.IdxMacchina}");
// ricarica...
await selRecord(null);
}
await reloadData();
}
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();
}
@@ -75,15 +137,56 @@ namespace MP.SPEC.Components
await InvokeAsync(() =>
{
PagerResetReq.InvokeAsync(true);
//currPage = 1;
Task task = UpdateData();
StateHasChanged();
});
}
protected async Task resetSel()
{
await selRecord(null);
await reloadData();
}
protected async Task selectStatRecord(ODLModel? currRec)
{
showStats = true;
await Task.Delay(1);
statRecord = currRec;
if (currRec != null)
{
await reloadStatsData(currRec);
}
else
{
showStats = false;
ListOdlStats = null;
}
}
protected async Task selRecord(ODLModel? currRec)
{
await Task.Delay(1);
selDtFine = DateTime.Now;
currRecord = currRec;
showStats = false;
ListOdlStats = null;
ListOdlStatsNetto = null;
}
protected async Task toggleSpenta()
{
hideSpenta = !hideSpenta;
await Task.Delay(1);
if (statRecord != null)
{
await reloadStatsData(statRecord);
}
}
protected async Task UpdateData()
{
currRecord = null;
await selRecord(null);
await reloadData();
}
@@ -91,56 +194,208 @@ namespace MP.SPEC.Components
#region Private Fields
private string _statoSel = "*";
private static Logger Log = LogManager.GetCurrentClassLogger();
private ODLModel? currRecord = null;
private List<StatODLModel>? ListOdlStats;
private List<StatODLModel>? ListOdlStatsNetto;
private List<ODLModel>? ListRecords;
private List<ListValues>? ListStati;
private List<ODLModel>? SearchRecords;
private ODLModel? statRecord = null;
#endregion Private Fields
#region Private Properties
private int _totalCount { get; set; } = 0;
private int currPage
{
get => MessageService.currPage;
set => MessageService.currPage = value;
get => currFilter.CurrPage;
set => currFilter.CurrPage = value;
}
private string durataFilt
{
get
{
string answ = "ND";
if (statRecord != null)
{
if (hideSpenta)
{
if (ListOdlStatsNetto != null)
{
var tsDurata = TimeSpan.FromMinutes(ListOdlStatsNetto.Sum(x => x.TotDurata));
if (tsDurata.TotalDays < 1)
{
answ = $"{tsDurata.Hours:00}h {tsDurata.Minutes:00}'";
}
else
{
answ = $"{tsDurata.Days}gg {tsDurata.Hours:00}h";
}
}
}
else
{
answ = statRecord.DurataMinuti;
}
}
return answ;
}
}
private bool hideSpenta { get; set; } = false;
/// <summary>
/// Indica se si tratti di ODL correnti
/// </summary>
private bool isCurrOdl
{
get => currFilter.IsActive;
}
private bool isLoading { get; set; } = false;
private int numRecord
private string leftStringCSS
{
get => MessageService.numRecord;
set => MessageService.numRecord = value;
get => hideSpenta ? "text-secondary" : "text-dark fw-bold";
}
private string SearchVal
private List<StatODLModel>? ListOdlStatsAct
{
get => string.IsNullOrEmpty(MessageService.SearchVal) ? "*" : MessageService.SearchVal;
get
{
List<StatODLModel> answ = new List<StatODLModel>();
if (hideSpenta)
{
answ = ListOdlStatsNetto;
}
else
{
answ = ListOdlStats;
}
return answ;
}
}
private int numRecord
{
get => currFilter.NumRec;
set => currFilter.NumRec = value;
}
private string rightStringCSS
{
get => hideSpenta ? "text-dark fw-bold" : "text-secondary";
}
private DateTime selDtFine { get; set; } = DateTime.Now;
private bool showStats { get; set; } = false;
private int totalCount
{
get => MessageService.totalCount;
set => MessageService.totalCount = value;
get => _totalCount;
set
{
if (_totalCount != value)
{
_totalCount = value;
updateRecordCount.InvokeAsync(value);
}
}
}
#endregion Private Properties
#region Private Methods
private async void MessageService_EA_PageUpdated()
/// <summary>
/// Chiama metodo x chiedere sync DB
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
private async Task addTask2Exe(string idxMacc, string taskName, string taskVal)
{
await reloadData();
// compongo URL e chiamo
string restUrl = $"IOB/addTask2Exe/{idxMacc}?taskName={taskName}&taskVal={taskVal}";
try
{
var response = await MpIoApiCall.callMpIoUrlGet(restUrl);
}
catch (Exception exc)
{
Log.Error($"Errore durante chiamata: {Environment.NewLine}{exc}");
}
}
private double calcolaPerc(double durata)
{
double answ = 0;
double tot = 0;
if (ListOdlStatsAct != null)
{
tot = ListOdlStatsAct.Sum(x => x.TotDurata);
double perc = (durata / tot) * 100;
if (perc > 1)
{
answ = Math.Round(perc, 2);
}
else
{
answ = Math.Round(perc, 4);
}
}
return answ;
}
/// <summary>
/// Chiama metodo x chiedere sync DB
/// </summary>
/// <param name="IdxMacc"></param>
/// <returns></returns>
private async Task callSyncDb(string IdxMacc)
{
// chiamo aggiunta task SyncDb...
await addTask2Exe(IdxMacc, "syncDbData", "");
}
private string pbStyle(string css)
{
string answ = "";
if (ListOdlStats != null)
{
if (css == "yellow")
{
answ = "orange";
}
else if (css == "blue")
{
answ = "#2874A6";
}
else
{
answ = css;
}
}
return answ;
}
private async Task reloadData()
{
isLoading = true;
SearchRecords = await MDService.ListODLFilt(true, SearchVal, StatoSel);
SearchRecords = await MDService.ListODLFilt(currFilter.IsActive, currFilter.SearchVal, currFilter.CodStato, currFilter.IdxMacchina, currFilter.DtStart, currFilter.DtEnd);
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
await Task.Delay(1);
@@ -148,6 +403,35 @@ namespace MP.SPEC.Components
isLoading = false;
}
private async Task reloadStatsData(ODLModel? currRec)
{
showStats = true;
if (currRec != null)
{
ListOdlStats = await MDService.StatOdl(currRec.IdxOdl);
ListOdlStatsNetto = ListOdlStats.Where(x => x.Semaforo != "sGr").ToList();
}
else
{
ListOdlStats = null;
ListOdlStatsNetto = null;
}
}
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
}
}
+6 -13
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>Data</th>
<th>Macchina</th>
<th>Parametro</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>
+54 -25
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!;
@@ -22,15 +25,15 @@ namespace MP.SPEC.Components
#endregion Public Properties
#region Public Methods
public string checkSelect(string IdxMacchina)
private SelectFluxParams lastFilter { get; set; } = new SelectFluxParams() { CurrPage = -1 };
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,13 +41,29 @@ namespace MP.SPEC.Components
return answ;
}
protected override async Task OnParametersSetAsync()
{
await Task.Delay(1);
// se sono cambiati --> rileggo...
if (!lastFilter.Equals(SelFilter))
{
lastFilter = SelFilter.clone();
await reloadData(true);
}
}
public SelectFluxParams? LastFilter = null;
public void Dispose()
{
aTimer.Elapsed -= ElapsedTimer;
MessageService.EA_PageUpdated -= MessageService_EA_PageUpdated;
MessageService.EA_SearchUpdated -= OnSeachUpdated;
aTimer.Stop();
aTimer.Dispose();
currRecord = null;
SearchRecords = null;
ListRecords = null;
GC.Collect();
}
public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
@@ -73,7 +92,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 +110,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();
}
@@ -104,14 +126,10 @@ namespace MP.SPEC.Components
[Inject]
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MessageService { get; set; } = null!;
protected int RefreshPeriod
{
get => SelFilter.TempoAgg;
}
//protected int RefreshPeriod { get; set; } = 5000;
#endregion Protected Properties
@@ -119,13 +137,11 @@ namespace MP.SPEC.Components
protected override async Task OnInitializedAsync()
{
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 +153,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;
@@ -160,8 +190,8 @@ namespace MP.SPEC.Components
private int currPage
{
get => MessageService.currPage;
set => MessageService.currPage = value;
get => SelFilter.CurrPage;
set => SelFilter.CurrPage = value;
}
private bool isLoading { get; set; } = false;
@@ -178,8 +208,8 @@ namespace MP.SPEC.Components
private int numRecord
{
get => MessageService.numRecord;
set => MessageService.numRecord = value;
get => SelFilter.NumRec;
set => SelFilter.NumRec = value;
}
private string SelFlux
@@ -191,6 +221,10 @@ namespace MP.SPEC.Components
{
get => SelFilter.IdxMacchina;
}
private DateTime? SelDtMax
{
get => SelFilter.dtMax;
}
private int totalCount
{
@@ -209,11 +243,6 @@ namespace MP.SPEC.Components
#region Private Methods
private async void MessageService_EA_PageUpdated()
{
await reloadData(true);
}
#endregion Private Methods
}
}
+46 -14
View File
@@ -1,7 +1,7 @@
@using MP.SPEC.Components
@using MP.SPEC.Data
@if (ListRecords == null)
@if (ListRecords == null || isLoading)
{
<LoadingData></LoadingData>
}
@@ -19,36 +19,68 @@ else
<th>
<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
</th>
<th>Articolo</th>
<th>Fase</th>
<th>Macchina</th>
<th># pz</th>
<th>T.Ciclo</th>
<th>Note</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-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>
@if (canStartOdl(record.IdxMacchina))
{
<button @onclick="() => startOdl(record)" class="btn btn-success btn-sm" title="Avvia PODL">
<i class="far fa-play-circle"></i>
</button>
}
else
{
<button class="btn btn-secondary btn-sm disabled" title="ODL ancora in corso">
<i class="far fa-play-circle"></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))
{
+274 -70
View File
@@ -2,32 +2,39 @@
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
using MP.SPEC.Services;
using NLog;
namespace MP.SPEC.Components
{
public partial class ListPODL
public partial class ListPODL : IDisposable
{
#region Public Properties
[Parameter]
public EventCallback<bool> PagerResetReq { get; set; }
public SelectPOdlParams actFilter { get; set; } = new SelectPOdlParams();
[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,36 +42,13 @@ namespace MP.SPEC.Components
return answ;
}
protected async Task resetSel()
public void Dispose()
{
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);
SearchRecords = null;
ListRecords = null;
ListStati = null;
GC.Collect();
}
#endregion Public Methods
@@ -78,19 +62,68 @@ namespace MP.SPEC.Components
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MsgService { get; set; } = null!;
protected IOApiService MpIoApiCall { get; set; } = null!;
#endregion Protected Properties
#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.IdxMacchina);
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;
//await FilterChanged.InvokeAsync(actFilter);
ListStati = await MDService.AnagStatiComm();
await reloadData();
}
protected override async Task OnParametersSetAsync()
{
if (!lastFilter.Equals(actFilter))
{
lastFilter = actFilter.clone();
await reloadData();
}
}
protected async void OnSeachUpdated()
@@ -104,6 +137,69 @@ 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 startOdl(PODLModel selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sei sicuro di voler avviare PODL selezionato?"))
return;
if (selRec != null)
{
int idxEvento = 0;
string evMess = "";
// verifico ancora NON ci sia ODL corrente/aperto
if (canStartOdl(selRec.IdxMacchina))
{
await callStartSetup(selRec.IdxMacchina);
await Task.Delay(1);
// chiamo stored stp_ODL_inizioSetupPromessa e recupero ODL corrente
bool fatto = await MDService.POdlDoSetup(selRec);
if (fatto)
{
var currPOdl = await MDService.PODL_getByKey(selRec.IdxPromessa);
var newOdl = await MDService.OdlGetByKey(currPOdl.IdxOdl);
// registro evento...
idxEvento = 2;
evMess = $"Inizio Setup | PODL {selRec.IdxPromessa}";
processaEvento(selRec.IdxMacchina, idxEvento, evMess, newOdl.IdxOdl, newOdl.CodArticolo);
// aspetto 1 sec
await Task.Delay(1000);
// registro inizio produzione
idxEvento = 2;
evMess = $"Registrata inizio Produzione | PODL {selRec.IdxPromessa} | ODL {newOdl.IdxOdl} | ART {newOdl.CodArticolo}";
processaEvento(selRec.IdxMacchina, idxEvento, evMess, newOdl.IdxOdl, newOdl.CodArticolo);
// chiamo task x IOB
await callForceUpdate(selRec.IdxMacchina);
await Task.Delay(1);
await callForceUpdate(selRec.IdxMacchina);
await Task.Delay(1);
await callSyncDb(selRec.IdxMacchina);
await Task.Delay(1);
}
}
}
}
protected async Task UpdateData()
{
currRecord = null;
@@ -114,9 +210,20 @@ namespace MP.SPEC.Components
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private PODLModel? currRecord = null;
private List<PODLModel>? ListRecords;
private List<ListValues>? ListStati;
/// <summary>
/// scadenza validità lista ODL correnti
/// </summary>
private DateTime odlCurrExp = DateTime.Now.AddMinutes(-1);
/// <summary>
/// Elenco ODL correnti...
/// </summary>
private List<string> odlCurrList = new List<string>();
private List<PODLModel>? SearchRecords;
@@ -124,55 +231,166 @@ namespace MP.SPEC.Components
#region Private Properties
private int _totalCount { get; set; } = 0;
private int currPage
{
get => MsgService.currPage;
set => MsgService.currPage = value;
get => actFilter.CurrPage;
set => actFilter.CurrPage = value;
}
private bool isLoading { get; set; } = false;
private SelectPOdlParams lastFilter { get; set; } = new SelectPOdlParams() { CurrPage = -1 };
private int numRecord
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
get => actFilter.NumRec;
set => actFilter.NumRec = value;
}
private string SearchVal
{
get => string.IsNullOrEmpty(MsgService.SearchVal) ? "*" : MsgService.SearchVal;
get => string.IsNullOrEmpty(actFilter.SearchVal) ? "*" : actFilter.SearchVal;
}
private string StatoSel
{
get => MsgService.StateSel;
set => MsgService.StateSel = value;
get => actFilter.CodFase;
set => actFilter.CodFase = value;
}
private int totalCount
{
get => MsgService.totalCount;
set => MsgService.totalCount = value;
get => _totalCount;
set
{
if (_totalCount != value)
{
_totalCount = value;
updateRecordCount.InvokeAsync(value);
}
}
}
#endregion Private Properties
#region Private Methods
private async void MessageService_EA_PageUpdated()
/// <summary>
/// Chiama metodo x chiedere sync DB
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
private async Task addTask2Exe(string idxMacc, string taskName, string taskVal)
{
await reloadData();
// compongo URL e chiamo
string restUrl = $"IOB/addTask2Exe/{idxMacc}?taskName={taskName}&taskVal={taskVal}";
try
{
var response = await MpIoApiCall.callMpIoUrlGet(restUrl);
}
catch (Exception exc)
{
Log.Error($"Errore durante chiamata: {Environment.NewLine}{exc}");
}
}
private async void MsgService_EA_StatoSearch()
/// <summary>
/// Chiama metodo x chiedere force Update
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
private async Task callForceUpdate(string IdxMacc)
{
await InvokeAsync(() =>
// chiamo aggiunta task SyncDb...
await addTask2Exe(IdxMacc, "ForceUpdate", $"SPEC|TS:{DateTime.Now:yyMMddHHmmss}");
}
/// <summary>
/// Chiama metodo x indicare inizio setup
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
private async Task callStartSetup(string IdxMacc)
{
// chiamo evento inizio setup
await addTask2Exe(IdxMacc, "startSetup", $"SPEC|TS:{DateTime.Now:yyMMddHHmmss}");
}
/// <summary>
/// Chiama metodo x chiedere sync DB
/// </summary>
/// <param name="IdxMacc"></param>
/// <returns></returns>
private async Task callSyncDb(string IdxMacc)
{
// chiamo aggiunta task SyncDb...
await addTask2Exe(IdxMacc, "syncDbData", "");
}
/// <summary>
/// verifica se sia avviabile ODL x macchina
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
private bool canStartOdl(string idxMacchina)
{
// controllo se lista scaduta...
bool answ = false;
DateTime adesso = DateTime.Now;
if (adesso > odlCurrExp || odlCurrList == null || odlCurrList.Count == 0)
{
PagerResetReq.InvokeAsync(true);
//currPage = 1;
Task task = UpdateData();
StateHasChanged();
});
odlCurrList = MDService.OdlGetCurrent();
odlCurrExp = adesso.AddSeconds(2);
}
answ = !odlCurrList.Contains(idxMacchina);
return answ;
}
/// <summary>
/// processa evento richiesto
/// </summary>
/// <param name="idxMacc"></param>
/// <param name="idxEvento"></param>
/// <param name="userMsg"></param>
/// <param name="idxODL"></param>
private async void processaEvento(string idxMacc, int idxEvento, string userMsg, int idxODL, string codArticolo)
{
// se manca codart calcolo...
if (string.IsNullOrEmpty(codArticolo))
{
var currOdl = await MDService.OdlGetByKey(idxODL);
if (currOdl != null)
{
codArticolo = currOdl.CodArticolo;
}
}
// scrivo evento scriviRigaEventoBarcode
EventListModel newRec = new EventListModel()
{
IdxMacchina = idxMacc,
InizioStato = DateTime.Now,
IdxTipo = idxEvento,
CodArticolo = codArticolo,
MatrOpr = 0,
pallet = "",
Value = userMsg
};
await MDService.EvListInsert(newRec);
}
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)
@@ -189,20 +407,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"></MP.SPEC.Components.Chart.Doughnut>
}
</div>
}
+108
View File
@@ -0,0 +1,108 @@
using Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.SPEC.Data;
namespace MP.SPEC.Components
{
public partial class ODLPlot
{
#region Public Fields
public List<DoughnutStyling> colors = new List<DoughnutStyling>();
public List<double> Data = new List<double>();
public List<string> Labels = new List<string>();
#endregion Public Fields
#region Public Properties
[Parameter]
public bool hideSpenta { get; set; }
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;
[Inject]
protected MpDataService MDService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected override async Task OnInitializedAsync()
{
isLoading = true;
await Task.Delay(1);
}
protected override async Task OnParametersSetAsync()
{
await ReloadData();
await Task.Delay(1);
}
protected async Task ReloadData()
{
Data.Clear();
Labels.Clear();
colors.Clear();
ListRecords = await MDService.StatOdl(SelectedOdl);
// se hideSpenta --> filtro stato 11 = spenta...
if (hideSpenta)
{
ListRecords = ListRecords.Where(x => x.Semaforo != "sGr").ToList();
}
foreach (var record in ListRecords)
{
Data.Add(record.TotDurata);
Labels.Add($"{record.Descrizione} - {record.TotDurata:N1}min");
if (record.Css == "yellow")
{
colors.Add(new DoughnutStyling("orange", "ccc"));
}
else if (record.Css == "blue")
{
colors.Add(new DoughnutStyling("#2874A6", "ccc"));
}
else
{
colors.Add(new DoughnutStyling(record.Css, "ccc"));
}
}
await Task.Delay(1);
isLoading = false;
}
#endregion Protected Methods
#region Private Fields
private List<StatODLModel>? ListRecords = null;
#endregion Private Fields
#region Private Properties
private bool isLoading { get; set; } = false;
#endregion Private Properties
}
}
+98 -66
View File
@@ -1,73 +1,58 @@
<div class="d-flex justify-content-between">
<div class="px-0">
@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-0">
<div class="d-flex justify-content-end">
@if (showEditPar)
<div class="d-flex justify-content-between pt-1 mb-1">
<div class="px-2">
@if (!liveUpdate)
{
<div class="px-2">
<button class="btn btn-primary" @onclick="() => toggleParams()"> <i class="fa-solid fa-arrow-right"></i></button>
</div>
<div class="px-2">
<select @bind="@selTempoAgg" class="form-select">
<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>
</div>
<div class="px-2">
<select @bind="@selMaxRecord" class="form-select">
<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">
<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-2">
<select @bind="@selMacchina" class="form-select">
</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)
{
@@ -78,8 +63,12 @@
}
</select>
</div>
<div class="px-2">
<select @bind="@selFlux" class="form-select">
<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)
{
@@ -90,6 +79,49 @@
}
</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>
</div>
+159 -11
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,14 +15,52 @@ namespace MP.SPEC.Components
#endregion Public Properties
#region Protected Fields
#region Public Methods
protected string lastUpdate = "-";
/// <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 Protected Fields
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
{
get => SelFilter.lastUpdate;
set => SelFilter.lastUpdate = value;
}
protected bool liveUpdate
{
get => SelFilter.LiveUpdate;
@@ -61,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))
@@ -122,17 +158,74 @@ 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();
setDtMax();
DateTime dtStart = SelFilter.dtMin != null ? (DateTime)SelFilter.dtMin : DateTime.Now.AddDays(-7);
DateTime dtEnd = SelFilter.dtMax != null ? (DateTime)SelFilter.dtMax : DateTime.Now;
ListMacchine = await MDService.MacchineWithFlux(dtStart, dtEnd);
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 = true;
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 15 sec
dtMax = dtMax.AddSeconds(15);
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()
@@ -141,7 +234,11 @@ 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;
}
}
@@ -149,15 +246,66 @@ namespace MP.SPEC.Components
#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 = (value == null);
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);
}
}
}
+16
View File
@@ -0,0 +1,16 @@
using System.Drawing;
namespace MP.SPEC.Data
{
public class DoughnutStyling
{
public string color { get; set; }
public string border { get; set; }
public DoughnutStyling(string color, string border)
{
this.color = color;
this.border = border;
}
}
}
+1 -1
View File
@@ -150,7 +150,7 @@
private string searchVal = "";
private bool showSearch;
private string stateSel = "*";
private string tipoSearch = "*";
private string tipoSearch = "";
#endregion Private Fields
+486 -39
View File
@@ -1,6 +1,7 @@
using MP.Data;
using MP.Data.Conf;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
@@ -20,8 +21,12 @@ namespace MP.SPEC.Data
// setup compoenti REDIS
redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
redisConnAdmin = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("RedisAdmin"));
redisDb = redisConn.GetDatabase();
// leggo cache lungo periodo
int.TryParse(_configuration.GetValue<string>("ServerConf:redisLongTimeCache"), out redisLongTimeCache);
_logger.LogInformation("Redis INIT");
// setup canali pub/sub
@@ -62,7 +67,6 @@ namespace MP.SPEC.Data
public async Task<List<ListValues>> AnagStatiComm()
{
int maxAgeConfig = 5;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
List<ListValues>? result = new List<ListValues>();
@@ -78,9 +82,9 @@ namespace MP.SPEC.Data
else
{
result = await Task.FromResult(dbController.AnagStatiComm());
// serializzp e salvo...
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(redisStatoCom, rawData, getRandTOut(maxAgeConfig));
await redisDb.StringSetAsync(redisStatoCom, rawData, getRandTOut(redisLongTimeCache));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagStatiComm Read from DB: {ts.TotalMilliseconds}ms");
@@ -94,7 +98,6 @@ namespace MP.SPEC.Data
public async Task<List<ListValues>> AnagTipoArtLV()
{
int maxAgeConfig = 5;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
List<ListValues>? result = new List<ListValues>();
@@ -110,9 +113,9 @@ namespace MP.SPEC.Data
else
{
result = await Task.FromResult(dbController.AnagTipoArtLV());
// serializzp e salvo...
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(redisTipoArt, rawData, getRandTOut(maxAgeConfig));
await redisDb.StringSetAsync(redisTipoArt, rawData, getRandTOut(redisLongTimeCache));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"AnagTipoArtLV Read from DB: {ts.TotalMilliseconds}ms");
@@ -124,6 +127,41 @@ 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());
// serializzo 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>
/// Eliminazione record selezionato
/// </summary>
@@ -224,7 +262,6 @@ namespace MP.SPEC.Data
public async Task<List<ConfigModel>> ConfigGetAll()
{
int maxAgeConfig = 5;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
List<ConfigModel>? result = new List<ConfigModel>();
@@ -240,9 +277,9 @@ namespace MP.SPEC.Data
else
{
result = await Task.FromResult(dbController.ConfigGetAll());
// serializzp e salvo...
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(redisConfKey, rawData, getRandTOut(maxAgeConfig));
await redisDb.StringSetAsync(redisConfKey, rawData, getRandTOut(redisLongTimeCache));
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ConfigGetAll Read from DB: {ts.TotalMilliseconds}ms");
@@ -279,6 +316,107 @@ 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)
/// </summary>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
/// <param name="DtStart">Data minima per estrazione records</param>
/// <param name="DtEnd">Data Massima per estrazione records</param>
/// <returns></returns>
public async Task<List<Dossiers>> DossiersGetLastFilt(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd)
{
List<Dossiers>? result = new List<Dossiers>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = $"{redisDossByMac}:{IdxMacchina}:{CodArticolo}:{DtStart:yyyyMMddHHmm}:{DtEnd:yyyyMMddHHmm}";
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<Dossiers>>($"{rawData}");
readType = "REDIS";
}
else
{
result = await Task.FromResult(dbController.DossiersGetLastFilt(IdxMacchina, CodArticolo, DtStart, DtEnd));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5));
}
if (result == null)
{
result = new List<Dossiers>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"DossiersGetLastFilt | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
/// <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> DossiersTakeParamsSnapshot(string IdxMacchina, int MaxSec, DateTime DtRif)
{
bool answ = false;
await Task.Delay(1);
// chiamo stored x salvare parametri
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));
currKey = $"{redisDossByMac}:*";
redisDb.StringSet(currKey, "", TimeSpan.FromSeconds(1));
return answ;
}
/// <summary>
/// Restitusice elenco aziende
/// </summary>
@@ -302,22 +440,61 @@ namespace MP.SPEC.Data
return Task.FromResult(dbController.ElencoLink());
}
/// <summary>
/// Aggiunta record EventList
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
public async Task<bool> EvListInsert(EventListModel newRec)
{
return await dbController.EvListInsert(newRec);
}
public async Task<bool> FlushRedisCache()
{
await Task.Delay(1);
RedisValue pattern = new RedisValue($"{redisBaseAddr}*");
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)
{
List<FluxLog>? result = new List<FluxLog>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
var results = await Task.FromResult(dbController.FluxLogGetLastFilt(IdxMacchina, CodFlux, MaxRec));
string readType = "DB";
string currKey = $"{redisFluxLogFilt}:{IdxMacchina}:{CodFlux}:{MaxRec}:{DtMax:yyyyMMdd}:{DtMax:HHmm}";
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<FluxLog>>($"{rawData}");
readType = "REDIS";
}
else
{
result = await Task.FromResult(dbController.FluxLogGetLastFilt(DtMax, IdxMacchina, CodFlux, MaxRec));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(10));
}
if (result == null)
{
result = new List<FluxLog>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"FluxLogGetLastFilt | Read from DB: {ts.TotalMilliseconds}ms");
return results;
Log.Debug($"FluxLogGetLastFilt | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
/// <summary>
@@ -329,6 +506,28 @@ namespace MP.SPEC.Data
return Task.FromResult(currTagConf);
}
public List<FluxLogDTO> getFluxLog(string Valore)
{
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;
}
/// <summary>
/// restituisce il valore da REDIS associato al tag richeisto
/// </summary>
@@ -352,10 +551,11 @@ namespace MP.SPEC.Data
/// <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="IdxMacchina">id macchina da cercare</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, string IdxMacchina, DateTime startDate, DateTime endDate)
{
return await Task.FromResult(dbController.ListODLFilt(inCorso, codArt, keyRichPart));
return await Task.FromResult(dbController.ListODLFilt(inCorso, codArt, keyRichPart, IdxMacchina, startDate, endDate));
}
/// <summary>
@@ -366,7 +566,35 @@ namespace MP.SPEC.Data
/// <returns></returns>
public async Task<List<PODLModel>> ListPODLFilt(string codArt, string keyRichPart)
{
return await Task.FromResult(dbController.ListPODLFilt(codArt, keyRichPart));
List<PODLModel>? result = new List<PODLModel>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = $"{redisPOdlList}:{codArt}:{keyRichPart}";
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<PODLModel>>($"{rawData}");
readType = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ListPODLFilt(codArt, keyRichPart));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(3));
}
if (result == null)
{
result = new List<PODLModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ListPODLFilt | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
/// <summary>
@@ -379,8 +607,6 @@ namespace MP.SPEC.Data
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
// 5 minuti valore cache
int maxAgeMin = 5;
string currKey = redisMacList;
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
@@ -392,9 +618,9 @@ namespace MP.SPEC.Data
else
{
result = await Task.FromResult(dbController.MacchineGetAll());
// serializzp e salvo...
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(maxAgeMin));
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
@@ -407,18 +633,18 @@ namespace MP.SPEC.Data
}
/// <summary>
/// Elenco ID macchine con dati FluxLog gestite
/// Elenco id Macchine che abbiano dati FLuxLog, nel periodo indicato
/// </summary>
/// <param name="dtStart"></param>
/// <param name="dtEnd"></param>
/// <returns></returns>
public async Task<List<string>> MacchineWithFlux()
public async Task<List<string>> MacchineWithFlux(DateTime dtStart, DateTime dtEnd)
{
List<string>? result = new List<string>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
// 5 minuti valore cache
int maxAgeMin = 5;
string currKey = redisMacByFlux;
string currKey = $"{redisMacByFlux}:{dtStart:yyyyMMddHHmm}:{dtEnd:yyyyMMddHHmm}";
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
@@ -428,10 +654,10 @@ namespace MP.SPEC.Data
}
else
{
result = await Task.FromResult(dbController.MacchineWithFlux());
// serializzp e salvo...
result = await dbController.MacchineWithFlux(dtStart, dtEnd);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(maxAgeMin));
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
@@ -443,6 +669,93 @@ namespace MP.SPEC.Data
return result;
}
/// <summary>
/// Effettua chiusura dell'ODL indicato, andand
/// </summary>
/// <param name="idxOdl">idx odl da chiudere</param>
/// <param name="idxMacchina">idx macchina</param>
/// <param name="matrOpr">matricola operatore</param>
/// <param name="confPezzi">indica se confermare i pezzi priam di chiudere ODL</param>
public async Task<bool> ODLClose(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi)
{
bool fatto = false;
await Task.Delay(1);
// recupero dati x conf modalità conferma
var configData = await ConfigGetAll();
if (configData != null)
{
bool confRett = false;
var currRec = configData.FirstOrDefault(x => x.Chiave == "confRett");
if (currRec != null)
{
bool.TryParse(currRec.Valore, out confRett);
}
int modoConfProd = 0;
currRec = configData.FirstOrDefault(x => x.Chiave == "modoConfProd");
if (currRec != null)
{
int.TryParse(currRec.Valore, out modoConfProd);
}
// chiamo metodo conferma!
fatto = await dbController.ODLClose(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd);
}
return fatto;
}
/// <summary>
/// Record ODL da chaive
/// </summary>
/// <returns></returns>
public async Task<ODLModel> OdlGetByKey(int IdxOdl)
{
await Task.Delay(1);
var dbResult = dbController.OdlGetByKey(IdxOdl);
return dbResult;
}
/// <summary>
/// ODL correnti (tutti)
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
public List<string> OdlGetCurrent()
{
List<string> dbResult = new List<string>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = $"{redisOdlCurrByMac}";
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
try
{
dbResult = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
}
catch
{ }
readType = "REDIS";
}
else
{
dbResult = dbController.OdlGetCurrent().Select(x => x.IdxMacchina).Distinct().ToList();
rawData = JsonConvert.SerializeObject(dbResult);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(3));
}
if (dbResult == null)
{
dbResult = new List<string>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"OdlGetCurrent | Read from {readType}: {ts.TotalMilliseconds}ms");
return dbResult;
}
/// <summary>
/// Elenco di tutti i parametri filtrati x macchina
/// </summary>
@@ -454,8 +767,6 @@ namespace MP.SPEC.Data
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
// 5 minuti valore cache
int maxAgeMin = 5;
string currKey = $"{redisFluxByMac}:{IdxMacchina}";
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
@@ -467,9 +778,9 @@ namespace MP.SPEC.Data
else
{
result = await Task.FromResult(dbController.ParametriGetFilt(IdxMacchina));
// serializzp e salvo...
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(maxAgeMin));
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
@@ -481,6 +792,16 @@ namespace MP.SPEC.Data
return result;
}
/// <summary>
/// Recupero PODL da chiave
/// </summary>
/// <param name="idxPODL"></param>
/// <returns></returns>
public async Task<PODLModel> PODL_getByKey(int idxPODL)
{
return await dbController.PODL_getByKey(idxPODL);
}
/// <summary>
/// Eliminazione record selezionato
/// </summary>
@@ -491,6 +812,16 @@ namespace MP.SPEC.Data
return await dbController.PODLDeleteRecord(currRec);
}
/// <summary>
/// Avvio fase setup per il record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> POdlDoSetup(PODLModel currRec)
{
return await dbController.PODL_startSetup(currRec, 0, 1, 1, "");
}
/// <summary>
/// Aggiornamento record selezionato
/// </summary>
@@ -498,7 +829,70 @@ namespace MP.SPEC.Data
/// <returns></returns>
public async Task<bool> POdlUpdateRecord(PODLModel currRec)
{
return await dbController.PODLUpdateRecord(currRec);
var dbResult = await dbController.PODLUpdateRecord(currRec);
// elimino cache redis...
RedisValue pattern = new RedisValue($"{redisPOdlList}:*");
bool answ = await ExecFlushRedisPattern(pattern);
return dbResult;
}
/// <summary>
/// Statistiche ODL calcolate (da stored stp_STAT_ODL)
/// </summary>
/// <returns></returns>
public Task<List<StatODLModel>> StatOdl(int IdxOdl)
{
return dbController.OdlStart(IdxOdl);
}
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 async Task<bool> DossiersUpdateValore(Dossiers currDoss)
{
// aggiorno record sul DB
bool answ = await dbController.DossiersUpdateValore(currDoss);
return answ;
}
#endregion Public Methods
@@ -526,12 +920,25 @@ namespace MP.SPEC.Data
#region Private Fields
private const string redisConfKey = "MP:SPEC:Cache:Config";
private const string redisFluxByMac = "MP:SPEC:Cache:FluxByMac";
private const string redisMacByFlux = "MP:SPEC:Cache:MacByFlux";
private const string redisMacList = "MP:SPEC:Cache:MacList";
private const string redisStatoCom = "MP:SPEC:Cache:StatoCom";
private const string redisTipoArt = "MP:SPEC:Cache:TipoArt";
private const string redisArtByDossier = redisBaseAddr + "SPEC:Cache:ArtByDossier";
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 redisOdlCurrByMac = redisBaseAddr + "SPEC:Cache:OdlByMac";
private const string redisMacByFlux = redisBaseAddr + "SPEC:Cache:MacByFlux";
private const string redisMacList = redisBaseAddr + "SPEC:Cache:MacList";
private const string redisPOdlList = redisBaseAddr + "SPEC:Cache:POdlList";
private const string redisFluxLogFilt = redisBaseAddr + "SPEC:Cache:FluxLogFilt";
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!;
@@ -543,11 +950,51 @@ namespace MP.SPEC.Data
/// </summary>
private ConnectionMultiplexer redisConn = null!;
/// <summary>
/// Oggetto per connessione a REDIS modalità admin (ex flux dati)
/// </summary>
private ConnectionMultiplexer redisConnAdmin = null!;
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
private IDatabase redisDb = null!;
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
}
}
+74
View File
@@ -0,0 +1,74 @@
namespace MP.SPEC.Data
{
public class SelectArticoliParams
{
#region Public Constructors
public SelectArticoliParams()
{ }
#endregion Public Constructors
#region Public Properties
public int CurrPage { get; set; } = 1;
public string IdxMacchina { get; set; } = "*";
public string Azienda { get; set; } = "*";
public int MaxRecord { get; set; } = 100;
public int NumRec { get; set; } = 10;
public int TotCount { get; set; } = 0;
#endregion Public Properties
#region Public Methods
public SelectArticoliParams clone()
{
SelectArticoliParams clonedData = new SelectArticoliParams()
{
CurrPage = this.CurrPage,
IdxMacchina = this.IdxMacchina,
Azienda = this.Azienda,
MaxRecord = this.MaxRecord,
NumRec = this.NumRec,
TotCount = this.TotCount
};
return clonedData;
}
public override bool Equals(object obj)
{
if (!(obj is SelectArticoliParams item))
return false;
if (MaxRecord != item.MaxRecord)
return false;
if (NumRec != item.NumRec)
return false;
if (TotCount != item.TotCount)
return false;
if (CurrPage != item.CurrPage)
return false;
if (IdxMacchina != item.IdxMacchina)
return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion Public Methods
}
}
+86
View File
@@ -0,0 +1,86 @@
using MP.Data;
namespace MP.SPEC.Data
{
public class SelectDossierParams
{
#region Public Constructors
public SelectDossierParams()
{ }
#endregion Public Constructors
#region Public Properties
public int CurrPage { get; set; } = 1;
public DateTime DtEnd { get; set; } = Utils.InitDatetime(DateTime.Now, 5);
public DateTime DtStart { get; set; } = Utils.InitDatetime(DateTime.Now, 5).AddDays(-730);
public string IdxMacchina { get; set; } = "*";
public string CodArticolo { get; set; } = "*";
public int NumRec { get; set; } = 10;
public int TotCount { get; set; } = 0;
public int MaxRecord { get; set; } = 100;
public bool isEditing { get; set; } = false;
#endregion Public Properties
#region Public Methods
public SelectDossierParams clone()
{
SelectDossierParams clonedData = new SelectDossierParams()
{
DtEnd = this.DtEnd,
DtStart = this.DtStart,
CurrPage = this.CurrPage,
IdxMacchina = this.IdxMacchina,
CodArticolo = this.CodArticolo,
MaxRecord = this.MaxRecord,
NumRec = this.NumRec,
TotCount = this.TotCount
};
return clonedData;
}
public override bool Equals(object obj)
{
if (!(obj is SelectDossierParams item))
return false;
if (IdxMacchina != item.IdxMacchina)
return false;
if (CodArticolo != item.CodArticolo)
return false;
if (MaxRecord != item.MaxRecord)
return false;
if (TotCount != item.TotCount)
return false;
if (NumRec != item.NumRec)
return false;
if (DtEnd != item.DtEnd)
return false;
if (CurrPage != item.CurrPage)
return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion Public Methods
}
}
+38 -6
View File
@@ -12,17 +12,40 @@
#region Public Properties
public string CodFlux { get; set; } = "*";
public string IdxMacchina { 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 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 NumRec { get; set; } = 10;
public int MaxRecord { get; set; } = 100;
public int TempoAgg { get; set; } = 10000;
public int TotCount { get; set; } = 0;
#endregion Public Properties
#region Public Methods
public SelectFluxParams clone()
{
SelectFluxParams clonedData = new SelectFluxParams()
{
CodFlux = this.CodFlux,
CurrPage = this.CurrPage,
dtRif = this.dtRif,
dtMax = this.dtMax,
dtMin = this.dtMin,
IdxMacchina = this.IdxMacchina,
lastUpdate = this.lastUpdate,
LiveUpdate = this.LiveUpdate,
NumRec = this.NumRec,
MaxRecord = this.MaxRecord,
TotCount = this.TotCount,
TempoAgg = this.TempoAgg
};
return clonedData;
}
public override bool Equals(object obj)
{
if (!(obj is SelectFluxParams item))
@@ -42,10 +65,19 @@
if (TempoAgg != item.TempoAgg)
return false;
if (NumRec!= item.NumRec)
return false;
if (TotCount!= item.TotCount)
return false;
if (CurrPage != item.CurrPage)
return false;
if (lastUpdate != item.lastUpdate)
return false;
return true;
}
+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
}
}
+73
View File
@@ -0,0 +1,73 @@
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 string IdxMacchina { get; set; } = "*";
public int CurrPage { get; set; } = 1;
public int NumRec { get; set; } = 10;
public int TotCount { get; set; } = 0;
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 (IdxMacchina != item.IdxMacchina)
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
}
}
+83
View File
@@ -0,0 +1,83 @@
namespace MP.SPEC.Data
{
public class SelectPOdlParams
{
#region Public Constructors
public SelectPOdlParams()
{ }
#endregion Public Constructors
#region Public Properties
public string CodFase { get; set; } = "*";
public int CurrPage { get; set; } = 1;
public string IdxMacchina { get; set; } = "*";
public int MaxRecord { get; set; } = 100;
public int NumRec { get; set; } = 10;
public string SearchVal { get; set; } = "*";
public int TotCount { get; set; } = 0;
#endregion Public Properties
#region Public Methods
public SelectPOdlParams clone()
{
SelectPOdlParams clonedData = new SelectPOdlParams()
{
CodFase = this.CodFase,
CurrPage = this.CurrPage,
IdxMacchina = this.IdxMacchina,
MaxRecord = this.MaxRecord,
NumRec = this.NumRec,
SearchVal = this.SearchVal,
TotCount = this.TotCount
};
return clonedData;
}
public override bool Equals(object obj)
{
if (!(obj is SelectPOdlParams item))
return false;
if (CodFase != item.CodFase)
return false;
if (MaxRecord != item.MaxRecord)
return false;
if (NumRec != item.NumRec)
return false;
if (TotCount != item.TotCount)
return false;
if (CurrPage != item.CurrPage)
return false;
if (IdxMacchina != item.IdxMacchina)
return false;
if (SearchVal != item.SearchVal)
return false;
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion Public Methods
}
}
+31 -6
View File
@@ -5,6 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP.SPEC</RootNamespace>
<Version>6.16.2210.2014</Version>
</PropertyGroup>
<ItemGroup>
@@ -13,19 +14,43 @@
<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>
<ProjectReference Include="..\MP.Data\MP.Data.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\favicon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Update="logs\.placeholder">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="post-build.ps1">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
</Target>
</Project>
+19 -15
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">
@@ -17,22 +17,25 @@
</div>
</div>
<div class="px-0 align-content-center">
<select @bind="@selAzienda" class="form-select">
@if (ListAziende != null)
{
foreach (var item in ListAziende)
<div class="input-group input-group">
<label class="input-group-text" for="maxRecord" title="Selezionare l'azienda da visualizzare"><i class="fa-solid fa-industry"></i></label>
<select @bind="@selAzienda" class="form-select" title="Selezionare l'azienda da visualizzare">
@if (ListAziende != null)
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
foreach (var item in ListAziende)
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
}
</select>
</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</div>
<div class="card-body">
@@ -119,11 +122,11 @@
<th>
<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
</th>
<th>Articolo</th>
<th>Disegno</th>
<th>Descrizione</th>
<th>Tipo</th>
<th>Azienda</th>
<th><i class="fa-solid fa-file"></i> Articolo</th>
<th><i class="fa-solid fa-compass-drafting"></i> Disegno</th>
<th><i class="fa-solid fa-file-word"></i> Descrizione</th>
<th><i class="fa-solid fa-rectangle-list"></i> Tipo</th>
<th><i class="fa-solid fa-industry"></i> Azienda</th>
<th></th>
</tr>
</thead>
@@ -132,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>
+41 -41
View File
@@ -24,9 +24,17 @@ namespace MP.SPEC.Pages
return answ;
}
private SelectArticoliParams currFilter = new SelectArticoliParams();
public void Dispose()
{
MessageService.EA_SearchUpdated -= OnSeachUpdated;
//MessageService.EA_SearchUpdated -= OnSeachUpdated;
currRecord = null;
ListTipoArt = null;
ListAziende = null;
SearchRecords = null;
ListRecords = null;
GC.Collect();
}
public async void OnSeachUpdated()
@@ -44,13 +52,10 @@ namespace MP.SPEC.Pages
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; }
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; }
[Inject]
protected MessageService MessageService { get; set; }
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected NavigationManager NavManager { get; set; }
@@ -78,7 +83,7 @@ namespace MP.SPEC.Pages
/// <returns></returns>
protected async Task addNew()
{
currRecord = new MP.Data.DatabaseModels.AnagArticoli()
currRecord = new AnagArticoli()
{
CodArticolo = $"_NEW_{DateTime.Now:yyyyMMdd.HHmmss}",
DescArticolo = "Nuovo articolo",
@@ -97,11 +102,11 @@ namespace MP.SPEC.Pages
}
/// <summary>
/// Eliminazione record selezioanto (previa conferma)
/// Eliminazione record selezionato (previa conferma)
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
protected async Task deleteRecord(MP.Data.DatabaseModels.AnagArticoli selRec)
protected async Task deleteRecord(AnagArticoli selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Eliminazione Articolo: sei sicuro di voler procedere?"))
return;
@@ -124,11 +129,7 @@ namespace MP.SPEC.Pages
protected override async Task OnInitializedAsync()
{
clearFile();
numRecord = 10;
// mostro ricerca
MessageService.ShowSearch = true;
MessageService.EA_SearchUpdated += OnSeachUpdated;
configData = await MDService.ConfigGetAll();
var currRec = configData.FirstOrDefault(x => x.Chiave == "AZIENDA");
if (currRec != null)
@@ -137,12 +138,15 @@ namespace MP.SPEC.Pages
}
ListAziende = await MDService.ElencoAziende();
ListTipoArt = await MDService.AnagTipoArtLV();
}
protected override async Task OnParametersSetAsync()
{
await reloadData();
}
protected void ResetData()
{
clearFile();
currRecord = null;
}
@@ -152,13 +156,28 @@ namespace MP.SPEC.Pages
await Task.Delay(1);
}
protected async Task selRecord(MP.Data.DatabaseModels.AnagArticoli selRec)
protected async Task selRecord(AnagArticoli selRec)
{
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(MP.Data.DatabaseModels.AnagArticoli selRec)
protected async Task update(AnagArticoli selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi di voler salvare le modifiche?"))
return;
@@ -180,12 +199,11 @@ namespace MP.SPEC.Pages
#region Private Fields
private string _selAzienda = "*";
private MP.Data.DatabaseModels.AnagArticoli? currRecord = null;
private string fileName = "Controlli.csv";
private List<MP.Data.DatabaseModels.AnagGruppi>? ListAziende;
private List<MP.Data.DatabaseModels.AnagArticoli>? ListRecords;
private List<MP.Data.DatabaseModels.ListValues>? ListTipoArt;
private List<MP.Data.DatabaseModels.AnagArticoli>? SearchRecords;
private AnagArticoli? currRecord = null;
private List<AnagGruppi>? ListAziende;
private List<AnagArticoli>? ListRecords;
private List<ListValues>? ListTipoArt;
private List<AnagArticoli>? SearchRecords;
#endregion Private Fields
@@ -209,11 +227,6 @@ namespace MP.SPEC.Pages
}
}
private string fullPath
{
get => $"{Directory.GetCurrentDirectory()}\\temp\\{fileName}";
}
private bool isLoading { get; set; } = false;
private int numRecord
@@ -274,23 +287,10 @@ namespace MP.SPEC.Pages
return answ;
}
private async void clearFile()
{
await Task.Run(() => File.Delete(fullPath));
}
private async Task ExportCsv()
{
isLoading = true;
// salvo davvero!
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath);
isLoading = false;
}
private async Task reloadData()
{
isLoading = true;
SearchRecords = await MDService.ArticoliGetSearch(100000, selAzienda, MessageService.SearchVal);
SearchRecords = await MDService.ArticoliGetSearch(100000, selAzienda, "*");
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
isLoading = false;
}
+36
View File
@@ -0,0 +1,36 @@
@page "/DOSS"
<div class="card mb-5">
<div class="card-header table-primary">
<div class="d-flex">
<div class="px-0 py-1">
<h3><b>DOSSIERS</b></h3>
</div>
<div class="px-2 flex-fill">
@if (isFiltering)
{
<LoadingDataSmall></LoadingDataSmall>
<i>filtro x macchina / periodo</i>
}
else
{
<DossiersFilter FilterChanged="updateFilter"></DossiersFilter>
}
</div>
</div>
</div>
<div class="card-body">
@if (isLoading)
{
<LoadingData></LoadingData>
}
else
{
<ListDossiers SelFilter="@currFilter" RecordSel="@selRecordDoss" 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>
</div>
+147
View File
@@ -0,0 +1,147 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using MP.SPEC.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Pages
{
public partial class DOSS
{
#region Protected Fields
protected DataPager pagerODL = null!;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
StateHasChanged();
}
protected override async Task OnInitializedAsync()
{
isLoading = true;
isFiltering = true;
// fix pagina
await Task.Delay(1);
var modFilter = currFilter;
modFilter.CurrPage = 1;
currFilter = modFilter;
await Task.Delay(1);
isFiltering = false;
}
protected async Task selRecordDoss(Dossiers selDoss)
{
currRecordDoss = selDoss;
await Task.Delay(1);
}
private string css()
{
string answ = "";
if (isEditing == false)
{
answ = "hidden";
}
else
{
answ = "visible";
}
return answ;
}
private void enableEditing()
{
isEditing = true;
}
protected void updateTotal(int newTotCount)
{
totalCount = newTotCount;
}
#endregion Protected Methods
#region Private Fields
private FluxLogDTO? _currDetFluxLogRecord = null;
#endregion Private Fields
#region Private Properties
private SelectDossierParams currFilter { get; set; } = new SelectDossierParams();
private int currPage
{
get => currFilter.CurrPage;
set => currFilter.CurrPage = value;
}
private Dossiers? currRecordDoss { get; set; } = null;
private bool isFiltering { get; set; } = false;
private bool isLoading { get; set; } = true;
private int numRecord
{
get => currFilter.NumRec;
set => currFilter.NumRec = value;
}
private bool isEditing
{
get => currFilter.isEditing;
set => currFilter.isEditing = value;
}
private int totalCount
{
get => currFilter.TotCount;
set => currFilter.TotCount = value;
}
#endregion Private Properties
#region Private Methods
private async Task updateFilter(SelectDossierParams newParams)
{
isFiltering = false;
isLoading = true;
await Task.Delay(1);
currPage = 1;
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
currFilter = newParams;
isLoading = false;
}
protected void UpdateTotCount(int newTotCount)
{
totalCount = newTotCount;
}
#endregion Private Methods
}
}
+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
}
}
+15 -7
View File
@@ -2,25 +2,23 @@
<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">
<img src="/images/LogoMapo.png" class="image-fluid" height="64" />
<img src="images/LogoMapo.png" class="image-fluid" height="64" />
</div>
<div class="p-2 align-content-center fs-1">
<b>MAPO SPEC</b>
</div>
<div class="p-2 bg-light">
<img src="/images/LogoEgw.png" class="image-fluid" height="64" />
<img src="images/LogoEgw.png" class="image-fluid" height="64" />
</div>
</div>
</div>
<div class="card-body text-center">
<h5 class="card-title">MAPO MES Custom Pages</h5>
<div class="shortcuts">
<div class="shortcuts my-3 py-3">
<div class="row">
<div class="col-12">
@if (ElencoLink == null)
@@ -35,6 +33,7 @@
}
else
{
foreach (var item in ElencoLink)
{
<a href="@item.NavigateUrl" class="shortcut">
@@ -46,7 +45,16 @@
</div>
</div>
</div>
<p class="card-text">Custom pages azienda <b>@currAzienda</b></p>
</div>
<dic class="card-footer bg-primary">
<div class="d-flex text-white justify-content-between">
<div class="px-2">
<h1>@currAzienda</h1>
</div>
<div class="px-2">
<h3 class="my-2">MAPO MES Custom Pages</h3>
</div>
</div>
</dic>
</div>
+86 -210
View File
@@ -1,228 +1,104 @@
@page "/ODL"
<div class="card">
<div class="card-header table-primary">
<div class="row">
<div class="col-5">
<div class="d-flex justify-content-between">
<div class="px-2">
<h3><b>ODL</b></h3>
</div>
<div class="px-2">
<button class="btn btn-success" disabled="!@addEnabled" @onclick="() => reqNewPODL()">Nuovo ODL <i class="bi bi-plus-square"></i></button>
</div><div class="px-2">
<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="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="col-2">
</div>
<div class="col-5">
<div class="d-flex justify-content-between">
<div class="px-2">
<div class="form-check form-switch" title="Visualizzazione ODL Programmati / In Corso" style="padding-top: 3px">
@*<input class="form-check-input" type="checkbox" id="flexSwitchCheckDefault" @onclick="() => toggleCurrent()">*@
<button type="button" class="btn btn-primary btn-sm" @onclick="() => navToPODL()">PODL</button>
<label class="form-check-label" for="flexSwitchCheckDefault">Visualizza programmati</label>
</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="px-2">
<select @bind="@selStato" class="form-select">
<option value="*">--- Tutti ---</option>
@if (ListStati != null)
{
foreach (var item in ListStati)
{
<option value="@item.value">@item.label</option>
}
}
</select>
<div class="offcanvas-body">
<div>
<div>
Seleziona i filtri per:
</div>
</div>
<div>
<div class="small mt-2">
<label class="px-2" for="fase" title="Selezionare inizio periodo">Fase</label>
</div>
<div class="input-group px-2">
<label class="input-group-text" for="fase" title="Selezionare la fase da visualizzare"><i class="fa-solid fa-screwdriver-wrench"></i></label>
<select @bind="@selStato" id="fase" 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>
<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 macchina da visualizzare"><i class="fa-solid fa-hard-drive"></i></label>
<select @bind="@selMacchina" id="macchina" class="form-select" title="Selezionare la macchina da visualizzare">
<option value="*">--- Tutti ---</option>
@if (ListMacchine != null)
{
foreach (var item in ListMacchine)
{
<option value="@item">@item</option>
}
}
</select>
</div>
</div>
@if (!isActive)
{
<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>
}
</div>
</div>
</div>
</div>
@if (reqNew)
{
<div class="d-flex justify-content-around">
<div class="px-2">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Azienda</span>
<select @bind="@currAzienda" class="form-select">
@if (ListAziende != null)
{
foreach (var item in ListAziende.Where(x => x.CodGruppo != "*").ToList())
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
</select>
<span class="input-group-text" id="inputGroup-sizing-sm">Art Search</span>
<input type="text" class="form-control" aria-label="Art search" aria-describedby="inputGroup-sizing-sm">
</div>
</div>
</div>
<div class="d-flex justify-content-around">
<div class="px-2">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Articolo</span>
<select @bind="@currAzienda" class="form-select">
@if (ListAziende != null)
{
foreach (var item in ListAziende.Where(x => x.CodGruppo != "*").ToList())
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
</select>
</div>
</div>
</div>
}
else if (currRecordOdl != null)
{
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-primary text-light">Modifica ODL</div>
<div class="card-body">
@*<div class="row">
<div class="col-4">
<div class="input-group">
<span class="input-group-text">Codice</span>
<input type="text" class="form-control" placeholder="Articolo" @bind-value="@currRecord.CodArticolo">
</div>
</div>
<div class="col-4">
<div class="input-group">
<span class="input-group-text">Disegno</span>
<input type="text" class="form-control" placeholder="Disegno" @bind-value="@currRecord.Disegno">
</div>
</div>
<div class="col-1">
<div class="input-group" title="Tipo">
<select @bind="@currRecord.Tipo" class="form-select text-end">
@if (ListTipoArt != null)
{
foreach (var item in ListTipoArt)
{
<option value="@item.value">@item.label</option>
}
}
</select>
</div>
</div>
<div class="col-3">
<div class="input-group" title="Azienda">
<select @bind="@currRecord.Azienda" class="form-select text-end">
@if (ListAziende != null)
{
foreach (var item in ListAziende.Where(x => x.CodGruppo != "*").ToList())
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
</select>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-8">
<input type="text" class="form-control" placeholder="Descrizione Articolo" @bind-value="@currRecord.DescArticolo">
</div>
<div class="col-2">
<div class="d-grid gap-2">
<button class="btn btn-warning" @onclick="() => cancel()">Annulla <i class="bi bi-x-circle"></i></button>
</div>
</div>
<div class="col-2">
<div class="d-grid gap-2">
<button class="btn btn-success" @onclick="() => update(currRecord)">Salva <i class="bi bi-save"></i></button>
</div>
</div>
</div>*@
</div>
</div>
</div>
</div>
}
else if (currRecordPOdl != null)
{
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-primary text-light">Modifica PODL</div>
<div class="card-body">
@*<div class="row">
<div class="col-4">
<div class="input-group">
<span class="input-group-text">Codice</span>
<input type="text" class="form-control" placeholder="Articolo" @bind-value="@currRecord.CodArticolo">
</div>
</div>
<div class="col-4">
<div class="input-group">
<span class="input-group-text">Disegno</span>
<input type="text" class="form-control" placeholder="Disegno" @bind-value="@currRecord.Disegno">
</div>
</div>
<div class="col-1">
<div class="input-group" title="Tipo">
<select @bind="@currRecord.Tipo" class="form-select text-end">
@if (ListTipoArt != null)
{
foreach (var item in ListTipoArt)
{
<option value="@item.value">@item.label</option>
}
}
</select>
</div>
</div>
<div class="col-3">
<div class="input-group" title="Azienda">
<select @bind="@currRecord.Azienda" class="form-select text-end">
@if (ListAziende != null)
{
foreach (var item in ListAziende.Where(x => x.CodGruppo != "*").ToList())
{
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
</select>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-8">
<input type="text" class="form-control" placeholder="Descrizione Articolo" @bind-value="@currRecord.DescArticolo">
</div>
<div class="col-2">
<div class="d-grid gap-2">
<button class="btn btn-warning" @onclick="() => cancel()">Annulla <i class="bi bi-x-circle"></i></button>
</div>
</div>
<div class="col-2">
<div class="d-grid gap-2">
<button class="btn btn-success" @onclick="() => update(currRecord)">Salva <i class="bi bi-save"></i></button>
</div>
</div>
</div>*@
</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" />
</div>
</div>
+93 -117
View File
@@ -7,19 +7,66 @@ 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 = null!;
#endregion Protected Fields
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; }
protected bool isActive
{
get => currFilter.IsActive;
set => currFilter.IsActive = value;
}
[Inject]
protected MpDataService MDService { get; set; }
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MessageService MsgService { get; set; }
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected NavigationManager NavManager { get; set; }
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
@@ -35,6 +82,12 @@ namespace MP.SPEC.Pages
currPage = newNum;
}
protected override async Task OnInitializedAsync()
{
ListStati = await MDService.AnagStatiComm();
ListMacchine = await MDService.MacchineWithFlux(currFilter.DtStart, currFilter.DtEnd);
}
protected async Task pgResetReq(bool doReset)
{
if (doReset)
@@ -43,149 +96,72 @@ namespace MP.SPEC.Pages
}
}
private MP.Data.DatabaseModels.ODLModel? currRecordOdl = null;
private MP.Data.DatabaseModels.PODLModel? currRecordPOdl = null;
/// <summary>
/// Crea nuovo record e va in editing...
/// </summary>
/// <returns></returns>
protected async Task addNew()
protected void setDtMax()
{
currRecordPOdl = new MP.Data.DatabaseModels.PODLModel()
{
CodArticolo = $"_NEW_{DateTime.Now:yyyyMMdd.HHmmss}"
};
await Task.Delay(1);
// copio il filtro
currFilter.DtEnd = RoundDatetime(5);
currFilter.DtStart = RoundDatetime(5).AddDays(-1);
}
protected async Task cancel()
protected void UpdateTotCount(int newTotCount)
{
currRecordOdl = null;
currRecordPOdl = null;
await reloadData();
await Task.Delay(1);
totalCount = newTotCount;
}
protected DataPager pagerODL;
protected bool reqNew = false;
/// <summary>
/// Crea nuovo record e va in editing...
/// </summary>
/// <returns></returns>
protected async Task reqNewPODL()
{
reqNew = !reqNew;
await Task.Delay(1);
}
protected override async Task OnInitializedAsync()
{
// abilito ricerca...
MsgService.ShowSearch = true;
// resetto search
MsgService.SearchVal = "";
ListAziende = await MDService.ElencoAziende();
ListStati = await MDService.AnagStatiComm();
// carico dati
await reloadData();
}
private string currAzienda { get; set; } = "*";
private List<MP.Data.DatabaseModels.AnagGruppi>? ListAziende;
#endregion Protected Methods
#region Private Fields
private List<MP.Data.DatabaseModels.ListValues>? ListStati;
private List<string>? ListMacchine;
#endregion Private Fields
#region Private Properties
private SelectOdlParams currFilter { get; set; } = new SelectOdlParams();
private int currPage
{
get => MsgService.currPage;
set => MsgService.currPage = value;
get => currFilter.CurrPage;
set => currFilter.CurrPage = value;
}
private bool isLoading { get; set; } = false;
private int numRecord
private string leftStringCSS
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
get => isActive ? "text-secondary" : "text-dark fw-bold";
}
private int numRecord
{
get => currFilter.NumRec;
set => currFilter.NumRec = value;
}
private string rightStringCSS
{
get => isActive ? "text-dark fw-bold" : "text-secondary";
}
private string selStato { get; set; } = "*";
#if false
private string selStato
{
get => _selStato;
set
{
if (!_selStato.Equals(value))
{
_selStato = value;
addEnabled = selStato != "*";
////StateHasChanged();
//var pUpd = Task.Run(async () =>
//{
// //await reloadData();
// await Task.Delay(1);
// await InvokeAsync(() => StateHasChanged());
//});
//pUpd.Wait();
}
}
}
#endif
//private bool showODL { get; set; } = false;
private bool addEnabled = false;
//private string textToggle
//{
// get => showODL ? "In Corso" : "Programmati";
//}
get => currFilter.CodStato;
set => currFilter.CodStato = value;
}
private string selMacchina
{
get => currFilter.IdxMacchina;
set => currFilter.IdxMacchina = value;
}
private int totalCount
{
get => MsgService.totalCount;
set => MsgService.totalCount = value;
get => currFilter.TotCount;
set => currFilter.TotCount = value;
}
#endregion Private Properties
#region Private Methods
private async Task reloadData()
{
isLoading = true;
await Task.Delay(1);
isLoading = false;
}
//private async Task toggleCurrent()
//{
// //NavManager.NavigateTo("/PODL");
// showODL = !showODL;
// await Task.Delay(1);
//}
private async Task navToPODL()
{
NavManager.NavigateTo("/PODL");
//showODL = !showODL;
await Task.Delay(1);
}
#endregion Private Methods
}
}
+3 -5
View File
@@ -1,9 +1,9 @@
@page "/PARAMS"
<div class="card">
<div class="card mb-5">
<div class="card-header table-primary">
<div class="d-flex">
<div class="px-0">
<div class="px-0 py-1">
<h3><b>PARAMETERS</b></h3>
</div>
<div class="px-2 flex-fill">
@@ -25,12 +25,10 @@
}
else
{
<ListPARAMS SelFilter="@currFilter" TotRecordChanged="@updateTotal"></ListPARAMS>
<ListPARAMS SelFilter="@currFilter" TotRecordChanged="@UpdateTotCount" RecordSel="@detailSel"></ListPARAMS>
}
</div>
<div class="card-footer py-1">
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
+40 -18
View File
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using MP.Data.DatabaseModels;
using MP.SPEC.Components;
using MP.SPEC.Data;
@@ -14,8 +15,6 @@ namespace MP.SPEC.Pages
#region Protected Properties
[Inject]
protected MessageService MsgService { get; set; } = null!;
#endregion Protected Properties
@@ -29,7 +28,12 @@ namespace MP.SPEC.Pages
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
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();
}
@@ -37,9 +41,6 @@ namespace MP.SPEC.Pages
{
isLoading = true;
isFiltering = true;
// disabilito ricerca...
MsgService.SearchVal = "";
MsgService.ShowSearch = false;
// fix pagina
await Task.Delay(1);
var modFilter = currFilter;
@@ -63,30 +64,48 @@ 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();
private int currPage
{
get => MsgService.currPage;
set => MsgService.currPage = value;
get => currFilter.CurrPage;
set => currFilter.CurrPage = value;
}
private bool isLoading { get; set; } = true;
private bool isFiltering { get; set; } = false;
private bool isLoading { get; set; } = true;
private int numRecord
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
get => currFilter.NumRec;
set => currFilter.NumRec = value;
}
private int totalCount { get; set; } = 0;
@@ -104,7 +123,7 @@ namespace MP.SPEC.Pages
if (newParams.CurrPage == 0)
{
newParams.CurrPage = 1;
newParams.LiveUpdate = false;
//newParams.LiveUpdate = false;
}
else
{
@@ -115,7 +134,10 @@ namespace MP.SPEC.Pages
currFilter = newParams;
isLoading = false;
}
protected void UpdateTotCount(int newTotCount)
{
totalCount = newTotCount;
}
#endregion Private Methods
}
}
+50 -31
View File
@@ -1,10 +1,10 @@
@page "/PODL"
<div class="card">
<div class="card mb-5">
<div class="card-header table-primary">
<div class="row">
<div class="col-6">
<div class="d-flex justify-content-between">
<div class="col-6 col-lg-8">
<div class="d-flex">
<div class="px-2">
<h3><b>P</b>romesse <b>ODL</b></h3>
@@ -17,10 +17,10 @@
</div>
</div>
</div>
<div class="col-3">
<div class="col-6 col-lg-4">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Azienda</span>
<select @bind="@currAzienda" class="form-select">
@*<label class="input-group-text" for="maxRecord" title="Selezionare l'azienda da visualizzare"><i class="fa-solid fa-industry"></i></label>
<select @bind="@currAzienda" class="form-select" title="Selezionare l'azienda da visualizzare">
@if (ListAziende != null)
{
foreach (var item in ListAziende)
@@ -28,32 +28,27 @@
<option value="@item.CodGruppo">@item.DescrGruppo</option>
}
}
</select>*@
<label class="input-group-text" for="maxRecord" title="Selezionare la fase da visualizzare"><i class="fa-solid fa-screwdriver-wrench"></i></label>
<select @bind="@currFase" 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>
<div class="col-3">
<div class="d-flex text-end">
<div class="input-group input-group-sm">
<span class="input-group-text" id="inputGroup-sizing-sm">Fase</span>
<select @bind="@selStato" class="form-select">
<option value="*">--- Tutti ---</option>
@if (ListStati != null)
{
foreach (var item in ListStati)
{
<option value="@item.value">@item.label</option>
}
}
</select>
</div>
</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">
@@ -82,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">
@@ -99,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">
@@ -134,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>
@@ -200,13 +222,10 @@
}
else
{
<ListPODL PagerResetReq="pgResetReq" RecordSel="@selRecord"></ListPODL>
<ListPODL PagerResetReq="pgResetReq" RecordSel="@selRecord" updateRecordCount="UpdateTotCount" actFilter="@currFilter"></ListPODL>
}
</div>
<div class="card-footer py-1">
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="@isLoading" />
</div>
</div>
</div>
+60 -23
View File
@@ -3,6 +3,8 @@ using Microsoft.JSInterop;
using MP.Data.DatabaseModels;
using MP.SPEC.Components;
using MP.SPEC.Data;
using MP.SPEC.Services;
using NLog;
namespace MP.SPEC.Pages
{
@@ -10,7 +12,7 @@ namespace MP.SPEC.Pages
{
#region Protected Fields
protected DataPager pagerODL;
protected DataPager pagerODL = null!;
protected bool reqNew = false;
@@ -19,16 +21,16 @@ namespace MP.SPEC.Pages
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; }
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MpDataService MDService { get; set; }
protected MpDataService MDService { get; set; } = null!;
[Inject]
protected MessageService MsgService { get; set; }
protected IOApiService MpIoApiCall { get; set; } = null!;
[Inject]
protected NavigationManager NavManager { get; set; }
protected NavigationManager NavManager { get; set; } = null!;
#endregion Protected Properties
@@ -66,10 +68,6 @@ namespace MP.SPEC.Pages
protected override async Task OnInitializedAsync()
{
// abilito ricerca...
MsgService.ShowSearch = true;
// resetto search
MsgService.SearchVal = "";
ListAziende = await MDService.ElencoAziende();
ListGruppiFase = await MDService.ElencoGruppiFase();
ListMacchine = await MDService.MacchineGetAll();
@@ -106,7 +104,7 @@ namespace MP.SPEC.Pages
var firstArt = ListArticoli.FirstOrDefault();
currArticolo = firstArt != null ? firstArt.CodArticolo : "";
}
string codExt = $"{selStato}";
string codExt = $"{currFase}";
string codGruppo = "";
if (ListGruppiFase != null && ListGruppiFase.Count > 0)
{
@@ -150,15 +148,25 @@ namespace MP.SPEC.Pages
return;
await Task.Delay(1);
var done = await MDService.POdlUpdateRecord(selRec);
await callSyncDb(selRec);
currRecord = null;
await reloadData();
// forzo update parametri
await Task.Delay(1);
currFase = "*";
await Task.Delay(1);
}
protected void UpdateTotCount(int newTotCount)
{
totalCount = newTotCount;
}
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private PODLModel? _currRecord = null;
private List<AnagArticoli>? ListArticoli;
private List<AnagGruppi>? ListAziende;
@@ -175,7 +183,7 @@ namespace MP.SPEC.Pages
private bool addEnabled
{
get => selStato != "*";
get => currFase != "*";
}
private string artSearch
@@ -220,10 +228,25 @@ namespace MP.SPEC.Pages
}
}
private string currFase
{
get => currFilter.CodFase;
set
{
if (!currFilter.CodFase.Equals(value))
{
currFilter.CodFase = value;
currPage = 1;
}
}
}
private SelectPOdlParams currFilter { get; set; } = new SelectPOdlParams();
private int currPage
{
get => MsgService.currPage;
set => MsgService.currPage = value;
get => currFilter.CurrPage;
set => currFilter.CurrPage = value;
}
private PODLModel? currRecord
@@ -240,26 +263,40 @@ namespace MP.SPEC.Pages
private int numRecord
{
get => MsgService.numRecord;
set => MsgService.numRecord = value;
}
private string selStato
{
get => MsgService.StateSel;
set => MsgService.StateSel = value;
get => currFilter.NumRec;
set => currFilter.NumRec = value;
}
private int totalCount
{
get => MsgService.totalCount;
set => MsgService.totalCount = value;
get => currFilter.TotCount;
set => currFilter.TotCount = value;
}
#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=";
try
{
var response = await MpIoApiCall.callMpIoUrlGet(restUrl);
}
catch (Exception exc)
{
Log.Error($"Errore durante chiamata: {Environment.NewLine}{exc}");
}
}
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 {
}
+10
View File
@@ -0,0 +1,10 @@
@page "/Utils"
@using MP.SPEC.Components
@using MP.SPEC.Data
<h3>Utils</h3>
<div class="">
<button class="btn btn-primary" @onclick="() => flushCache()"> Flush Cache </button>
</div>
+30
View File
@@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Components;
using MP.SPEC.Data;
namespace MP.SPEC.Pages
{
public partial class Utils
{
#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/chartBoot.js"></script>
<script src="lib/modalHandler.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"
}
}
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
<body>
<i>Modulo MON MAPO</i>
<i>Modulo MAPOSPEC </i>
<h4>Versione: {{CURRENT-REL}}</h4>
<br /> Note di rilascio:
<ul>
@@ -19,7 +19,7 @@
<img src="logoSteamware.png" />
</div>
<div style="float: right;">
<a href="https://www.steamware.net/IOT" target="_blank">&copy; Steamware 2006-2021</a>
<a href="https://www.steamware.net/IOT" target="_blank">&copy; Steamware 2006-2022</a>
</div>
</div>
</body>
+3 -3
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MON MAPO</i>
<h4>Versione: 6.15.2207.2109</h4>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 6.16.2210.2014</h4>
<br /> Note di rilascio:
<ul>
<li>
@@ -19,7 +19,7 @@
<img src="logoSteamware.png" />
</div>
<div style="float: right;">
<a href="https://www.steamware.net/IOT" target="_blank">&copy; Steamware 2006-2021</a>
<a href="https://www.steamware.net/IOT" target="_blank">&copy; Steamware 2006-2022</a>
</div>
</div>
</body>

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