Merge branch 'Release/MpTab3_04'

This commit is contained in:
Samuele Locatelli
2025-04-07 12:14:36 +02:00
74 changed files with 2497 additions and 456 deletions
+15 -9
View File
@@ -1,4 +1,4 @@
<div class="top-row d-flex justify-content-between text-light">
<div class="top-row d-flex justify-content-between text-light @CssReload">
<div class="col-4 d-flex">
<div class="pe-1">
<button class="btn btn-sm @ResetClass" @onclick="() => ForceReload()" title="Update"><i class="fa-solid fa-rotate"></i></button>
@@ -9,20 +9,26 @@
</div>
</div>
<div class="col-4 text-center d-flex justify-content-center px-0">
<div class="btn btn-outline-info p-1 text-decoration-none text-light" @onclick="()=>backToSM()">
<div class="btn btn-outline-info py-1 px-2 text-decoration-none text-light" @onclick="()=>backToSM()">
<i class="fa-solid fa-house"></i>
MapoTAB3
<img src="images/LogoSteamware.png" style="height: 1.3rem" />
</div>
</div>
<div class="col-4 text-end">
@if (!HideMenu)
{
<div class="row w-100 slideMen">
<div class="p-0">
<SlideMenu MenuItems="@CurrMenuItems"></SlideMenu>
<div class="d-flex flex-row-reverse">
@if (!HideMenu)
{
<div class="px-1 slideMen">
<span class="p-0">
<SlideMenu MenuItems="@CurrMenuItems"></SlideMenu>
</span>
</div>
</div>
}
}
@if (IsReloading)
{
<div class="px-1 text-nowrap">Reloading User Data...</div>
}
</div>
</div>
</div>
+15 -6
View File
@@ -71,20 +71,28 @@ namespace MP_TAB3.Components
protected async Task backToSM()
{
await Task.Delay(1);
if (!NavMan.Uri.Contains("reg-new-device"))
{
await MsgServ.IdxMaccSet("");
NavMan.NavigateTo("status-map", true);
NavMan.NavigateTo("status-map", false);
}
}
private bool IsReloading = false;
private string CssReload
{
get => IsReloading ? "bg-primary bg-gradient" : "";
}
protected async Task ForceReload()
{
Stopwatch sw = new Stopwatch();
sw.Start();
Log.Info("Start ForceReload");
IsReloading = true;
ResetClass = "btn-warning";
MsgServ.IsReloading = true;
await InvokeAsync(StateHasChanged);
var currToken = await MsgServ.GetCurrOperDtoLSAsync();
var lastOpr = await MsgServ.GetLastMatrOprAsync();
@@ -102,14 +110,15 @@ namespace MP_TAB3.Components
await EA_ReloadMStor.InvokeAsync(true);
// calcolo tempo esecuzione
sw.Stop();
int delta = 500 - (int)sw.ElapsedMilliseconds;
delta = delta > 0 ? delta : 50;
int delta = 150 - (int)sw.ElapsedMilliseconds;
delta = delta > 0 ? delta : 10;
await Task.Delay(delta);
ResetClass = "btn-primary";
// await InvokeAsync(StateHasChanged);
MsgServ.IsReloading = false;
IsReloading = false;
Log.Info($"ForceReload completed in {sw.Elapsed.TotalMilliseconds}ms");
// ricarica pagina!
NavMan.NavigateTo("status-map");
NavMan.NavigateTo("status-map", true);
}
protected override async Task OnInitializedAsync()
+216
View File
@@ -0,0 +1,216 @@
<div class="row my-1 mx-0 rounded-3" style="background-color: #34495E; ">
<div class="col-12 px-1">
<CalendarMonth DtRif="@dtCurr" MainCss="table table-dark table-borderless" DateSelected="DisplayDate" MonthChanged="ReloadMonth" DateCheck="@DateCheck" DateCheckBlock="@DateCFF" SingleWeek="@showDetail" SelDayCss="selDate rounded-top p-2" HeadStyle="color: #E67E22"></CalendarMonth>
</div>
@if (showDetail)
{
<div class="col-12 px-1 bg-gradient py-2">
@if (EditRecord == null)
{
<div class="row">
@if (DayMinTot < 1440)
{
<div class="col-3 my-2 pe-1">
<button class="btn btn-success w-100" @onclick="() => AddNew(true)" title="Inserisci produzione"><i class="fa-solid fa-plus"></i> Prod</button>
</div>
<div class="col-3 my-2 px-1">
<button class="btn btn-warning w-100" @onclick="() => AddNew(false)" title="Inserisci Fermata"><i class="fa-solid fa-plus"></i> Fermata</button>
</div>
<div class="col-3 my-2 px-1">
<button class="btn btn-secondary w-100" @onclick="() => FixMissing()" title="Riempi periodi mancanti"><i class="fa-solid fa-fill-drip"></i> Spenta</button>
</div>
}
else
{
@if (DayImportRatio != 1)
{
<div class="col-3 my-2 pe-1">
<button class="btn btn-success w-100" @onclick="() => FreezeDay()" title="Conferma giornata"><i class="fa-solid fa-stamp"></i> Conferma</button>
</div>
}
else
{
<div class="col-3 my-2">
<div class="rounded-3 py-2 px-3 text-center bg-dark w-100 bg-gradient"><i class="fa-solid fa-square-check text-success"></i> Conferma OK</div>
</div>
}
<div class="col-6 my-2 px-1">
</div>
}
<div class="col-3 my-2 ps-1">
<button class="btn btn-outline-light w-100" @onclick="@CloseDet"><i class="fa-solid fa-xmark"></i> Close</button>
</div>
</div>
@if (SeqStatus != null && SeqStatus.Count() > 0)
{
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between fs-4">
<div class="px-1">Prod: @($"{DayMinLav:N1}") min (@($"{DayOee:P0}"))</div>
<div class="px-1">Copert: @($"{DayMinTot:N0}") min</div>
</div>
</div>
<div class="col-12">
<div class="progress" style="min-height: 3.5rem;">
@foreach (var item in SeqStatus)
{
<div class="progress-bar @item.CssBlock" style="width: @($"{item.ValuePerc:P0}");">
<div>@item.Title</div>
<small>@($"{item.Value:N0}min")</small>
</div>
}
</div>
</div>
</div>
}
}
else
{
<div class="row mx-0 bg-dark bg-gradient">
<div class="col-6 mt-2">
<button class="btn btn-warning w-100" @onclick="() => DoCancel()"><i class="fa-solid fa-ban"></i> Cancel</button>
</div>
<div class="col-6 mt-2">
<button class="btn btn-success w-100" @onclick="() => DoSave()"><i class="fa-solid fa-floppy-disk"></i> Save</button>
</div>
<div class="col-12 my-2">
@if (EditRecord.IsWork)
{
@if (doSearchArt)
{
<dialog class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog">
<div class="modal-dialog modal-xl">
<div class="modal-content p-2">
<div class="modal-title d-flex justify-content-between">
<div class="px-0">
<h3>Selezione Articoli da ricerca</h3>
</div>
<div class="px-0">
<button class="btn btn-outline-dark" @onclick="() => SearchArtToggle()"><i class="fa-solid fa-xmark"></i></button>
</div>
</div>
<div class="modal-body">
<SelectCodArt SearchMinChar="3" E_CodArt="SetArtSelected"></SelectCodArt>
</div>
</div>
</div>
</dialog>
}
<div class="row">
<div class="col-6 col-lg-3 my-2">
<div class="form-floating">
<input type="text" class="form-control" @bind="@EditRecord.KeyRichiesta"></input>
<label>Commessa</label>
</div>
</div>
<div class="col-6 col-lg-3 my-2">
<div class="input-group">
<div class="form-floating">
<input type="text" class="form-control" @bind="@EditRecord.CodArticolo"></input>
<label>Articolo</label>
</div>
<button class="btn btn-success" @onclick="() => SearchArtToggle()"><i class="fa-brands fa-searchengin fa-2x"></i></button>
</div>
</div>
<div class="col-6 col-lg-2 my-2">
<div class="form-floating">
<input type="time" class="form-control" @bind="@EditRecord.InizioStato"></input>
<label for="floatingComm">Inizio</label>
</div>
</div>
<div class="col-3 col-lg-2 my-2">
<div class="form-floating">
<input type="number" class="form-control" @bind="@EditRecord.PzBuoni" step="1"></input>
<label for="floatingComm">Pezzi</label>
</div>
</div>
<div class="col-3 col-lg-2 my-2">
<div class="form-floating">
<select @bind="@EditRecord.TCiclo" class="form-select">
@foreach (var item in ListTCiclo)
{
<option value="@item.value">@item.label</option>
}
</select>
<label for="floatingComm">T.Ciclo</label>
</div>
</div>
</div>
}
else
{
<div class="row">
<div class="col-12">
<div class="form-floating">
<select @bind="@EditRecord.IdxTipoEv" class="form-select">
@foreach (var item in ListEvents)
{
<option value="@item.value">@item.label</option>
}
</select>
<label>Tipo Fermata</label>
</div>
</div>
<div class="col-6 my-2">
<div class="form-floating">
<input type="time" class="form-control" @bind="@EditRecord.InizioStato"></input>
<label for="floatingComm">Inizio</label>
</div>
</div>
<div class="col-6 my-2">
<div class="form-floating">
<input type="number" id="minProd" name="minProd" class="form-control" @bind="@EditRecord.MinProd" step="0.1" placeholder="0.0" min="0" max="1440"></input>
<label for="floatingComm">Durata (min)</label>
</div>
</div>
</div>
}
</div>
</div>
}
</div>
<div class="col-12 px-1">
<table class="table table-dark table-sm table-striped">
<thead>
<tr>
<th></th>
<th>Macc</th>
<th>Stato</th>
<th>Art.</th>
<th>Ora</th>
<th class="text-end">Pezzi #</th>
<th class="text-end">T.Ciclo</th>
<th class="text-end">Minuti</th>
<th class="text-end"></th>
</tr>
</thead>
<tbody>
@foreach (var item in ListDay)
{
<tr>
<td><button class="btn btn-sm btn-primary" @onclick="() => DoEdit(item)"><i class="fa-solid fa-pen"></i></button></td>
<td>@item.IdxMacchina</td>
<td>@(EvDescript(item.IdxTipoEv))</td>
<td>
@item.CodArticolo
@if (!string.IsNullOrEmpty(item.KeyRichiesta))
{
<small>@item.KeyRichiesta</small>
}
</td>
<td title="@($"{item.InizioStato:yyyy.MM.dd HH:mm:ss} --> {item.FineStato:yyyy.MM.dd HH:mm:ss}")">@($"{item.InizioStato:HH:mm}")</td>
<td class="text-end">@item.PzBuoni</td>
<td class="text-end">@($"{item.TCiclo:f2}")</td>
<td class="text-end">@($"{item.MinProd:f2}")</td>
<td class="text-end"><button class="btn btn-sm btn-danger" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash-can"></i></button></td>
</tr>
}
</tbody>
</table>
</div>
<div class="col-12 px-1">
</div>
}
</div>
+483
View File
@@ -0,0 +1,483 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MP.Core.DTO;
using MP.Data.DbModels;
using MP.Data.Services;
using MP_TAB3.Pages;
using NLog;
using System.Net.Security;
using static MP_TAB3.Components.ProdAdvDispl;
namespace MP_TAB3.Components
{
public partial class InsManual
{
#region Public Properties
[Parameter]
public MappaStatoExpl? RecMSE
{
get => currRecMSE;
set
{
// salvo SOLO SE non sono in conferma
if (!confProdActive)
{
currRecMSE = value;
}
}
}
#endregion Public Properties
#region Protected Properties
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected TabDataService TabDServ { get; set; } = null!;
#endregion Protected Properties
/// <summary>
/// Boolear controllo visualizzazione ricerca articoli
/// </summary>
private bool doSearchArt = false;
private void SearchArtToggle()
{
doSearchArt = !doSearchArt;
}
/// <summary>
/// Salva selezione articolo
/// </summary>
/// <param name="codArt"></param>
private void SetArtSelected(string codArt)
{
if (EditRecord != null)
{
EditRecord.CodArticolo = codArt;
doSearchArt = false;
}
}
#region Protected Methods
protected void AddNew(bool isWork)
{
if (RecMSE != null)
{
string idxMacc = RecMSE.IdxMacchina;
DateTime startPeriod = dtCurr.Date;
if (ListDay != null)
{
var lastRec = ListDay.LastOrDefault();
if (lastRec != null && lastRec.FineStato.HasValue)
{
startPeriod = lastRec.FineStato.Value;
}
else
{
startPeriod = dtCurr.Date.AddHours(6);
}
}
// evento da richiesta: default lavora/spenta
int idxTipo = isWork ? 1 : 12;
// creazione nuovo record ed aggiunta in coda agli esistenti...
EditRecord = new InsManualiModel()
{
IdxMacchina = idxMacc,
InizioStato = startPeriod,
IdxTipoEv = idxTipo,
MatrOpr = MServ.MatrOpr
};
}
}
/// <summary>
/// impossta record x eliminazione
/// </summary>
/// <param name="selRec"></param>
protected async Task DoDelete(InsManualiModel selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler eliminare il record tipo {selRec.IdxTipoEv} | {selRec.InizioStato:yyyy.MM.dd HH:mm} per {selRec.MinProd:N2} min?"))
return;
// esegue eliminazione del record...
await TabDServ.InsManDelete(selRec);
// rileggo i dati...
ReloadData();
RecalcDayData(dtCurr);
}
/// <summary>
/// imposta record x editing
/// </summary>
/// <param name="selRec"></param>
protected void DoEdit(InsManualiModel? selRec)
{
doSearchArt = false;
EditRecord = selRec;
}
/// <summary>
/// Annulla editing
/// </summary>
/// <param name="selRec"></param>
protected void DoCancel()
{
doSearchArt = false;
EditRecord = null;
ReloadData();
RecalcDayData(dtCurr);
}
protected async Task DoSave()
{
doSearchArt = false;
// solo se ho record...
if (EditRecord != null)
{
// sistemo i dati...
var dayElap = EditRecord.InizioStato.Subtract(EditRecord.InizioStato.Date);
EditRecord.MatrOpr = MServ.MatrOpr;
EditRecord.InizioStato = dtCurr.Date.Add(dayElap);
// imposto altri campi secondo il TIPO di record...
if (EditRecord.IsWork)
{
EditRecord.MinProd = EditRecord.TCiclo * EditRecord.PzBuoni;
}
else
{
EditRecord.PzBuoni = 0;
EditRecord.TCiclo = 0;
}
EditRecord.FineStato = EditRecord.InizioStato.AddMinutes((double)EditRecord.MinProd);
// lancio salvataggio sul DB
await TabDServ.InsManUpsert(EditRecord);
// rileggo i dati...
ReloadData();
if (!IsTimeInfoOk(dtCurr, false))
{
int numChange = await DoRecalcDay();
}
// rileggo i dati...
ReloadData();
RecalcDayData(dtCurr);
EditRecord = null;
}
}
/// <summary>
/// traduzione evento da lista...
/// </summary>
/// <param name="idxTipoEv"></param>
/// <returns></returns>
protected string EvDescript(int idxTipoEv)
{
string answ = "-";
if (ListEvents != null)
{
var rSel = ListEvents.FirstOrDefault(x => x.value == idxTipoEv);
if (rSel != null)
{
answ = rSel.label;
}
}
return answ;
}
protected async Task FixMissing()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler riempire i periodi mancanti?"))
return;
// filtra dati odierni x tab editabile...
if (ListPeriod != null && ListPeriod.Count > 0)
{
// chiamo insert con eventi spenta (12) HardCoded...
int numAdd = await TabDServ.InsManFillMissing(ListDay, 12, MServ.MatrOpr);
// rileggo i dati...
ReloadData();
RecalcDayData(dtCurr);
}
}
protected override async Task OnParametersSetAsync()
{
ReloadData();
await Task.Delay(1);
}
#endregion Protected Methods
#region Private Fields
private Dictionary<DateTime, string> DateCFF = new Dictionary<DateTime, string>();
/// <summary>
/// Lista date + css associato x display calendario
/// </summary>
private Dictionary<DateTime, string> DateCheck = new Dictionary<DateTime, string>();
/// <summary>
/// Minuti lavorati (da sequencer)
/// </summary>
private double DayMinLav = 0;
/// <summary>
/// Minuti caricati (da sequencer)
/// </summary>
private double DayMinTot = 0;
/// <summary>
/// % record importati
/// </summary>
private double DayImportRatio = 0;
/// <summary>
/// OEE giornaliero (ore lav / 24h)
/// </summary>
private double DayOee = 0;
private InsManualiModel? EditRecord = null;
private List<ManualStatusDTO> SeqStatus = new List<ManualStatusDTO>();
#endregion Private Fields
#region Private Properties
private bool confProdActive { get; set; } = false;
private MappaStatoExpl? currRecMSE { get; set; } = null;
private DateTime dtCurr { get; set; } = DateTime.Today;
private List<InsManualiModel>? ListDay { get; set; } = new List<InsManualiModel>();
private List<InsManDayDto>? ListDTO { get; set; } = new List<InsManDayDto>();
/// <summary>
/// Eventi inseribili come fermate
/// </summary>
private List<vSelEventiBCodeModel> ListEvents { get; set; } = new List<vSelEventiBCodeModel>();
/// <summary>
/// Eventi inseribili come fermate
/// </summary>
private List<ListValues> ListTCiclo { get; set; } = new List<ListValues>();
private List<InsManualiModel>? ListPeriod { get; set; } = new List<InsManualiModel>();
private bool showDetail { get; set; } = false;
#endregion Private Properties
#region Private Methods
private void CloseDet()
{
showDetail = false;
}
private void DisplayDate(DateTime dtSel)
{
dtCurr = dtSel;
showDetail = true;
RecalcDayData(dtSel);
}
/// <summary>
/// Ricalcolo dati giornalieri
/// </summary>
/// <returns></returns>
private async Task<int> DoRecalcDay()
{
int numChange = 0;
// prendo i dati odierni, e uno x uno ciclo e sistemo...
DateTime lastDate = dtCurr.Date;
List<InsManualiModel> ListChange = new List<InsManualiModel>();
if (ListDay != null && ListDay.Count > 0)
{
foreach (var item in ListDay)
{
bool isFirst = lastDate.TimeOfDay == new TimeSpan(0);
if ((item.InizioStato < lastDate && isFirst) || (item.InizioStato != lastDate && !isFirst))
{
item.InizioStato = lastDate;
}
// controllo se la data fine ok...
if (!item.FineStato.HasValue || Math.Abs(item.InizioStato.AddMinutes((double)item.MinProd).Subtract(item.FineStato.Value).TotalMinutes) > 1)
{
item.FineStato = item.InizioStato.AddMinutes((double)item.MinProd);
item.MatrOpr = MServ.MatrOpr;
numChange++;
ListChange.Add(item);
}
lastDate = item.FineStato.Value;
}
// salvo tutto
await TabDServ.InsManUpsert(ListChange);
}
return numChange;
}
private bool IsTimeInfoOk(DateTime reqDate, bool reloadDay)
{
bool allOk = false;
List<InsManualiModel> myListDay = new List<InsManualiModel>();
if (ListDTO != null)
{
var dayDto = ListDTO.FirstOrDefault(x => x.DataRif == reqDate.Date);
if (dayDto != null && (ListDay != null || (reloadDay && ListPeriod != null)))
{
if (reloadDay)
{
// calcolo eventi giorno
myListDay = ListPeriod
.Where(x => x.InizioStato.Date == reqDate)
.OrderBy(x => x.InizioStato)
.ThenBy(x => x.IdxInsMan)
.ToList();
}
else
{
myListDay = ListDay;
}
var firstRec = myListDay.OrderBy(x => x.InizioStato).FirstOrDefault();
var lastRec = myListDay.OrderByDescending(x => x.InizioStato).FirstOrDefault();
var deltaMins = lastRec!.FineStato!.Value.Subtract(firstRec!.InizioStato).TotalMinutes;
allOk = Math.Abs(deltaMins - (double)dayDto.MinProdTot) < 1;
}
}
return allOk;
}
/// <summary>
/// Congela la definizione giornaliera di produzione
/// </summary>
/// <returns></returns>
private async Task FreezeDay()
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler confermare gli eventi della giornata? i valori non saranno più modificabili."))
return;
// esegue stored
bool fatto = false;
if (RecMSE != null)
{
string IdxMacc = RecMSE.IdxMacchina;
fatto = await TabDServ.InsManFreezeDay(IdxMacc, dtCurr);
}
return;
}
/// <summary>
/// Ricalcola dati giornalieri
/// </summary>
/// <param name="dtSel"></param>
private void RecalcDayData(DateTime dtSel)
{
// filtra dati odierni x tab editabile...
if (ListPeriod != null && ListPeriod.Count > 0)
{
// calcolo eventi giorno
ListDay = ListPeriod
.Where(x => x.InizioStato.Date == dtSel)
.OrderBy(x => x.InizioStato)
.ThenBy(x => x.IdxInsMan)
.ToList();
// ora calcolo il sequencer x mostrare dettaglio orario...
SeqStatus = TabDServ.InsManSeqDayStatus(ListDay);
// calcolo min lavorati odierni
DayMinLav = 0;
var recLav = SeqStatus.FirstOrDefault(x => x.IdxTipo == 1);
if (recLav != null)
{
DayMinLav = recLav.Value;
DayOee = recLav.ValuePerc;
}
// minuti totali come record day...
DayMinTot = (double)ListDay.Sum(x => x.MinProd);
if (dtSel.Date == dtCurr.Date && ListDTO != null)
{
var dayDto = ListDTO.FirstOrDefault(x => x.DataRif == dtSel.Date);
if (dayDto != null)
{
DayImportRatio = dayDto.RatioImport;
}
}
}
}
private void ReloadData()
{
// rileggo dati periodo...
ListDTO = new List<InsManDayDto>();
if (RecMSE != null)
{
string IdxMacc = RecMSE.IdxMacchina;
// valori selezionabili x TCiclo
ListTCiclo = TabDServ.ListValuesFilt("InsManuali", IdxMacc);
// eventi fermate
var eventsAll = TabDServ.AnagEventiGetByMacch(IdxMacc);
if (eventsAll != null)
{
ListEvents = eventsAll.Where(x => x.EventoTablet).ToList();
}
DateTime MeseStart = new DateTime(dtCurr.Year, dtCurr.Month, 1);
DateTime MeseEnd = MeseStart.AddMonths(1);
ListPeriod = TabDServ.InsManFilt(IdxMacc, MeseStart, MeseEnd);
ListDTO = TabDServ.InsManDayDto(ListPeriod);
DateCheck = new Dictionary<DateTime, string>();
DateCFF = new Dictionary<DateTime, string>();
string cssImport = "bg-success text-light rounded-circle p-2";
string cssOkDay = "bg-success bg-opacity-50 text-light rounded-circle p-2";
string cssPartDay = "bg-info bg-opacity-25 text-light rounded-circle p-2";
string cssHasData = "bg-warning text-light rounded-circle p-2";
string cssToday = "bg-info text-dark rounded-circle p-2";
string cssFest = "bg-danger text-warning rounded-pill2 px-0 opacity-50";
string cssChius = "bg-warning text-dark rounded-pill2 px-0 opacity-50";
string cssFerie = "bg-success text-light px-0 opacity-50";
if (ListDTO != null)
{
string currCss = "";
foreach (var item in ListDTO)
{
currCss = "";// item.MinProdTot == 0 ? "" : cssHasData;
// controllo minuti dichiarati...
if (item.RatioImport == 1)
{
currCss = cssImport;
}
else if (item.DataRif == DateTime.Today)
{
currCss = cssToday;
}
else if (IsTimeInfoOk(item.DataRif.Date, true))
{
currCss = item.MinProdTot < 1440 ? cssPartDay : cssOkDay;
}
else
{
currCss = item.MinProdTot == 0 ? "" : cssHasData;
}
DateCheck.Add(item.DataRif, currCss);
}
}
}
}
private async Task ReloadMonth(DateTime dtSel)
{
dtCurr = dtSel;
ReloadData();
await Task.Delay(1);
}
#endregion Private Methods
}
}
+13 -1
View File
@@ -21,7 +21,11 @@ else
<div class="card-img-overlay p-0 d-flex flex-row-reverse align-items-start">
<div class="labelTop px-2 w-100">
<div class="text-center fs-2 fw-bold">
@CRecMSE.Nome
@CRecMSE.Nome
@if(isManual)
{
<i class="ps-1 text-light fs-3 fa-solid fa-puzzle-piece"></i>
}
</div>
</div>
</div>
@@ -86,6 +90,10 @@ else
<div class="labelTop px-2 py-0 w-100">
<div class="text-center fs-2 fw-bold">
@CRecMSE.Nome
@if (isManual)
{
<i class="ps-1 text-light fs-3 fa-solid fa-puzzle-piece"></i>
}
</div>
</div>
</div>
@@ -151,6 +159,10 @@ else
<div class="col-12">
<h4 class="text-center mb-0 fw-bold">
@CRecMSE.Nome
@if (isManual)
{
<i class="ps-1 text-light fs-3 fa-solid fa-puzzle-piece"></i>
}
</h4>
</div>
<div class="col-4 fs-4">
+43 -16
View File
@@ -34,6 +34,7 @@ namespace MP_TAB3.Components
private bool inAttr = false;
private bool isLoading = false;
private bool isMulti = false;
private bool isManual = false;
private bool LastFullMode = true;
private string LastIdxMacchSub = "";
private int LastKeepAliveMin = 5;
@@ -147,10 +148,14 @@ namespace MP_TAB3.Components
get
{
string answ = "text-nowrap";
try
{
if (RecMSE != null && RecMSE.DescrizioneStato.Length >= 17)
{
answ = " scroll-left";
}
}
catch { }
return answ;
}
}
@@ -316,14 +321,17 @@ namespace MP_TAB3.Components
/// <returns></returns>
public string ImgUrlMacc(string url)
{
if (string.IsNullOrEmpty(imgBasePath))
{
// se configurata uso cartella virtuale... altrimenti cartella processo
string baseUrl = config.GetValue<string>("SpecialConf:AppUrl") ?? (config.GetValue<string>("OptConf:AppUrl") ?? "");
imgBasePath = $"{baseUrl}/macchine";
}
if (string.IsNullOrEmpty(url.ToString()))
{
url = "Steamware.png";
}
string fullPath = $"{imgBasePath}/{url}";
#if false
string fullPath = Path.Combine(imgBasePath, url);
#endif
return fullPath;
}
@@ -360,17 +368,6 @@ namespace MP_TAB3.Components
TabDServ.ConfigGetVal("TAB_ShowQtaExtra", ref showQtaExtra);
await ReloadXDL(true);
// se configurata uso cartella virtuale... altrimenti cartella processo
#if false
var sImgBasePath = config.GetValue<string>("ServerConf:ImgBasePath") ?? (config.GetValue<string>("OptConf:ImgBasePath") ?? "");
if (!string.IsNullOrEmpty(sImgBasePath))
{
imgBasePath = sImgBasePath;
}
else
{
imgBasePath = $"{Environment.CurrentDirectory}/images/";
}
#endif
string baseUrl = config.GetValue<string>("SpecialConf:AppUrl") ?? (config.GetValue<string>("OptConf:AppUrl") ?? "");
imgBasePath = $"{baseUrl}/macchine";
await loadDetails();
@@ -381,6 +378,12 @@ namespace MP_TAB3.Components
{
// controllo variazione parametri...
string lastIMS = LastIdxMacchSub;
if (string.IsNullOrEmpty(imgBasePath))
{
// se configurata uso cartella virtuale... altrimenti cartella processo
string baseUrl = config.GetValue<string>("SpecialConf:AppUrl") ?? (config.GetValue<string>("OptConf:AppUrl") ?? "");
imgBasePath = $"{baseUrl}/macchine";
}
if (paramsChanged())
{
saveParams();
@@ -422,9 +425,14 @@ namespace MP_TAB3.Components
TabDServ.DataInvalidated -= TabDServ_DataInvalidated;
}
/// <summary>
/// Rilettura dettagli
/// </summary>
/// <returns></returns>
private async Task loadDetails()
{
if (CRecMSE != null)
// verifico di non essere in reloading e di avere dati...
if (!MServ.IsReloading && CRecMSE != null)
{
bool doForce = false;
if (SDService.MachNumPzGet(IdxMaccCur) != CRecMSE.PezziProd || SDService.MachProdStGet(IdxMaccCur).IdxOdl != CRecMSE.IdxOdl || (datiProdAct != null && datiProdAct.PzTotODL != CRecMSE.PezziProd))
@@ -438,7 +446,24 @@ namespace MP_TAB3.Components
{
datiProdAct = SDService.MachProdStGet(IdxMaccCur);
}
isMulti = SMServ.DictMacchMulti[IdxMaccMain] == 1;
// fix multi
if (SMServ.DictMacchMulti.ContainsKey(IdxMaccMain))
{
isMulti = SMServ.DictMacchMulti[IdxMaccMain] == 1;
}
else
{
isMulti = false;
}
// fix manual
if (SMServ.DictMacchManual.ContainsKey(IdxMaccMain))
{
isManual = SMServ.DictMacchManual[IdxMaccMain];
}
else
{
isManual = false;
}
// verificare
if (!FullMode || !detailLoaded || doForce)
{
@@ -501,6 +526,8 @@ namespace MP_TAB3.Components
{
// salvo idxMacch
await MServ.IdxMaccSet(RecMSE!.IdxMacchina);
// salvo se sia manuale...
await MServ.LastOpenedPageSet("machine-detail");
// navigo!
NavMan.NavigateTo($"machine-detail");
+7 -7
View File
@@ -1,8 +1,8 @@
<div class="card text-white2 shadow bg-dark p-0 m-0">
<div class="card-body rounded rounded-3 py-2">
<div class="card shadow bg-dark p-0 m-0">
<div class="card-body rounded rounded-3 py-2 px-3">
<div class="row">
<div class="col-12 placeholder-glow text-center mb-1">
<span class="placeholder col-3 fs-2 bg-light"></span>
<span class="placeholder col-3 fs-1 bg-light"></span>
</div>
<div class="col-4 placeholder-glow my-1">
<span class="placeholder text-light col-12"></span>
@@ -14,7 +14,7 @@
<span class="placeholder text-primary placeholder-sm col-2"></span>
</div>
<div class="col-4 placeholder-glow text-center py-2 my-1">
<span class="placeholder col-6 bg-success rounded-circle h-100"></span>
<span class="placeholder col-6 bg-secondary rounded-circle h-100"></span>
</div>
<div class="col-4 placeholder-glow my-1">
<span class="placeholder col-12"></span>
@@ -26,9 +26,9 @@
<span class="placeholder text-light col-2"></span>
</div>
<div class="col-12 placeholder-glow text-center my-1">
<span class="placeholder placeholder-lg fs-2 col-2 bg-warning"></span>
<span class="placeholder placeholder-lg fs-2 col-7 bg-primary"></span>
<span class="placeholder placeholder-lg fs-2 col-2 bg-info"></span>
<span class="placeholder placeholder-lg fs-1 col-2 bg-warning"></span>
<span class="placeholder placeholder-lg fs-1 col-7 bg-primary"></span>
<span class="placeholder placeholder-lg fs-1 col-2 bg-info"></span>
</div>
</div>
</div>
@@ -15,10 +15,10 @@
<span class="placeholder placeholder-lg col-3 bg-danger"></span>
<span class="placeholder placeholder-lg col-4 bg-warning"></span>
</div>
<div class="col-5 placeholder-glow text-center mb-2">
<div class="col-5 placeholder-glow text-center mb-1">
<span class="placeholder col-12 bg-success fs-1 h-100 rounded-circle my-1 mx-2"></span>
</div>
<div class="col-7 placeholder-glow mb-2">
<div class="col-7 placeholder-glow mb-1">
<span class="placeholder small text-light col-9"></span>
<span class="placeholder small text-light col-2"></span>
<span class="placeholder small text-light col-9"></span>
@@ -9,7 +9,7 @@
}
@media (min-width: 600px) {
.pholderHeight {
height: 5.1rem;
height: 6.6rem;
}
}
@media (min-width: 768px) {
@@ -12,7 +12,7 @@
@media (min-width: 600px) {
.pholderHeight {
height: 5.1rem;
height: 6.6rem;
}
}
+1 -1
View File
@@ -1 +1 @@
.pholderHeight{height:5.5rem;object-fit:cover;}@media(min-width:430px){.pholderHeight{height:5.8rem;}}@media(min-width:600px){.pholderHeight{height:5.1rem;}}@media(min-width:768px){.pholderHeight{height:7.6rem;}}@media(min-width:800px){.pholderHeight{height:8.2rem;}}@media(min-width:1025px){.pholderHeight{height:7.2rem;}}
.pholderHeight{height:5.5rem;object-fit:cover;}@media(min-width:430px){.pholderHeight{height:5.8rem;}}@media(min-width:600px){.pholderHeight{height:6.6rem;}}@media(min-width:768px){.pholderHeight{height:7.6rem;}}@media(min-width:800px){.pholderHeight{height:8.2rem;}}@media(min-width:1025px){.pholderHeight{height:7.2rem;}}
+55 -47
View File
@@ -1,19 +1,19 @@
<div class="col-12 mt-1">
<div class="mt-1">
<MachSel RecMSE="RecMSE" E_MachSel="SetMacc"></MachSel>
</div>
<div class="col-12 mt-3">
<div class="mt-2">
<div class="row">
@if (enableMagPrint)
{
<div class="col-6 pe-1">
<div class="col-6 pe-2">
<PrintMag RecMSE="RecMSE"></PrintMag>
</div>
}
@if (odlOk)
{
<div class="@ConfCssWidth ps-1">
<div class="@ConfCssWidth">
<button class="btn btn-lg @ConfBg py-2 px-2 text-nowrap text-truncate" style="width: 100%" @onclick="()=>ToggleConfProd()">
<span>@ConfTitle</span><i class="fa-solid @ConfTitleIcon ps-1"></i>
</button>
@@ -26,6 +26,56 @@
</div>
</div>
@if (showConfirmResult)
{
<div class="border border-info border-2 rounded-3 my-2 p-2">
<div class="row">
<div class="col-6">
<b>Conferma Produzione</b> effettuata alle @($"{lastConfProd:HH:mm:ss}")
</div>
<div class="col-6">
<div class="d-flex justify-content-between lh-sm text-success">
@if (lastPzBuoni > 0)
{
<span>Pz Buoni</span>
<span class="fw-bold">@lastPzBuoni</span>
}
else
{
<span class="text-secondary">Pz Buoni</span>
<span class="text-secondary">@lastPzBuoni</span>
}
</div>
<div class="d-flex justify-content-between lh-sm text-danger">
@if (lastPzScarto > 0)
{
<span>Pz scarto</span>
<span>@lastPzScarto</span>
}
else
{
<span class="text-secondary">Pz scarto</span>
<span class="text-secondary">@lastPzScarto</span>
}
</div>
<div class="d-flex justify-content-between lh-sm text-info">
@if (lastPzRilav > 0)
{
<span>Cicli Rilav.</span>
<span>@lastPzRilav</span>
}
else
{
<span class="text-secondary">Cicli Rilav.</span>
<span class="text-secondary">@lastPzRilav</span>
}
</div>
</div>
</div>
</div>
}
@if (confProdActive)
{
<div class="cardBg bg-dark bg-gradient p-2 mt-2 border border-success border-2">
@@ -117,6 +167,7 @@
</div>
</div>
}
<div class="col-12">
<div class="row textCondens mt-2 px-2">
<div class="col-12 py-0 text-start text-uppercase lh-1 fw-bold">
@@ -210,49 +261,6 @@
</div>
</div>
@if (showConfirmResult)
{
<div class="border border-info border-2 rounded-3 my-2 p-2">
<b>Conferma Produzione</b> effettuata alle @($"{lastConfProd:HH:mm:ss}")
<div class="d-flex justify-content-between lh-sm text-success">
@if (lastPzBuoni > 0)
{
<span>Pz Buoni</span>
<span class="fw-bold">@lastPzBuoni</span>
}
else
{
<span class="text-secondary">Pz Buoni</span>
<span class="text-secondary">@lastPzBuoni</span>
}
</div>
<div class="d-flex justify-content-between lh-sm text-danger">
@if (lastPzScarto > 0)
{
<span>Pz scarto</span>
<span>@lastPzScarto</span>
}
else
{
<span class="text-secondary">Pz scarto</span>
<span class="text-secondary">@lastPzScarto</span>
}
</div>
<div class="d-flex justify-content-between lh-sm text-info">
@if (lastPzRilav > 0)
{
<span>Cicli Rilav.</span>
<span>@lastPzRilav</span>
}
else
{
<span class="text-secondary">Cicli Rilav.</span>
<span class="text-secondary">@lastPzRilav</span>
}
</div>
</div>
}
@if (!confProdActive)
{
<div class="col-12">
-2
View File
@@ -291,7 +291,6 @@ namespace MP_TAB3.Components
protected async Task SalvaConfPz()
{
isProcessing = true;
// effettua conferma con conf da DB del tipo (giorni / turni / periodo
bool fatto = effettuaConfermaProd();
await TabDServ.FlushCache("StatoProd");
@@ -313,7 +312,6 @@ namespace MP_TAB3.Components
lastPzRilav = numPzRilav2Rec;
lastPzScarto = numPzScarto2Rec;
lastConfProd = DateTime.Now;
// cambio button conferma...
confProdActive = false;
numPzLasciati = 0;
+37
View File
@@ -0,0 +1,37 @@
<div class="row">
<div class="col-12 col-lg-6 col-xl-4 mb-2">
<div class="row">
<div class="col-8 col-md-9 pe-0">
<div class="form-floating small">
<input type="text" class="form-control" @bind="SearchVal">
<label><i class="fa-solid fa-magnifying-glass"></i> Articolo (3+ char)</label>
</div>
</div>
<div class="col-4 col-md-3 ps-0">
<div class="form-floating small">
<input type="number" class="form-control text-end" @bind="Num2Displ">
<label># Displ</label>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 col-xl-8 mb-2">
<div class="form-floating">
<select class="form-select form-select-sm" disabled="@ListArtDisabled" @bind="@CodArtSel">
<option value="" selected>-- Nessuno --</option>
@if (ListArticoli == null)
{
<option value="" disabled>No record found</option>
}
else
{
@foreach (var item in ListArticoli)
{
<option value="@item.Key">@item.Value</option>
}
}
</select>
<label for="floatingSelect">Selezione Articolo (@DisplayCount / <b>@TotalCount</b>)</label>
</div>
</div>
</div>
+140
View File
@@ -0,0 +1,140 @@
using Microsoft.AspNetCore.Components;
using MP.Data.Services;
using NLog;
namespace MP_TAB3.Components
{
public partial class SelectCodArt
{
#region Public Properties
[Parameter]
public EventCallback<string> E_CodArt { get; set; }
[Parameter]
public int SearchMinChar { get; set; }
#endregion Public Properties
#region Protected Properties
protected string CodArtSel
{
get => codArtSel;
set
{
if (codArtSel != value)
{
codArtSel = value;
E_CodArt.InvokeAsync(CodArtSel).ConfigureAwait(false);
}
}
}
protected int DisplayCount { get; set; } = 0;
protected bool ListArtDisabled { get => string.IsNullOrEmpty(SearchVal) || SearchVal.Length < SearchMinChar; }
protected Dictionary<string, string>? ListArticoli { get; set; } = null;
protected Dictionary<string, string> ListArticoliAll { get; set; } = new Dictionary<string, string>();
[Inject]
protected ListSelectDataSrv MDataService { get; set; } = null!;
protected int Num2Displ
{
get => num2Displ;
set
{
if (num2Displ != value)
{
num2Displ = value;
FiltArticoli();
}
}
}
protected string SearchVal
{
get => searchVal;
set
{
if (searchVal != value)
{
searchVal = value;
var pUpd = Task.Run(async () =>
{
await ReloadArticoli();
});
pUpd.Wait();
}
}
}
protected int TotalCount { get; set; } = 0;
#endregion Protected Properties
#region Protected Methods
protected void FiltArticoli()
{
bool done = false;
if (!ListArtDisabled)
{
if (ListArticoliAll != null)
{
TotalCount = ListArticoliAll.Count;
ListArticoli = ListArticoliAll.Take(Num2Displ).ToDictionary(x => x.Key, x => x.Value);
DisplayCount = ListArticoli.Count;
done = true;
}
}
if (!done)
{
TotalCount = 0;
ListArticoli = new Dictionary<string, string>();
DisplayCount = 0;
}
}
protected async Task GetArticoli()
{
if (!ListArtDisabled)
{
Log.Debug("START GetArticoli");
var rawData = await MDataService.ArticoliGetSearch(10000, "*", searchVal);
// trasformo!
if (rawData != null)
{
ListArticoliAll = rawData.ToDictionary(x => x.CodArticolo, x => $"{x.CodArticolo} | {x.DescArticolo} | {x.Disegno}");
}
Log.Debug("END GetArticoli");
}
}
protected async Task ReloadArticoli()
{
await GetArticoli();
FiltArticoli();
}
#endregion Protected Methods
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Private Properties
private string codArtSel { get; set; } = "";
private int num2Displ { get; set; } = 20;
private string searchVal { get; set; } = "";
#endregion Private Properties
}
}
+9 -1
View File
@@ -28,7 +28,15 @@
<div class="list-group">
@foreach (var item in MenuItems)
{
<button class="p-2 list-group-item list-group-item-action @cssActive(item.NavigateUrl) link-underline link-underline-opacity-0 link-underline-opacity-75-hover" @onclick="() => SetPage(item.NavigateUrl)" data-bs-dismiss="offcanvas"><i class="fa fa-lg @item.icona pe-2"></i> @item.Testo</button>
@* if (IsManual && item.ordine > 20) *@
if (IsManual && item.ordine > 40)
{
<button class="p-2 list-group-item list-group-item-action @cssActive(item.NavigateUrl) link-underline link-underline-opacity-0 link-underline-opacity-75-hover disabled" data-bs-dismiss="offcanvas"><i class="fa fa-lg @item.icona pe-2"></i> @item.Testo</button>
}
else
{
<button class="p-2 list-group-item list-group-item-action @cssActive(item.NavigateUrl) link-underline link-underline-opacity-0 link-underline-opacity-75-hover" @onclick="() => SetPage(item.NavigateUrl)" data-bs-dismiss="offcanvas"><i class="fa fa-lg @item.icona pe-2"></i> @item.Testo</button>
}
}
</div>
</div>
+18
View File
@@ -18,6 +18,9 @@ namespace MP_TAB3.Components
[Inject]
protected MessageService MsgServ { get; set; } = null!;
[Inject]
protected SharedMemService MStor { get; set; } = null!;
[Inject]
protected NavigationManager navManager { get; set; } = null!;
@@ -30,6 +33,19 @@ namespace MP_TAB3.Components
return navManager.Uri.Contains(currUri) ? "bg-dark text-light" : "";
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
idxMaccSel = await MsgServ.IdxMaccGet();
if (!string.IsNullOrEmpty(idxMaccSel) && MStor.DictMacchManual.ContainsKey(idxMaccSel))
{
IsManual = MStor.DictMacchManual[idxMaccSel];
}
else
{
IsManual = false;
}
}
protected override void OnInitialized()
{
var rawVers = typeof(Program).Assembly.GetName().Version;
@@ -51,6 +67,8 @@ namespace MP_TAB3.Components
#region Private Fields
private string idxMaccSel = "";
private bool IsManual = false;
private Version version = null!;
#endregion Private Fields
+3 -3
View File
@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<Version>6.16.2503.2717</Version>
<Version>6.16.2504.712</Version>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP_TAB3</RootNamespace>
</PropertyGroup>
@@ -36,8 +36,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="EgwCoreLib.Razor" Version="1.5.2503.1410" />
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2503.1410" />
<PackageReference Include="EgwCoreLib.Razor" Version="1.5.2504.108" />
<PackageReference Include="EgwCoreLib.Utils" Version="1.5.2504.108" />
<PackageReference Include="Microsoft.AspNetCore.Components" Version="6.0.36" />
<PackageReference Include="Microsoft.AspNetCore.Http.Connections.Common" Version="6.0.36" />
<PackageReference Include="NLog" Version="5.3.4" />
+34 -16
View File
@@ -4,6 +4,7 @@ using MP.Data;
using MP.Data.Services;
using Newtonsoft.Json;
using NLog.Fluent;
using MP_TAB3.Components;
namespace MP_TAB3.Pages
{
@@ -12,17 +13,6 @@ namespace MP_TAB3.Pages
/// </summary>
public partial class BasePage : IDisposable
{
#region Private Fields
private bool doBlink = false;
/// <summary>
/// DateTime ultimo salvataggio in LocalStorage
/// </summary>
private DateTime lastSave = DateTime.Now;
#endregion Private Fields
#region Public Properties
/// <summary>
@@ -30,11 +20,6 @@ namespace MP_TAB3.Pages
/// </summary>
public MappaStatoExpl? CurrMSE { get; set; } = null;
/// <summary>
/// Macchina selezionata
/// </summary>
public string IdxMacc { get; set; } = "";
[Inject]
public MessageService MsgServ { get; set; } = null!;
@@ -57,6 +42,20 @@ namespace MP_TAB3.Pages
#endregion Public Methods
#region Protected Properties
/// <summary>
/// Macchina selezionata
/// </summary>
protected string IdxMacc { get; set; } = "";
protected bool IsManual { get; set; } = false;
[Inject]
protected SharedMemService MStor { get; set; } = null!;
#endregion Protected Properties
#region Protected Methods
/// <summary>
@@ -126,10 +125,29 @@ namespace MP_TAB3.Pages
{
CurrMSE = await MsgServ.GetMachineMse(IdxMacc);
}
if (!string.IsNullOrEmpty(IdxMacc) && MStor.DictMacchManual.ContainsKey(IdxMacc))
{
IsManual = MStor.DictMacchManual[IdxMacc];
}
else
{
IsManual = false;
}
}
#endregion Protected Methods
#region Private Fields
private bool doBlink = false;
/// <summary>
/// DateTime ultimo salvataggio in LocalStorage
/// </summary>
private DateTime lastSave = DateTime.Now;
#endregion Private Fields
#region Private Methods
/// <summary>
+1 -1
View File
@@ -67,6 +67,6 @@
await InvokeAsync(StateHasChanged);
// rimando alla home...
await Task.Delay(bDelay);
navManager.NavigateTo("", true);
navManager.NavigateTo("Index", true);
}
}
+8 -1
View File
@@ -10,5 +10,12 @@ else
{
<CheckControls RecMSE="CurrMSE"></CheckControls>
<MachineBlock RecMSE="CurrMSE" FullMode="false" IdxMacchSub="@IdxMaccSubSel"></MachineBlock>
<ProdConfirm RecMSE="CurrMSE" E_Updated="RefreshData" E_MachSel="SetMacc"></ProdConfirm>
@if (IsManual)
{
<InsManual RecMSE="CurrMSE"></InsManual>
}
else
{
<ProdConfirm RecMSE="CurrMSE" E_Updated="RefreshData" E_MachSel="SetMacc"></ProdConfirm>
}
}
-3
View File
@@ -8,9 +8,6 @@ namespace MP_TAB3.Pages
{
#region Protected Properties
[Inject]
protected SharedMemService MStor { get; set; } = null!;
[Inject]
protected TabDataService TabServ { get; set; } = null!;
+1 -1
View File
@@ -238,7 +238,7 @@ namespace MP_TAB3.Pages
{
await base.ReloadData();
// recupero eventi
var eventsAll = await TabDServ.AnagEventiGetByMacch(IdxMacc);
var eventsAll = TabDServ.AnagEventiGetByMacch(IdxMacc);
if (eventsAll != null)
{
events2show = eventsAll.Where(x => x.EventoTablet).ToList();
+4 -5
View File
@@ -12,16 +12,15 @@
@if (ShowScanBarcode)
{
<BarcodeReader
@ref="barcodeReaderCustom"
<BarcodeReader @ref="barcodeReaderCustom"
ScanResult="(e) => ScanDoneHandler(e)"
Close="ToggleCodeScan"
ScanBtnTitle="Scan"
ResetBtnTitle="Reset"
CloseBtnTitle="Close"
UseBuiltinDiv="false"
UseBuiltinDiv="false"
SelectDeviceBtnTitle="Select Device">
</BarcodeReader>
</BarcodeReader>
<div @ref="barcodeReaderCustom.Element" class="d-flex justify-content-center">
<div class="col-12 col-md-8 col-lg-6">
@@ -39,7 +38,7 @@
</div>
</div>
</div>
}
@if (oprList.Count > 0)
+8 -2
View File
@@ -15,10 +15,13 @@ namespace MP_TAB3.Pages
public void Dispose()
{
barcodeReaderCustom.Stop();
barcodeReaderCustom.CloseScan();
ShowScanBarcode = false;
txtError = "";
matrOpr = 0;
oprList = new List<AnagOperatoriModel>();
//GC.Collect();
GC.Collect();
}
#endregion Public Methods
@@ -135,8 +138,11 @@ namespace MP_TAB3.Pages
await TDService.RegDichiarInsert(ulRec);
}
// nascondo scanner...
ShowScanBarcode = false;
// passo a status map
await Task.Delay(150);
await Task.Delay(50);
NavMan.NavigateTo("status-map", true);
}
else
+3 -12
View File
@@ -42,18 +42,9 @@
mseIdx++;
if (currMse != null)
{
<div class="col ps-0 pe-1">
<MachineBlock RecMSE="currMse" FullMode="true" Width="@Width" Height="@Height" ShowCard="@ShowCard" doBlink="@doBlink"></MachineBlock>
</div>
@* if (mseIdx % 2 == 0)
{
}
else
{
<div class="col ps-0 pe-1">
<PlaceholderStatusMap></PlaceholderStatusMap>
</div>
}*@
<div class="col ps-0 pe-1">
<MachineBlock RecMSE="currMse" FullMode="true" Width="@Width" Height="@Height" ShowCard="@ShowCard" doBlink="@doBlink"></MachineBlock>
</div>
}
else
{
+170 -136
View File
@@ -10,32 +10,6 @@ namespace MP_TAB3.Pages
{
public partial class StatusMap : IDisposable
{
#region Public Methods
public void Dispose()
{
ListMSE = null;
TDFeeder.dataPipe.EA_NewMessage -= DataPipe_EA_NewMessage;
TDFeeder.blinkPipe.EA_NewMessage -= BlinkPipe_EA_NewMessage;
GC.Collect();
}
#endregion Public Methods
#region Public Classes
public class WindowDimension
{
#region Public Properties
public int Height { get; set; }
public int Width { get; set; }
#endregion Public Properties
}
#endregion Public Classes
#region Protected Fields
protected bool _showCard = false;
@@ -44,6 +18,14 @@ namespace MP_TAB3.Pages
#endregion Protected Fields
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private bool doBlink = false;
#endregion Private Fields
#region Protected Properties
[Inject]
@@ -56,6 +38,43 @@ namespace MP_TAB3.Pages
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
/// <summary>
/// Numero colonne mappa: calcolato larghezza riga...
/// </summary>
protected int mapNCol
{
get
{
int answ = 2;
if (Width > 450)
{
if (Width < 1024)
{
answ = (int)Math.Floor((decimal)Width / 200);
}
else
{
answ = (int)Math.Floor((decimal)Width / 220) - 1;
}
}
return answ;
}
}
/// <summary>
/// Numero righe mappa: calcolato da num elementi e numMax x riga...
/// </summary>
protected int mapNRow
{
get
{
int answ = 1;
int numElems = ListMSE != null ? ListMSE.Count : 1;
answ = (int)Math.Ceiling((double)numElems / mapNCol);
return answ;
}
}
[Inject]
protected StatusData MDataService { get; set; } = null!;
@@ -85,6 +104,37 @@ namespace MP_TAB3.Pages
#endregion Protected Properties
#region Private Properties
private List<MappaStatoExpl>? AllDataMSE { get; set; } = null;
private string baseLang { get; set; } = "";
private List<Macchine>? ListMachineEnabled { get; set; } = null;
private List<MappaStatoExpl>? ListMSE { get; set; } = null;
private int MatrOpr
{
get => MsgServ.MatrOpr;
}
private string tcMode { get; set; } = "";
#endregion Private Properties
#region Public Methods
public void Dispose()
{
ListMSE = null;
TDFeeder.dataPipe.EA_NewMessage -= DataPipe_EA_NewMessage;
TDFeeder.blinkPipe.EA_NewMessage -= BlinkPipe_EA_NewMessage;
GC.Collect();
}
#endregion Public Methods
#region Protected Methods
/// <summary>
@@ -108,58 +158,6 @@ namespace MP_TAB3.Pages
return answ;
}
/// <summary>
/// Numero righe mappa: calcolato da num elementi e numMax x riga...
/// </summary>
protected int mapNRow
{
get
{
int answ = 1;
int numElems = ListMSE != null ? ListMSE.Count : 1;
answ = (int)Math.Ceiling((double)numElems / mapNCol);
return answ;
}
}
/// <summary>
/// restituisce MSE dato indice
/// </summary>
/// <param name="mseIdx">Indice MSE richiesto</param>
/// <returns></returns>
protected MappaStatoExpl? MseById(int mseIdx)
{
MappaStatoExpl? answ = null;
if (ListMSE != null && ListMSE.Count > mseIdx)
{
answ = ListMSE[mseIdx];
}
return answ;
}
/// <summary>
/// Numero colonne mappa: calcolato larghezza riga...
/// </summary>
protected int mapNCol
{
get
{
int answ = 2;
if (Width > 450)
{
if (Width < 1024)
{
answ = (int)Math.Floor((decimal)Width / 200);
}
else
{
answ = (int)Math.Floor((decimal)Width / 220) - 1;
}
}
return answ;
}
}
protected async Task DoLogout()
{
string tgtUrl = "logout";
@@ -197,16 +195,36 @@ namespace MP_TAB3.Pages
return answ;
}
/// <summary>
/// restituisce MSE dato indice
/// </summary>
/// <param name="mseIdx">Indice MSE richiesto</param>
/// <returns></returns>
protected MappaStatoExpl? MseById(int mseIdx)
{
MappaStatoExpl? answ = null;
if (ListMSE != null && ListMSE.Count > mseIdx)
{
answ = ListMSE[mseIdx];
}
return answ;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await getWDim();
isCalcSize = false;
AllDataMSE = await MDataService.MseGetAll(true);
FiltOprMse();
// rileggo elenco macchine operatore...
if (ListMachineEnabled == null || ListMachineEnabled.Count == 0)
{
ListMachineEnabled = await TabDServ.MacchineByMatrOper(MatrOpr);
}
await InvokeAsync(StateHasChanged);
}
// rileggo macchina e pagina
await RestoreMaccPage();
if (ListMSE != null)
{
// salvo in LocalStorage...
@@ -219,33 +237,28 @@ namespace MP_TAB3.Pages
// ora resetto il resto
ListMSE = null;
setDefaults();
await LoadMseData();
SetupConf();
TDFeeder.dataPipe.EA_NewMessage += DataPipe_EA_NewMessage;
TDFeeder.blinkPipe.EA_NewMessage += BlinkPipe_EA_NewMessage;
Random rnd = new Random();
await Task.Delay(rnd.Next(1, 50));
SetupConf();
var LastOpenedPage = await MsgServ.LastOpenedPageGet();
var currMacc = await MsgServ.IdxMaccGet();
if (currMacc != "" && currMacc != null)
{
await MsgServ.IdxMaccSet(currMacc);
if (LastOpenedPage != "" && LastOpenedPage != null)
{
NavMan.NavigateTo(LastOpenedPage);
}
}
}
protected override async Task OnParametersSetAsync()
{
// x prima cosa elenco macchine operatore...
ListMachineEnabled = await TabDServ.MacchineByMatrOper(MatrOpr);
// x prima cosa elenco macchine operatore... se mancasse
if (ListMachineEnabled == null || ListMachineEnabled.Count == 0)
{
ListMachineEnabled = await TabDServ.MacchineByMatrOper(MatrOpr);
}
}
protected async Task SaveData(List<MappaStatoExpl> newList)
{
// rileggo elenco macchine operatore...
ListMachineEnabled = await TabDServ.MacchineByMatrOper(MatrOpr);
if (ListMachineEnabled == null || ListMachineEnabled.Count == 0)
{
ListMachineEnabled = await TabDServ.MacchineByMatrOper(MatrOpr);
}
// salvo valori ricevuti
AllDataMSE = newList;
// filtro!
@@ -254,33 +267,6 @@ namespace MP_TAB3.Pages
#endregion Protected Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private bool doBlink = false;
#endregion Private Fields
#region Private Properties
private List<MappaStatoExpl>? AllDataMSE { get; set; } = null;
private string baseLang { get; set; } = "";
private List<Macchine>? ListMachineEnabled { get; set; } = null;
private List<MappaStatoExpl>? ListMSE { get; set; } = null;
private int MatrOpr
{
get => MsgServ.MatrOpr;
}
private string tcMode { get; set; } = "";
#endregion Private Properties
#region Private Methods
/// <summary>
@@ -319,21 +305,31 @@ namespace MP_TAB3.Pages
/// <exception cref="NotImplementedException"></exception>
private void DataPipe_EA_NewMessage(object? sender, EventArgs e)
{
PubSubEventArgs currArgs = (PubSubEventArgs)e;
// conversione on-the-fly List<string> --> allarmi
if (!string.IsNullOrEmpty(currArgs.newMessage))
#if false
// se fossi in update resetto...
if (MsgServ.IsReloading)
{
try
{
List<MappaStatoExpl>? dataList = JsonConvert.DeserializeObject<List<MappaStatoExpl>>(currArgs.newMessage);
if (dataList != null)
{
InvokeAsync(() => SaveData(dataList));
}
}
catch
{ }
AllDataMSE = null;
}
else
{
}
#endif
PubSubEventArgs currArgs = (PubSubEventArgs)e;
// conversione on-the-fly List<string> --> allarmi
if (!string.IsNullOrEmpty(currArgs.newMessage))
{
try
{
List<MappaStatoExpl>? dataList = JsonConvert.DeserializeObject<List<MappaStatoExpl>>(currArgs.newMessage);
if (dataList != null)
{
InvokeAsync(() => SaveData(dataList));
}
}
catch
{ }
}
InvokeAsync(() =>
{
StateHasChanged();
@@ -359,6 +355,30 @@ namespace MP_TAB3.Pages
}
}
private async Task LoadMseData()
{
AllDataMSE = await MDataService.MseGetAll(true);
FiltOprMse();
}
/// <summary>
/// Restore della macchina + pagina selezionate da info di sessione browser
/// </summary>
/// <returns></returns>
private async Task RestoreMaccPage()
{
var LastOpenedPage = await MsgServ.LastOpenedPageGet();
var currMacc = await MsgServ.IdxMaccGet();
if (currMacc != "" && currMacc != null)
{
await MsgServ.IdxMaccSet(currMacc);
if (LastOpenedPage != "" && LastOpenedPage != null)
{
NavMan.NavigateTo(LastOpenedPage);
}
}
}
private void setDefaults()
{
string df = MsgServ.UserPrefSetup("DefCardMode", "full");
@@ -376,5 +396,19 @@ namespace MP_TAB3.Pages
}
#endregion Private Methods
#region Public Classes
public class WindowDimension
{
#region Public Properties
public int Height { get; set; }
public int Width { get; set; }
#endregion Public Properties
}
#endregion Public Classes
}
}
+20 -19
View File
@@ -8,9 +8,9 @@
<table class="table table-striped table-sm">
<thead>
<tr>
<th>Articolo</th>
<th>Informazioni</th>
<th>Periodo</th>
<th class="w-50">Articolo</th>
<th class="w-25">Informazioni</th>
<th class="w-25 text-end">Periodo</th>
</tr>
</thead>
<tbody>
@@ -27,7 +27,6 @@
<div class="placeholder col-6"></div>
<small class="placeholder col-6"></small>
</td>
<td><span class="placeholder col-12"></span></td>
<td class="text-end">
<div class="placeholder col-10"></div>
<small class="placeholder col-10"></small>
@@ -40,7 +39,7 @@
@if (ListODL == null || ListODL.Count == 0)
{
<tr>
<td colspan="5">
<td colspan="3">
<div class="alert alert-warning fs-3 w-100">Nessun record trovato</div>
</td>
</tr>
@@ -53,28 +52,30 @@
<td>
<div>@item.CodArticolo</div>
<small class="text-secondary">@item.DescArticolo</small>
</td>
<td>
<div>
<small><b>Impianto:</b> @item.IdxMacchina</small>
</div>
<div>
<small><b>TC:</b> @item.Tcassegnato.ToString("N3")</small>
</div>
<div>
<small><b>N° pz:</b> @item.NumPezzi pz</small>
</div>
<div class="badge text-bg-light border border-primary">
<small class="text-secondary">@item.Note</small>
</div>
</td>
@* <td></td> *@
<td>
<div class="d-flex justify-content-between small">
<div class="px-0 fw-bold">Imp.:</div>
<div class="px-0">@(DescMacc(item.IdxMacchina))</div>
</div>
<div class="d-flex justify-content-between small">
<div class="px-0 fw-bold">TC:</div>
<div class="px-0">@item.Tcassegnato.ToString("N3")</div>
</div>
<div class="d-flex justify-content-between small">
<div class="px-0 fw-bold">N° pz:</div>
<div class="px-0">@item.NumPezzi</div>
</div>
</td>
<td class="text-end">
<div>
<small><b>Inizio:</b> @item.DataInizio</small>
<small><i class="fa-solid fa-play small pe-1"></i> @item.DataInizio</small>
</div>
<div>
<small><b>Fine:</b> @item.DataFine</small>
<small><i class="fa-solid fa-stop small pe-1"></i> @item.DataFine</small>
</div>
</td>
</tr>
+18
View File
@@ -49,6 +49,7 @@ namespace MP_TAB3.Pages
protected List<ODLExpModel> ListComplete { get; set; } = new List<ODLExpModel>();
protected List<ODLExpModel> ListODL { get; set; } = new List<ODLExpModel>();
protected List<Macchine> ListMachine { get; set; } = new List<Macchine>();
protected int MatrOpr
{
@@ -57,6 +58,19 @@ namespace MP_TAB3.Pages
[Inject]
protected MessageService MServ { get; set; } = null!;
[Inject]
protected TabDataService TabDServ { get; set; } = null!;
protected string DescMacc(string idxMacc)
{
string answ = idxMacc;
var recMac = ListMachine.FirstOrDefault(x => x.IdxMacchina == idxMacc);
if (recMac != null)
{
answ = recMac.Nome;
}
return answ;
}
#endregion Protected Properties
@@ -71,6 +85,10 @@ namespace MP_TAB3.Pages
protected async Task ReloadData()
{
isLoading = true;
if (ListMachine == null || ListMachine.Count == 0)
{
ListMachine = await TabDServ.MacchineByMatrOper(MatrOpr);
}
if (!string.IsNullOrEmpty(CodArt))
{
try
+3 -5
View File
@@ -14,11 +14,11 @@
<meta name="author" content="EgalWare" />
<link rel="shortcut icon" href="images/favicon.ico" />
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />
<base href="~/" />
@* <base href="~/" /> *@
<link rel="stylesheet" href="lib/font-awesome/css/all.min.css" />
<link rel="stylesheet" href="lib/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="css/font.min.css" />
<link rel="stylesheet" href="css/site.css" />
<link rel="stylesheet" href="css/site.min.css" />
<link rel="stylesheet" href="MP-TAB3.styles.css" />
<component type="typeof(HeadOutlet)" render-mode="Server" />
</head>
@@ -38,9 +38,7 @@
<script src="lib/Utils.js"></script>
<script src="lib/WindowSize.js"></script>
<script src="lib/bootstrap/js/bootstrap.bundle.js"></script>
@* <script src="_framework/blazor.server.js"></script> *@
<script src="lib/bootstrap/js/bootstrap.bundle.min.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 src="_framework/blazor.server.js" autostart="false"></script>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 6.16.2503.2717</h4>
<h4>Versione: 6.16.2504.712</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2503.2717
6.16.2504.712
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2503.2717</version>
<version>6.16.2504.712</version>
<url>https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+1 -1
View File
@@ -270,7 +270,7 @@ namespace MP_TAB3.Shared
{
// Logger.LogInformation("URL of new location: {Location}", e.Location);
CurrLevel = MStor.PageLevel(NavMan.Uri);
// recupero men
// recupero menu
if (MStor.DictMenu.ContainsKey(CurrLevel))
{
CurrMenuItems = MStor.DictMenu[CurrLevel];
+37 -8
View File
@@ -1,5 +1,4 @@
@inject NavigationManager NavMan
@inject ListSelectDataSrv MDataService
@inject ListSelectDataSrv MDataService
@@ -22,9 +21,19 @@
}
else
{
<NavLink class="nav-link px-2" @onclick="()=>SetPage(item.NavigateUrl)">
<i class="fa fa-lg @item.icona pe-2" aria-hidden="true"></i> @item.Testo
</NavLink>
if (IsManual && item.ordine > 20)
{
<NavLink class="nav-link px-2 disabled text-secondary">
<i class="fa fa-lg @item.icona pe-2" aria-hidden="true"></i> @item.Testo
</NavLink>
}
else
{
<NavLink class="nav-link px-2" @onclick="()=>SetPage(item.NavigateUrl)">
<i class="fa fa-lg @item.icona pe-2" aria-hidden="true"></i> @item.Testo
</NavLink>
}
}
</div>
}
@@ -40,19 +49,36 @@
[Inject]
protected MessageService MsgServ { get; set; } = null!;
[Inject]
protected NavigationManager navManager { get; set; } = null!;
protected SharedMemService MStor { get; set; } = null!;
[Inject]
protected NavigationManager NavMan { get; set; } = null!;
protected bool linkActive(string objUrl)
{
bool answ = false;
if (navManager.Uri.Contains(objUrl))
if (NavMan.Uri.Contains(objUrl))
{
answ = true;
}
return answ;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
idxMaccSel = await MsgServ.IdxMaccGet();
if (!string.IsNullOrEmpty(idxMaccSel) && MStor.DictMacchManual.ContainsKey(idxMaccSel))
{
IsManual = MStor.DictMacchManual[idxMaccSel];
}
else
{
IsManual = false;
}
}
protected async Task SetPage(string tgtUrl)
{
if (tgtUrl.Contains("status-map"))
@@ -61,6 +87,9 @@
}
await MsgServ.LastOpenedPageSet(tgtUrl);
// navManager.NavigateTo(tgtUrl, true);
navManager.NavigateTo(tgtUrl, false);
NavMan.NavigateTo(tgtUrl, false);
}
private string idxMaccSel = "";
private bool IsManual = false;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+33
View File
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Core.DTO
{
public class InsManDayDto
{
public int IdxInsMan { get; set; }
[MaxLength(50)]
public string IdxMacchina { get; set; } = "NA";
public DateTime DataRif { get; set; } = DateTime.Today;
public int PzBuoniTot { get; set; } = 0;
/// <summary>
/// Minuti prodotti (da TC e pz prod
/// </summary>
public decimal MinProdTot { get; set; } = 0;
/// <summary>
/// Rapporto record importati/totali, 0 = niente, 1 = tutto importato
/// </summary>
public double RatioImport { get; set; } = 0;
}
}
+22
View File
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Core.DTO
{
public class ManualStatusDTO
{
public int IdxTipo { get; set; } = 0;
public double Value { get; set; } = 0;
public double ValueMax { get; set; } = 1440;
public double ValuePerc
{
get => Value / ValueMax;
}
public string Title { get; set; } = "";
public string CssBlock { get; set; } = "";
}
}
+8 -8
View File
@@ -146,7 +146,7 @@ namespace MP.Data.Controllers
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliDeleteRecord(AnagArticoli currRec)
public async Task<bool> ArticoliDeleteRecord(AnagArticoliModel currRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
@@ -177,9 +177,9 @@ namespace MP.Data.Controllers
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<AnagArticoli> ArticoliGetSearch(int numRecord, string searchVal = "")
public List<AnagArticoliModel> ArticoliGetSearch(int numRecord, string searchVal = "")
{
List<AnagArticoli> dbResult = new List<AnagArticoli>();
List<AnagArticoliModel> dbResult = new List<AnagArticoliModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -200,9 +200,9 @@ namespace MP.Data.Controllers
/// <param name="azienda"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public List<AnagArticoli> ArticoliGetSearch(int numRecord, string azienda = "*", string searchVal = "")
public List<AnagArticoliModel> ArticoliGetSearch(int numRecord, string azienda = "*", string searchVal = "")
{
List<AnagArticoli> dbResult = new List<AnagArticoli>();
List<AnagArticoliModel> dbResult = new List<AnagArticoliModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -220,9 +220,9 @@ namespace MP.Data.Controllers
/// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed)
/// </summary>
/// <returns></returns>
public List<AnagArticoli> ArticoliGetUsed()
public List<AnagArticoliModel> ArticoliGetUsed()
{
List<AnagArticoli> dbResult = new List<AnagArticoli>();
List<AnagArticoliModel> dbResult = new List<AnagArticoliModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
@@ -239,7 +239,7 @@ namespace MP.Data.Controllers
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliUpdateRecord(AnagArticoli editRec)
public async Task<bool> ArticoliUpdateRecord(AnagArticoliModel editRec)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
+209
View File
@@ -10,6 +10,8 @@ using System.Data;
using System.Linq;
using System.Threading.Tasks;
using static MP.Core.Objects.Enums;
using System.Drawing.Drawing2D;
using ZXing;
namespace MP.Data.Controllers
{
@@ -644,6 +646,161 @@ namespace MP.Data.Controllers
return dbResult;
}
/// <summary>
/// Elimina record
/// </summary>
/// <param name="currRecord"></param>
public bool InsManDelete(InsManualiModel currRecord)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
var actRec = dbCtx
.DbSetInsManuali
.Where(x => currRecord.IdxInsMan > 0 && x.IdxInsMan == currRecord.IdxInsMan)
.FirstOrDefault();
// se ci fosse aggiorno...
if (actRec != null)
{
dbCtx
.DbSetInsManuali
.Remove(actRec);
}
var res = dbCtx.SaveChanges();
fatto = res != 0;
}
return fatto;
}
/// <summary>
/// Elenco insert manuali dato
/// </summary>
/// <param name="IdxMacc"></param>
/// <param name="dtStart"></param>
/// <param name="dtEnd"></param>
/// <returns></returns>
public List<InsManualiModel> InsManFilt(string IdxMacc, DateTime dtStart, DateTime dtEnd)
{
List<InsManualiModel> dbResult = new List<InsManualiModel>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetInsManuali
.Where(x => x.IdxMacchina == IdxMacc && x.InizioStato >= dtStart && x.InizioStato <= dtEnd)
.AsNoTracking()
.ToList();
}
return dbResult;
}
/// <summary>
/// Congela la giornata di ins manuali richeista
/// </summary>
/// <param name="idxMacchina"></param>
/// <param name="dtCurr"></param>
/// <returns></returns>
public bool InsManFreezeDay(string idxMacchina, DateTime dtCurr)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina);
var DataElab = new SqlParameter("@DataElab", dtCurr);
var dbResult = dbCtx
.Database
.ExecuteSqlRaw("EXEC stp_IM_ElaboraInsManuali @IdxMacchina, @DataElab", IdxMacc, DataElab);
fatto = dbResult > 0;
}
return fatto;
}
/// <summary>
/// Esegue upsert record
/// </summary>
/// <param name="currRecord"></param>
public bool InsManUpsert(InsManualiModel currRecord)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
var actRec = dbCtx
.DbSetInsManuali
.Where(x => currRecord.IdxInsMan > 0 && x.IdxInsMan == currRecord.IdxInsMan)
.FirstOrDefault();
// se ci fosse aggiorno...
if (actRec == null)
{
dbCtx
.DbSetInsManuali
.Add(currRecord);
}
else
{
actRec.CodArticolo = currRecord.CodArticolo;
actRec.FineStato = currRecord.FineStato;
actRec.IdxMacchina = currRecord.IdxMacchina;
actRec.IdxTipoEv = currRecord.IdxTipoEv;
actRec.Imported = currRecord.Imported;
actRec.InizioStato = currRecord.InizioStato;
actRec.KeyRichiesta = currRecord.KeyRichiesta;
actRec.MatrOpr = currRecord.MatrOpr;
actRec.MinProd = currRecord.MinProd;
actRec.PzBuoni = currRecord.PzBuoni;
actRec.TCiclo = currRecord.TCiclo;
dbCtx.Entry(actRec).State = EntityState.Modified;
}
var res = dbCtx.SaveChanges();
fatto = res != 0;
}
return fatto;
}
/// <summary>
/// Esegue salvataggio lista records + svuotamento cache
/// </summary>
/// <param name="currRecord"></param>
public bool InsManUpsert(List<InsManualiModel> listRecord)
{
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
{
foreach (var currRecord in listRecord)
{
var actRec = dbCtx
.DbSetInsManuali
.Where(x => currRecord.IdxInsMan > 0 && x.IdxInsMan == currRecord.IdxInsMan)
.FirstOrDefault();
// se ci fosse aggiorno...
if (actRec == null)
{
dbCtx
.DbSetInsManuali
.Add(currRecord);
}
else
{
actRec.CodArticolo = currRecord.CodArticolo;
actRec.FineStato = currRecord.FineStato;
actRec.IdxMacchina = currRecord.IdxMacchina;
actRec.IdxTipoEv = currRecord.IdxTipoEv;
actRec.Imported = currRecord.Imported;
actRec.InizioStato = currRecord.InizioStato;
actRec.KeyRichiesta = currRecord.KeyRichiesta;
actRec.MatrOpr = currRecord.MatrOpr;
actRec.MinProd = currRecord.MinProd;
actRec.PzBuoni = currRecord.PzBuoni;
actRec.TCiclo = currRecord.TCiclo;
dbCtx.Entry(actRec).State = EntityState.Modified;
}
}
var res = dbCtx.SaveChanges();
fatto = res != 0;
}
return fatto;
}
/// <summary>
/// Elenco PODL macchina
/// </summary>
@@ -669,6 +826,27 @@ namespace MP.Data.Controllers
return dbResult;
}
/// <summary>
/// Elenco valori ammessi x tabella/colonna
/// </summary>
/// <param name="tabName"></param>
/// <param name="fieldName"></param>
/// <returns></returns>
public List<ListValues> ListValuesFilt(string tabName, string fieldName)
{
List<ListValues> dbResult = new List<ListValues>();
using (var dbCtx = new MoonProContext(_configuration))
{
dbResult = dbCtx
.DbSetListValues
.Where(x => x.TableName == tabName && x.FieldName == fieldName)
.AsNoTracking()
.OrderBy(x => x.ordinal)
.ToList();
}
return dbResult;
}
/// <summary>
/// Imposto abilitazione insert eventi macchina (x fermare/avviare dati da IOB)
/// </summary>
@@ -1439,6 +1617,37 @@ namespace MP.Data.Controllers
return dbResult;
}
/// <summary>
/// Recupero PODL da chiave
/// </summary>
/// <param name="idxPODL"></param>
/// <returns></returns>
public async Task<PODLExpModel> PODLExp_getByKeyAsync(int idxPODL)
{
PODLExpModel dbResult = new PODLExpModel();
using (var dbCtx = new MoonProContext(_configuration))
{
try
{
var IdxPromessa = new SqlParameter("@IdxPromessa", idxPODL);
var rawResult = await dbCtx
.DbSetPODLExp
.FromSqlRaw("EXEC stp_PODL_getByIdx @IdxPromessa", IdxPromessa)
.AsNoTracking()
.ToListAsync();
if (rawResult != null && rawResult.Count > 0)
{
dbResult = rawResult.FirstOrDefault();
}
}
catch (Exception exc)
{
Log.Error($"Eccezione durante PODLExp_getByKeyAsync{Environment.NewLine}{exc}");
}
}
return dbResult;
}
/// <summary>
/// Restituisce elenco RC filtrato
/// </summary>
@@ -9,7 +9,7 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace MP.Data.DbModels
{
[Table("AnagArticoli")]
public partial class AnagArticoli
public partial class AnagArticoliModel
{
#region Public Properties
+1 -1
View File
@@ -40,7 +40,7 @@ namespace MP.Data.DbModels
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
public virtual AnagArticoliModel ArticoloNav { get; set; } = null!;
#endregion Public Properties
}
+1 -1
View File
@@ -50,7 +50,7 @@ namespace MP.Data.DbModels
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
public virtual AnagArticoliModel ArticoloNav { get; set; } = null!;
#endregion Public Properties
}
+1 -1
View File
@@ -41,7 +41,7 @@ namespace MP.Data.DbModels
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
public virtual AnagArticoliModel ArticoloNav { get; set; } = null!;
#endregion Public Properties
}
+71
View File
@@ -0,0 +1,71 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DbModels
{
[Table("InsManuali")]
public partial class InsManualiModel
{
#region Public Properties
[Key]
public int IdxInsMan { get; set; }
[MaxLength(50)]
public string IdxMacchina { get; set; } = "NA";
public int IdxTipoEv { get; set; } = 0;
[MaxLength(50)]
public string KeyRichiesta { get; set; } = "";
[MaxLength(50)]
public string CodArticolo { get; set; } = "";
public DateTime InizioStato { get; set; } = DateTime.Now;
public DateTime? FineStato { get; set; } = null;
public int MatrOpr { get; set; } = 0;
public int PzBuoni { get; set; } = 0;
/// <summary>
/// Tempo Ciclo std
/// </summary>
public decimal TCiclo { get; set; } = 0;
/// <summary>
/// Minuti prodotti (da TC e pz prod
/// </summary>
public decimal MinProd { get; set; } = 0;
/// <summary>
/// DataOra conferma import e trasformazione dati (come Eventi, DDB, ODL...)
/// </summary>
public DateTime? Imported { get; set; } = null;
[NotMapped]
public bool IsWork
{
get => IdxTipoEv == 1;
}
/// <summary>
/// Navigazione oggetto Machine
/// </summary>
[ForeignKey("IdxMacchina")]
public virtual Macchine MachineNav { get; set; } = null!;
/// <summary>
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoliModel ArticoloNav { get; set; } = null!;
#endregion Public Properties
}
}
+1 -1
View File
@@ -59,7 +59,7 @@ namespace MP.Data.DbModels
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
public virtual AnagArticoliModel ArticoloNav { get; set; } = null!;
public string DescArticolo { get; set; } = "";
public string CodMacchina { get; set; } = "";
+1 -1
View File
@@ -62,7 +62,7 @@ namespace MP.Data.DbModels
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
public virtual AnagArticoliModel ArticoloNav { get; set; } = null!;
#endregion Public Properties
}
+1 -1
View File
@@ -73,7 +73,7 @@ namespace MP.Data.DbModels
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
public virtual AnagArticoliModel ArticoloNav { get; set; } = null!;
public string DescArticolo { get; set; } = "";
public string CodMacchina { get; set; } = "";
+1 -1
View File
@@ -66,7 +66,7 @@ namespace MP.Data.DbModels
/// Navigazione oggetto Articolo
/// </summary>
[ForeignKey("CodArticolo")]
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
public virtual AnagArticoliModel ArticoloNav { get; set; } = null!;
#endregion Public Properties
}
+9 -8
View File
@@ -8,14 +8,15 @@ namespace MP.Data.DbModels
// </Auto-Generated>
public partial class VMSFDModel
{
public string IdxMacchina { get; set; }
public string Codmacchina { get; set; }
public bool PalletChange { get; set; }
public string CodArticoloA { get; set; }
public string CodArticoloB { get; set; }
public bool SimplePallet { get; set; }
public bool InsEnabled { get; set; }
public bool SLogEnabled { get; set; }
public string IdxMacchina { get; set; } = "ND";
public string Codmacchina { get; set; } = "000";
public bool PalletChange { get; set; } = false;
public string CodArticoloA { get; set; } = "ND";
public string CodArticoloB { get; set; } = "ND";
public bool SimplePallet { get; set; } = true;
public bool InsEnabled { get; set; } = true;
public bool SLogEnabled { get; set; } = false;
public int IsManual { get; set; } = 0;
public int IdxFamigliaIngresso { get; set; }
public int Multi { get; set; }
public int BitFilt { get; set; }
+5 -3
View File
@@ -46,7 +46,7 @@ namespace MP.Data
public virtual DbSet<AnagGruppi> DbSetAnagGruppi { get; set; }
public virtual DbSet<AnagStatiModel> DbSetAnagStati { get; set; }
public virtual DbSet<AnagTagsModel> DbSetAnagTags { get; set; }
public virtual DbSet<AnagArticoli> DbSetArticoli { get; set; }
public virtual DbSet<AnagArticoliModel> DbSetArticoli { get; set; }
public virtual DbSet<ConfigModel> DbSetConfig { get; set; }
public virtual DbSet<LinkMenu> DbSetLinkMenu { get; set; }
public virtual DbSet<ListValues> DbSetListValues { get; set; }
@@ -91,12 +91,14 @@ namespace MP.Data
public virtual DbSet<ST_TemplateRows> DbSetStTemplateRows { get; set; }
public virtual DbSet<CommentiModel> DbSetCommenti { get; set; }
public virtual DbSet<FermiNonQualModel> DbSetFNQ { get; set; }
public virtual DbSet<FermiNonQualModel> DbSetFNQ { get; set; }
public virtual DbSet<vSelEventiBCodeModel> DbSetVSEB { get; set; }
public virtual DbSet<vSelOdlModel> DbSetVSODL { get; set; }
public virtual DbSet<vSelCauScartoModel> DbSetVSCS { get; set; }
public virtual DbSet<InsManualiModel> DbSetInsManuali { get; set; }
#endregion Public Properties
#region Private Methods
@@ -156,7 +158,7 @@ namespace MP.Data
.IsRequired()
.HasMaxLength(50);
});
modelBuilder.Entity<AnagArticoli>(entity =>
modelBuilder.Entity<AnagArticoliModel>(entity =>
{
entity.HasKey(e => e.CodArticolo);
+2 -2
View File
@@ -48,7 +48,7 @@ namespace MP.Data
#region Public Properties
public virtual DbSet<AnagArticoli> DbSetArticoli { get; set; }
public virtual DbSet<AnagArticoliModel> DbSetArticoli { get; set; }
public virtual DbSet<Macchine> DbSetMacchine { get; set; }
public virtual DbSet<FluxLogModel> DbSetFluxLog { get; set; }
public virtual DbSet<DossierModel> DbSetDossiers { get; set; }
@@ -84,7 +84,7 @@ namespace MP.Data
{
modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS");
modelBuilder.Entity<AnagArticoli>(entity =>
modelBuilder.Entity<AnagArticoliModel>(entity =>
{
entity.HasKey(e => e.CodArticolo);
+119
View File
@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MP.Data.Services
{
/// <summary>
/// Gestore statistiche esecuzione processi x analisi timing
/// </summary>
public class ExecStatsCollector
{
#region Public Methods
/// <summary>
/// restituisce una stringa da poter emettere in log con il summary degli eventi tracciati ed eventuale reset...
/// </summary>
/// <param name="CallName"></param>
/// <param name="resetCount"></param>
/// <returns></returns>
public string GetCallSum(string CallName, bool resetCount)
{
string answ = "";
if (TrackData.ContainsKey(CallName))
{
var reqRec = TrackData[CallName];
answ = $"{CallName} | {reqRec.NumCall} x {reqRec.AvgTime:N3}ms | min: {reqRec.MinTime:N3} | MAX: {reqRec.MaxTime:N3}";
// se richiede reset --> effettuo
if (resetCount)
{
TrackData[CallName].ListMsRec = new List<double>();
}
}
return answ;
}
/// <summary>
/// Accumula record di tracciamento info esecuzione e restituisce numero elementi finali
/// </summary>
/// <param name="CallName">nome chiamata da registrare</param>
/// <param name="msDuration">Durata in ms</param>
/// <returns></returns>
public int RecordCall(string CallName, double msDuration)
{
if (TrackData.ContainsKey(CallName))
{
TrackData[CallName].ListMsRec.Add(msDuration);
}
else
{
TrackData.Add(CallName, new RecordData() { ListMsRec = new List<double>() { msDuration } });
}
return TrackData[CallName].NumCall;
}
#endregion Public Methods
#region Public Classes
/// <summary>
/// Record atomico informazioni x un dato task tracciato
/// </summary>
public class RecordData
{
#region Public Properties
/// <summary>
/// Tempo medio
/// </summary>
public double AvgTime
{
get => ListMsRec.Sum(x => x) / (NumCall > 0 ? NumCall : 1);
}
/// <summary>
/// Lista registrazioni di tempi esecuzione in ms
/// </summary>
public List<double> ListMsRec { get; set; } = new List<double>();
/// <summary>
/// Tempo Massimo
/// </summary>
public double MaxTime
{
get => ListMsRec.OrderByDescending(x => x).FirstOrDefault();
}
/// <summary>
/// Tempo minimo
/// </summary>
public double MinTime
{
get => ListMsRec.OrderBy(x => x).FirstOrDefault();
}
/// <summary>
/// numero registrazioni disponibili
/// </summary>
public int NumCall
{
get => ListMsRec.Count();
}
#endregion Public Properties
}
#endregion Public Classes
#region Private Fields
/// <summary>
/// Dizionario di dati statistici accumulati
/// </summary>
private Dictionary<string, RecordData> TrackData = new Dictionary<string, RecordData>();
#endregion Private Fields
}
}
+4 -4
View File
@@ -61,18 +61,18 @@ namespace MP.Data.Services
/// <param name="azienda">cod azienda, * = tutte</param>
/// <param name="searchVal">Ricerca testuale</param>
/// <returns></returns>
public async Task<List<AnagArticoli>> ArticoliGetSearch(int numRecord, string azienda, string searchVal)
public async Task<List<AnagArticoliModel>> ArticoliGetSearch(int numRecord, string azienda, string searchVal)
{
string source = "DB";
Stopwatch sw = new Stopwatch();
sw.Start();
List<AnagArticoli>? result = new List<AnagArticoli>();
List<AnagArticoliModel>? result = new List<AnagArticoliModel>();
// cerco in redis...
string currKey = $"{redisBaseKey}:Art:{azienda}:{searchVal}:{numRecord}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<AnagArticoli>>($"{rawData}");
result = JsonConvert.DeserializeObject<List<AnagArticoliModel>>($"{rawData}");
source = "REDIS";
}
else
@@ -84,7 +84,7 @@ namespace MP.Data.Services
}
if (result == null)
{
result = new List<AnagArticoli>();
result = new List<AnagArticoliModel>();
}
sw.Stop();
Log.Debug($"ArticoliGetSearch | azienda: {azienda} | searchVal: {searchVal} | numRecord: {numRecord} | {source} | {sw.Elapsed.TotalMilliseconds}ms");
+12 -3
View File
@@ -411,6 +411,11 @@ namespace MP.Data.Services
return answ;
}
/// <summary>
/// Semaforo x indicare fasi di reload attive e così non effettuare alcune operazioni...
/// </summary>
public bool IsReloading { get; set; } = false;
/// <summary>
/// Restituisce il record OperatoreDTO da localstorage
/// </summary>
@@ -541,10 +546,14 @@ namespace MP.Data.Services
/// <exception cref="NotImplementedException"></exception>
public async Task SaveMse(List<MappaStatoExpl> currListMSE)
{
foreach (var item in currListMSE)
// procedo SOLO SE non sono in reloading...
if (!IsReloading)
{
string serVal = JsonConvert.SerializeObject(item);
await localStorage.SetItemAsync(machineMse(item.IdxMacchina), serVal);
foreach (var item in currListMSE)
{
string serVal = JsonConvert.SerializeObject(item);
await localStorage.SetItemAsync(machineMse(item.IdxMacchina), serVal);
}
}
}
+7 -1
View File
@@ -42,10 +42,15 @@ namespace MP.Data.Services
public Dictionary<string, string> DictMacchine { get; set; } = new Dictionary<string, string>();
/// <summary>
/// Dizionario macchine con info multi(bool)
/// Dizionario macchine con info multi(int)
/// </summary>
public Dictionary<string, int> DictMacchMulti { get; set; } = new Dictionary<string, int>();
/// <summary>
/// Dizionario macchine con info manual(bool)
/// </summary>
public Dictionary<string, bool> DictMacchManual { get; set; } = new Dictionary<string, bool>();
/// <summary>
/// Dizionario Menu
/// </summary>
@@ -224,6 +229,7 @@ namespace MP.Data.Services
ListMSFD = newList ?? new List<VMSFDModel>();
// salvo dizionario MULTI
DictMacchMulti = ListMSFD.ToDictionary(x => x.IdxMacchina, x => x.Multi);
DictMacchManual = ListMSFD.ToDictionary(x => x.IdxMacchina, x => x.IsManual == 1);
Log.Info("SharedMemService | SetMsfd executed!");
}
+32 -32
View File
@@ -9,6 +9,16 @@ namespace MP.Data.Services
{
public class TabDataFeeder : StatusData, IDisposable
{
#region Private Fields
private static System.Timers.Timer fastTimer = new System.Timers.Timer(4000);
private static Logger Log = LogManager.GetCurrentClassLogger();
private int fastRefreshMs = 1000;
#endregion Private Fields
#region Public Constructors
public TabDataFeeder(IConfiguration configuration) : base(configuration)
@@ -70,16 +80,6 @@ namespace MP.Data.Services
#endregion Public Methods
#region Private Fields
private static System.Timers.Timer fastTimer = new System.Timers.Timer(4000);
private static Logger Log = LogManager.GetCurrentClassLogger();
private int fastRefreshMs = 1000;
#endregion Private Fields
#region Private Methods
private void ElapsedFastTimer(object? source, System.Timers.ElapsedEventArgs e)
@@ -87,28 +87,28 @@ namespace MP.Data.Services
try
{
var pUpd = Task.Run(async () =>
{
// secondi pari --> blink, secondi dispari --> ricarica
DateTime adesso = DateTime.Now;
int resto = 0;
Math.DivRem(adesso.Second, 2, out resto);
if (resto == 0)
{
// invio in channel blink il segnale
blinkPipe.sendMessage("true");
Log.Debug("Elapsed Fast Timer Blink");
}
else
{
// invio in channel blink segnale false
blinkPipe.sendMessage("false");
// rileggo dati...
var newData = await MseGetAll();
// invio tramite la pipe...
dataPipe.sendMessage(JsonConvert.SerializeObject(newData));
Log.Debug("Elapsed Fast Timer reload");
}
});
{
// secondi pari --> blink, secondi dispari --> ricarica
DateTime adesso = DateTime.Now;
int resto = 0;
Math.DivRem(adesso.Second, 2, out resto);
if (resto == 0)
{
// invio in channel blink il segnale
blinkPipe.sendMessage("true");
Log.Trace("Elapsed Fast Timer Blink");
}
else
{
// invio in channel blink segnale false
blinkPipe.sendMessage("false");
// rileggo dati...
var newData = await MseGetAll();
// invio tramite la pipe...
dataPipe.sendMessage(JsonConvert.SerializeObject(newData));
Log.Trace("Elapsed Fast Timer reload");
}
});
pUpd.Wait();
}
catch (Exception exc)
+554 -37
View File
@@ -18,6 +18,9 @@ using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Driver.Core.Operations;
using MP.Data.Controllers;
using DnsClient.Protocol;
namespace MP.Data.Services
{
@@ -79,16 +82,16 @@ namespace MP.Data.Services
#region Public Events
/// <summary>
/// Evento richiesta rilettura dati pagina (x refresh pagine aperte)
/// </summary>
public event EventHandler ReloadRequest = delegate { };
/// <summary>
/// Evento report dati invalidati x rilettura
/// </summary>
public event EventHandler DataInvalidated = delegate { };
/// <summary>
/// Evento richiesta rilettura dati pagina (x refresh pagine aperte)
/// </summary>
public event EventHandler ReloadRequest = delegate { };
#endregion Public Events
#region Public Properties
@@ -256,22 +259,54 @@ namespace MP.Data.Services
return result;
}
/// <summary>
/// Elenco parametri validi tab/campo
/// </summary>
/// <returns></returns>
public List<ListValues> ListValuesFilt(string tabName, string fieldName)
{
string source = "DB";
Stopwatch sw = new Stopwatch();
sw.Start();
List<ListValues>? result = new List<ListValues>();
// cerco in redis...
string currKey = $"{redisBaseKey}:ListVal:{tabName}:{fieldName}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<ListValues>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbTabController.ListValuesFilt(tabName, fieldName);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, UltraLongCache);
}
if (result == null)
{
result = new List<ListValues>();
}
sw.Stop();
Log.Debug($"ListValuesFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco EVENTI validi x macchina
/// </summary>
/// <returns></returns>
public async Task<List<vSelEventiBCodeModel>> AnagEventiGetByMacch(string IdxMacch)
public List<vSelEventiBCodeModel> AnagEventiGetByMacch(string IdxMacch)
{
// setup parametri costanti
DateTime startDate = new DateTime(2000, 1, 1);
DateTime endDate = DateTime.Today.AddDays(1);
string source = "DB";
Stopwatch sw = new Stopwatch();
sw.Start();
List<vSelEventiBCodeModel>? result = new List<vSelEventiBCodeModel>();
// cerco in redis...
string currKey = $"{redisBaseKey}:VSEB:{IdxMacch}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<vSelEventiBCodeModel>>($"{rawData}");
@@ -282,7 +317,7 @@ namespace MP.Data.Services
result = dbTabController.AnagEventiGetByMacc(IdxMacch);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
redisDb.StringSet(currKey, rawData, LongCache);
}
if (result == null)
{
@@ -848,7 +883,7 @@ namespace MP.Data.Services
public async Task<bool> FlushCache()
{
RedisValue pattern = new RedisValue($"{redisBaseKey}:*");
bool answ = await ExecFlushRedisPattern(pattern);
bool answ = await ExecFlushRedisPatternAsync(pattern);
return answ;
}
@@ -859,7 +894,7 @@ namespace MP.Data.Services
public async Task<bool> FlushCache(string KeyReq)
{
RedisValue pattern = new RedisValue($"{redisBaseKey}:{KeyReq}:*");
bool answ = await ExecFlushRedisPattern(pattern);
bool answ = await ExecFlushRedisPatternAsync(pattern);
return answ;
}
@@ -890,6 +925,298 @@ namespace MP.Data.Services
return answ;
}
/// <summary>
/// Elenco DTO resoconto InsManuali macchina da records dettaglio
/// </summary>
/// <param name="listDetail">Dettagli</param>
/// <returns></returns>
public List<InsManDayDto> InsManDayDto(List<InsManualiModel> listDetail)
{
List<InsManDayDto>? result = new List<InsManDayDto>();
if (listDetail.Count > 0)
{
string idxMacchina = listDetail.FirstOrDefault().IdxMacchina;
// proietto...
result = listDetail
.GroupBy(x => x.InizioStato.Date)
.Select(group => new InsManDayDto
{
DataRif = group.Key,
IdxMacchina = idxMacchina,
MinProdTot = group.Sum(item => item.MinProd),
PzBuoniTot = group.Sum(item => item.PzBuoni),
RatioImport = group.Count(item => item.Imported != null) / group.Count()
})
.ToList();
}
return result;
}
/// <summary>
/// Elimina record + svuotamento cache
/// </summary>
/// <param name="currRecord"></param>
public async Task<bool> InsManDelete(InsManualiModel currRecord)
{
bool fatto = false;
// salvo
fatto = dbTabController.InsManDelete(currRecord);
// svuoto cache
RedisValue pattern = $"{redisBaseKey}:InsMan:*";
await ExecFlushRedisPatternAsync(pattern);
return fatto;
}
/// <summary>
/// Riempie eventuali buchi con evento indicato
/// </summary>
/// <param name="listDetail">Record dettaglio giornata</param>
/// <param name="idxTipoEv">IdxTipo da riempire</param>
/// <param name="matrOpr">MatrOperatore corrente</param>
/// <returns></returns>
public async Task<int> InsManFillMissing(List<InsManualiModel> listDetail, int idxTipoEv, int matrOpr)
{
List<InsManualiModel> rec2add = new List<InsManualiModel>();
InsManualiModel newRec = new InsManualiModel();
if (listDetail.Count > 0)
{
// punto come record attuale il primo
InsManualiModel currRec = listDetail.FirstOrDefault();
string idxMacc = currRec.IdxMacchina;
DateTime periodStart = currRec.InizioStato;
DateTime periodEnd = currRec.FineStato.Value;
// se NON parte da mezzanotte metto un "pad iniziale"...
if (periodStart.TimeOfDay > new TimeSpan(0))
{
// creo record x la durata necessaria
newRec = new InsManualiModel()
{
CodArticolo = "ND",
KeyRichiesta = "",
IdxMacchina = idxMacc,
InizioStato = periodStart.Date,
FineStato = periodStart,
IdxTipoEv = idxTipoEv,
MatrOpr = matrOpr,
PzBuoni = 0,
TCiclo = 0,
MinProd = (decimal)periodStart.TimeOfDay.TotalMinutes
};
rec2add.Add(newRec);
}
// cerco ultimo record...
currRec = listDetail.LastOrDefault();
periodStart = currRec.InizioStato;
periodEnd = currRec.FineStato.Value;
// se non arrivo a mezzanotte aggiungo "pad finale"
var lastPeriod = TimeSpan.FromHours(24).Subtract(periodEnd.TimeOfDay).TotalMinutes;
if (lastPeriod > 1)
{
// creo record x la durata necessaria
newRec = new InsManualiModel()
{
CodArticolo = "ND",
KeyRichiesta = "",
IdxMacchina = idxMacc,
InizioStato = periodEnd,
FineStato = periodEnd.Date.AddDays(1).AddSeconds(-1),
IdxTipoEv = idxTipoEv,
MatrOpr = matrOpr,
PzBuoni = 0,
TCiclo = 0,
MinProd = (decimal)lastPeriod
};
rec2add.Add(newRec);
}
// eseguo upsert massivo
await InsManUpsert(rec2add);
}
return rec2add.Count;
}
/// <summary>
/// Elenco insManuali macchina
/// </summary>
/// <param name="idxMacchina">Macchina</param>
/// <param name="dtFrom">Inizio periodo</param>
/// <param name="dtTo">Fine periodo</param>
/// <returns></returns>
public List<InsManualiModel> InsManFilt(string idxMacchina, DateTime dtFrom, DateTime dtTo)
{
string source = "DB";
Stopwatch sw = new Stopwatch();
sw.Start();
List<InsManualiModel>? result = new List<InsManualiModel>();
// cerco in redis...
string currKey = $"{redisBaseKey}:InsMan:{idxMacchina}:{dtFrom:yyyyMMdd-HHmmss}:{dtTo::yyyyMMdd-HHmmss}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<InsManualiModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbTabController.InsManFilt(idxMacchina, dtFrom, dtTo);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, FastCache);
}
if (result == null)
{
result = new List<InsManualiModel>();
}
sw.Stop();
Log.Debug($"InsManFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco DTO x plotting seq stati giornaliero
/// </summary>
/// <param name="listDetail">Record dettaglio giornata</param>
/// <returns></returns>
public List<ManualStatusDTO> InsManSeqDayStatus(List<InsManualiModel> listDetail)
{
List<ManualStatusDTO>? result = new List<ManualStatusDTO>();
// per sicurezza RIORDINO!
listDetail = listDetail
.OrderBy(x => x.InizioStato)
.ToList();
if (listDetail.Count > 0)
{
DateTime periodStart = listDetail.FirstOrDefault().InizioStato;
DateTime periodEnd = listDetail.FirstOrDefault().FineStato.Value;
double duration = 0;
int lastIdxTipo = -1;
ManualStatusDTO currRec = new ManualStatusDTO();
// se NON parte da mezzanotte metto un "pad iniziale"...
if (periodStart.TimeOfDay > new TimeSpan(0))
{
lastIdxTipo = 0;
currRec = new ManualStatusDTO
{
IdxTipo = lastIdxTipo,
CssBlock = "bg-light text-dark",
Title = "missing",
Value = periodStart.TimeOfDay.TotalMinutes,
ValueMax = 1440
};
}
// ciclo tutti i record, verificando idxTipo...
foreach (var item in listDetail)
{
if (item.IdxTipoEv != lastIdxTipo)
{
// aggiungo rec precedente... se > 0
if (currRec.Value > 0)
{
result.Add(currRec);
}
lastIdxTipo = item.IdxTipoEv;
periodStart = item.InizioStato;
periodEnd = item.FineStato.Value;
duration = (double)item.MinProd;
currRec = new ManualStatusDTO
{
IdxTipo = lastIdxTipo,
// fare da DB --> anagEventi
CssBlock = item.IdxTipoEv == 1 ? "bg-success text-light" : "bg-secondary text-light",
Title = $"{periodStart:HH:mm}-{periodEnd:HH:mm}",
Value = duration,
ValueMax = 1440
};
}
else
{
duration += (double)item.MinProd;
periodEnd = item.FineStato.Value;
currRec = new ManualStatusDTO
{
IdxTipo = lastIdxTipo,
// fare da DB --> anagEventi
CssBlock = item.IdxTipoEv == 1 ? "bg-success text-light" : "bg-secondary text-light",
Title = $"{periodStart:HH:mm}-{periodEnd:HH:mm}",
Value = duration,
ValueMax = 1440
};
}
}
// aggiungo rec precedente... se > 0
if (currRec.Value > 0)
{
result.Add(currRec);
}
// se non arrivo a mezzanotte aggiungo "pad finale"
var deltaFin = TimeSpan.FromHours(24).Subtract(periodEnd.TimeOfDay);
if (deltaFin.TotalMinutes > 1)
{
lastIdxTipo = 0;
currRec = new ManualStatusDTO
{
IdxTipo = lastIdxTipo,
CssBlock = "bg-light text-dark",
Title = "missing",
Value = deltaFin.TotalMinutes,
ValueMax = 1440
};
result.Add(currRec);
}
}
return result;
}
/// <summary>
/// Chiama stored x congelare i dati giornalieri
/// </summary>
/// <param name="idxMacchina"></param>
/// <param name="dtCurr"></param>
/// <returns></returns>
public async Task<bool> InsManFreezeDay(string idxMacchina, DateTime dtCurr)
{
bool fatto = false;
// salvo
fatto = dbTabController.InsManFreezeDay(idxMacchina, dtCurr);
// svuoto cache
RedisValue pattern = $"{redisBaseKey}:InsMan:*";
await ExecFlushRedisPatternAsync(pattern);
return fatto;
}
/// <summary>
/// Esegue salvataggio record + svuotamento cache
/// </summary>
/// <param name="currRecord"></param>
public async Task<bool> InsManUpsert(InsManualiModel currRecord)
{
bool fatto = false;
// salvo
fatto = dbTabController.InsManUpsert(currRecord);
// svuoto cache
RedisValue pattern = $"{redisBaseKey}:InsMan:*";
await ExecFlushRedisPatternAsync(pattern);
return fatto;
}
/// <summary>
/// Esegue salvataggio record + svuotamento cache
/// </summary>
/// <param name="listRecord"></param>
public async Task<bool> InsManUpsert(List<InsManualiModel> listRecord)
{
bool fatto = false;
// salvo
fatto = dbTabController.InsManUpsert(listRecord);
// svuoto cache
RedisValue pattern = $"{redisBaseKey}:InsMan:*";
await ExecFlushRedisPatternAsync(pattern);
return fatto;
}
/// <summary>
/// Recupero info IOB x TAB (da info registrate IOB-WIN--&gt; MP-IO)
/// </summary>
@@ -1052,6 +1379,8 @@ namespace MP.Data.Services
/// <returns></returns>
public async Task<List<Macchine>> MacchineByMatrOper(int MatrOpr)
{
int rndWait = rnd.Next(0, 2);
await Task.Delay(rndWait);
// setup parametri costanti
string source = "DB";
Stopwatch sw = new Stopwatch();
@@ -1059,7 +1388,7 @@ namespace MP.Data.Services
List<Macchine> result = new List<Macchine>();
// cerco in redis...
string currKey = $"{redisBaseKey}:MachByMatOp:{MatrOpr}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
RedisValue rawData = redisDb.StringGet(currKey);
//if (!string.IsNullOrEmpty($"{rawData}"))
if (rawData.HasValue)
{
@@ -1071,14 +1400,20 @@ namespace MP.Data.Services
result = dbTabController.MacchineByMatrOper(MatrOpr);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
redisDb.StringSet(currKey, rawData, UltraLongCache);
}
if (result == null)
{
result = new List<Macchine>();
}
sw.Stop();
Log.Debug($"MacchineByMatrOper | {source} | {sw.Elapsed.TotalMilliseconds}ms");
string callName = $"MacchineByMatrOper.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
@@ -1303,20 +1638,6 @@ namespace MP.Data.Services
return result;
}
/// <summary>
/// Invio notifica rilettura (con parametro)
/// </summary>
/// <param name="message"></param>
public void NotifyReloadRequest(string message)
{
if (ReloadRequest != null)
{
// messaggio
ReloadEventArgs rea = new ReloadEventArgs(message);
ReloadRequest.Invoke(this, rea);
}
}
/// <summary>
/// Invio notifica dati invalidati x impianto
/// </summary>
@@ -1331,6 +1652,20 @@ namespace MP.Data.Services
}
}
/// <summary>
/// Invio notifica rilettura (con parametro)
/// </summary>
/// <param name="message"></param>
public void NotifyReloadRequest(string message)
{
if (ReloadRequest != null)
{
// messaggio
ReloadEventArgs rea = new ReloadEventArgs(message);
ReloadRequest.Invoke(this, rea);
}
}
/// <summary>
/// ODL da key
/// </summary>
@@ -1339,13 +1674,18 @@ namespace MP.Data.Services
/// <returns></returns>
public async Task<ODLExpModel> OdlByIdx(int idxOdl, bool onlyUnused)
{
int rndWait = rnd.Next(0, 3);
await Task.Delay(rndWait);
string source = "DB";
Stopwatch sw = new Stopwatch();
sw.Start();
ODLExpModel result = new ODLExpModel();
// cerco in redis...
string currKey = $"{redisBaseKey}:ODL:{idxOdl}:{onlyUnused}";
RedisValue rawData = redisDb.StringGet(currKey);
#if false
RedisValue rawData = await redisDb.StringGetAsync(currKey);
#endif
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<ODLExpModel>($"{rawData}");
@@ -1353,18 +1693,32 @@ namespace MP.Data.Services
}
else
{
var listRes = dbTabController.OdlByIdx(idxOdl, onlyUnused);
#if false
var listRes = await Task.FromResult(dbTabController.OdlByIdx(idxOdl, onlyUnused));
#endif
result = listRes.FirstOrDefault();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, FastCache);
#if false
await redisDb.StringSetAsync(currKey, rawData, FastCache);
#endif
}
if (result == null)
{
result = new ODLExpModel();
}
sw.Stop();
#if false
Log.Debug($"OdlByIdx | {idxOdl} | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"OdlByIdx.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
@@ -1398,6 +1752,9 @@ namespace MP.Data.Services
/// <returns></returns>
public async Task<ODLExpModel> OdlCurrByMacc(string idxMacchina, bool forceDb)
{
// pausa random x evitare sovrapposizioni...
int rndWait = rnd.Next(0, 3);
await Task.Delay(rndWait);
string source = "DB";
Stopwatch sw = new Stopwatch();
sw.Start();
@@ -1407,7 +1764,10 @@ namespace MP.Data.Services
{
// cerco in redis...
string currKey = $"{redisBaseKey}:ODL:{idxMacchina}:CURR";
RedisValue rawData = redisDb.StringGet(currKey);
#if false
RedisValue rawData = await redisDb.StringGetAsync(currKey);
#endif
if (rawData.HasValue && !forceDb)
{
result = JsonConvert.DeserializeObject<ODLExpModel>($"{rawData}");
@@ -1415,18 +1775,32 @@ namespace MP.Data.Services
}
else
{
var listRes = dbTabController.OdlCurrByMacc(idxMacchina);
#if false
var listRes = await Task.FromResult(dbTabController.OdlCurrByMacc(idxMacchina));
#endif
result = listRes.FirstOrDefault();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, FastCache);
#if false
await redisDb.StringSetAsync(currKey, rawData, FastCache);
#endif
}
if (result == null)
{
result = new ODLExpModel();
}
sw.Stop();
#if false
Log.Debug($"OdlCurrByMacc | {source} | {idxMacchina} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"OdlCurrByMacc.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
}
else
{
@@ -1755,7 +2129,7 @@ namespace MP.Data.Services
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
var done = await ExecFlushRedisPattern(currKey);
var done = await ExecFlushRedisPatternAsync(currKey);
if (done)
{
answ = true;
@@ -1933,12 +2307,26 @@ namespace MP.Data.Services
public async Task<PODLExpModel> PODLExp_getByKey(int idxPODL)
{
string source = "DB";
// pausa random x evitare sovrapposizioni...
int rndWait = rnd.Next(0, 3);
await Task.Delay(rndWait);
Stopwatch sw = new Stopwatch();
sw.Start();
PODLExpModel result = new PODLExpModel();
// cerco in redis...
string currKey = $"{redisBaseKey}:PODL:{idxPODL}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
RedisValue rawData;
rawData = redisDb.StringGet(currKey);
#if false
if (doSync)
{
rawData = redisDb.StringGet(currKey);
}
else
{
rawData = await redisDb.StringGetAsync(currKey);
}
#endif
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<PODLExpModel>($"{rawData}");
@@ -1946,17 +2334,46 @@ namespace MP.Data.Services
}
else
{
result = await Task.FromResult(dbTabController.PODLExp_getByKey(idxPODL));
result = dbTabController.PODLExp_getByKey(idxPODL);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, FastCache);
redisDb.StringSet(currKey, rawData, FastCache);
#if false
if (doSync)
{
result = dbTabController.PODLExp_getByKey(idxPODL);
}
else
{
result = await dbTabController.PODLExp_getByKeyAsync(idxPODL);
}
//result = await Task.FromResult(dbTabController.PODLExp_getByKey(idxPODL));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
if (doSync)
{
redisDb.StringSet(currKey, rawData, FastCache);
}
else
{
await redisDb.StringSetAsync(currKey, rawData, FastCache);
}
#endif
}
if (result == null)
{
result = new PODLExpModel();
}
sw.Stop();
#if false
Log.Debug($"PODL_getByKey | {idxPODL} | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"PODL_getByKey.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
@@ -2068,6 +2485,8 @@ namespace MP.Data.Services
/// <returns></returns>
public async Task<List<RegistroControlliModel>> RegControlliFilt(string idxMacchina, int idxODL, DateTime dataFrom, DateTime dataTo, bool showMulti)
{
int rndWait = rnd.Next(0, 2);
await Task.Delay(rndWait);
// setup parametri costanti
string source = "DB";
Stopwatch sw = new Stopwatch();
@@ -2075,7 +2494,10 @@ namespace MP.Data.Services
List<RegistroControlliModel>? result = new List<RegistroControlliModel>();
// cerco in redis...
string currKey = $"{redisBaseKey}:RecContr:{idxMacchina}:{idxODL}:{dataFrom:yyyyyMMdd-HHmm}:{dataFrom:yyyyyMMdd-HHmm}:{showMulti}";
RedisValue rawData = redisDb.StringGet(currKey);
#if false
RedisValue rawData = await redisDb.StringGetAsync(currKey);
#endif
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<RegistroControlliModel>>($"{rawData}");
@@ -2086,14 +2508,25 @@ namespace MP.Data.Services
result = dbTabController.RegControlliFilt(idxMacchina, idxODL, dataFrom, dataTo, showMulti);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, UltraLongCache);
#if false
await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
#endif
}
if (result == null)
{
result = new List<RegistroControlliModel>();
}
sw.Stop();
#if false
Log.Debug($"RegControlliFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"RegControlliFilt.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
@@ -2130,6 +2563,8 @@ namespace MP.Data.Services
/// <returns></returns>
public async Task<List<RegistroControlliModel>> RegControlliLast(string idxMacchina)
{
int rndWait = rnd.Next(0, 2);
await Task.Delay(rndWait);
// setup parametri costanti
string source = "DB";
Stopwatch sw = new Stopwatch();
@@ -2137,7 +2572,10 @@ namespace MP.Data.Services
List<RegistroControlliModel>? result = new List<RegistroControlliModel>();
// cerco in redis...
string currKey = $"{redisBaseKey}:RecContr:{idxMacchina}:LAST";
RedisValue rawData = redisDb.StringGet(currKey);
#if false
RedisValue rawData = await redisDb.StringGetAsync(currKey);
#endif
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<RegistroControlliModel>>($"{rawData}");
@@ -2148,14 +2586,25 @@ namespace MP.Data.Services
result = dbTabController.RegControlliLast(idxMacchina);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
#if false
await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
#endif
redisDb.StringSet(currKey, rawData, UltraLongCache);
}
if (result == null)
{
result = new List<RegistroControlliModel>();
}
sw.Stop();
#if false
Log.Debug($"RegControlliLast | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"RegControlliLast.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
@@ -2514,7 +2963,7 @@ namespace MP.Data.Services
{
pattern = new RedisValue($"{MpIoNS}:{baseMem}:*");
}
bool answ = await ExecFlushRedisPattern(pattern);
bool answ = await ExecFlushRedisPatternAsync(pattern);
return answ;
}
@@ -2927,6 +3376,8 @@ namespace MP.Data.Services
/// <returns></returns>
public async Task<StatoProdModel> StatoProdMacchina(string idxMacchina, DateTime dtReq)
{
int rndWait = rnd.Next(0, 2);
await Task.Delay(rndWait);
// setup parametri costanti
string source = "DB";
Stopwatch sw = new Stopwatch();
@@ -2934,7 +3385,10 @@ namespace MP.Data.Services
StatoProdModel? result = new StatoProdModel();
// cerco in redis...
string currKey = $"{redisBaseKey}:StatoProd:{idxMacchina}:{dtReq:HHmm}";
RedisValue rawData = redisDb.StringGet(currKey);
#if false
RedisValue rawData = await redisDb.StringGetAsync(currKey);
#endif
//if (!string.IsNullOrEmpty($"{rawData}"))
if (rawData.HasValue)
{
@@ -2946,14 +3400,25 @@ namespace MP.Data.Services
result = dbTabController.StatoProdMacchina(idxMacchina, dtReq);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, UltraFastCache);
#if false
await redisDb.StringSetAsync(currKey, rawData, UltraFastCache);
#endif
}
if (result == null)
{
result = new StatoProdModel();
}
sw.Stop();
#if false
Log.Debug($"StatoProdMacchina | {source} | {sw.Elapsed.TotalMilliseconds}ms");
#endif
string callName = $"StatoProdMacchina.{source}";
int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds);
if (numRec >= nRecLog)
{
Log.Debug(esCollect.GetCallSum(callName, true));
}
return result;
}
@@ -3342,15 +3807,38 @@ namespace MP.Data.Services
private static Logger Log = LogManager.GetCurrentClassLogger();
private string CodModulo = "";
private string CodModuloParam = "";
private string ConnStr = "";
private Dictionary<string, string> connStrParams = new Dictionary<string, string>();
private string DataBase = "";
private string DataSource = "";
/// <summary>
/// gestore collezione statistiche esecuzione x logging
/// </summary>
private ExecStatsCollector esCollect = new ExecStatsCollector();
private string MpIoNS = "";
/// <summary>
/// numero minimo di record per cui iniziare fase di log
/// </summary>
private int nRecLog = 10;
private string redisBaseKey = "MP:TAB:Cache";
private string redisUserDataKey = "MP:TAB:Users";
/// <summary>
/// Generatore random classe
/// </summary>
private Random rnd = new Random();
#endregion Private Fields
#region Private Properties
@@ -3366,11 +3854,39 @@ namespace MP.Data.Services
#region Private Methods
/// <summary>
/// Esegue flush memoria redis dato pattern
/// Esegue flush memoria redis dato pattern, metodo sincrono
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
private async Task<bool> ExecFlushRedisPattern(RedisValue pattern)
private bool ExecFlushRedisPattern(RedisValue pattern)
{
bool answ = false;
var listEndpoints = redisConn.GetEndPoints();
foreach (var endPoint in listEndpoints)
{
//var server = redisConnAdmin.GetServer(listEndpoints[0]);
var server = redisConn.GetServer(endPoint);
if (server != null)
{
var keyList = server.Keys(redisDb.Database, pattern);
foreach (var item in keyList)
{
redisDb.KeyDelete(item);
}
answ = true;
}
}
// notifico update ai client in ascolto x reset cache
NotifyReloadRequest($"FlushRedisCache | {pattern}");
return answ;
}
/// <summary>
/// Esegue flush memoria redis dato pattern in async
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
private async Task<bool> ExecFlushRedisPatternAsync(RedisValue pattern)
{
bool answ = false;
var listEndpoints = redisConn.GetEndPoints();
@@ -3581,6 +4097,7 @@ namespace MP.Data.Services
return redHashMpIO($"SavedTask:{idxMacchina}");
}
#endregion Private Methods
}
}
+6 -6
View File
@@ -249,7 +249,7 @@ namespace MP.IOC.Data
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliDeleteRecord(AnagArticoli currRec)
public async Task<bool> ArticoliDeleteRecord(AnagArticoliModel currRec)
{
bool fatto = await SpecDbController.ArticoliDeleteRecord(currRec);
await resetCacheArticoli();
@@ -262,9 +262,9 @@ namespace MP.IOC.Data
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public async Task<List<AnagArticoli>> ArticoliGetSearch(int numRecord, string azienda, string searchVal)
public async Task<List<AnagArticoliModel>> ArticoliGetSearch(int numRecord, string azienda, string searchVal)
{
List<AnagArticoli>? result = new List<AnagArticoli>();
List<AnagArticoliModel>? result = new List<AnagArticoliModel>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
@@ -274,7 +274,7 @@ namespace MP.IOC.Data
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<AnagArticoli>>($"{rawData}");
result = JsonConvert.DeserializeObject<List<AnagArticoliModel>>($"{rawData}");
readType = "REDIS";
}
else
@@ -286,7 +286,7 @@ namespace MP.IOC.Data
}
if (result == null)
{
result = new List<AnagArticoli>();
result = new List<AnagArticoliModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
@@ -299,7 +299,7 @@ namespace MP.IOC.Data
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliUpdateRecord(AnagArticoli currRec)
public async Task<bool> ArticoliUpdateRecord(AnagArticoliModel currRec)
{
bool fatto = await SpecDbController.ArticoliUpdateRecord(currRec);
await resetCacheArticoli();
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MP-IOC </i>
<h4>Versione: 6.16.2503.1418</h4>
<h4>Versione: 6.16.2504.418</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2503.1418
6.16.2504.418
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2503.1418</version>
<version>6.16.2504.418</version>
<url>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+1 -1
View File
@@ -9,7 +9,7 @@
},
"Environment": "Steam PROD",
"AllowedHosts": "*",
"QrJumpPath": "MP/TAB/jumper?",
"QrJumpPath": "MP/TAB3/jumper?",
"appVers": "stable",
"ConnectionStrings": {
"DefaultConnection": "Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;MultipleActiveResultSets=true",
+1 -1
View File
@@ -52,7 +52,7 @@
]
},
"AllowedHosts": "*",
"QrJumpPath": "MP/TAB/jumper?",
"QrJumpPath": "MP/TAB3/jumper?",
"Environment": "Steam DEV",
"appVers": "stable",
"ConnectionStrings": {
+1 -1
View File
@@ -314,7 +314,7 @@ namespace MP.SPEC.Components
private DossierModel? currRecordClone = null;
private List<AnagArticoli>? ListArticoli;
private List<AnagArticoliModel>? ListArticoli;
private List<AnagGruppi>? ListGruppiFase;
private List<Macchine>? ListMacchine;
+6 -6
View File
@@ -270,7 +270,7 @@ namespace MP.SPEC.Data
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliDeleteRecord(AnagArticoli currRec)
public async Task<bool> ArticoliDeleteRecord(AnagArticoliModel currRec)
{
bool fatto = await dbController.ArticoliDeleteRecord(currRec);
await resetCacheArticoli();
@@ -283,9 +283,9 @@ namespace MP.SPEC.Data
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public async Task<List<AnagArticoli>> ArticoliGetSearch(int numRecord, string azienda, string searchVal)
public async Task<List<AnagArticoliModel>> ArticoliGetSearch(int numRecord, string azienda, string searchVal)
{
List<AnagArticoli>? result = new List<AnagArticoli>();
List<AnagArticoliModel>? result = new List<AnagArticoliModel>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
@@ -295,7 +295,7 @@ namespace MP.SPEC.Data
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<AnagArticoli>>($"{rawData}");
result = JsonConvert.DeserializeObject<List<AnagArticoliModel>>($"{rawData}");
readType = "REDIS";
}
else
@@ -307,7 +307,7 @@ namespace MP.SPEC.Data
}
if (result == null)
{
result = new List<AnagArticoli>();
result = new List<AnagArticoliModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
@@ -320,7 +320,7 @@ namespace MP.SPEC.Data
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliUpdateRecord(AnagArticoli currRec)
public async Task<bool> ArticoliUpdateRecord(AnagArticoliModel currRec)
{
bool fatto = await dbController.ArticoliUpdateRecord(currRec);
await resetCacheArticoli();
+1 -1
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP.SPEC</RootNamespace>
<Version>6.16.2503.2116</Version>
<Version>6.16.2504.418</Version>
<UserSecretsId>1800a78a-6ff1-40f9-b490-87fb8bfc1394</UserSecretsId>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
+9 -9
View File
@@ -82,7 +82,7 @@ namespace MP.SPEC.Pages
/// <returns></returns>
protected async Task addNew()
{
currRecord = new AnagArticoli()
currRecord = new AnagArticoliModel()
{
CodArticolo = $"_NEW_{DateTime.Now:yyyyMMdd.HHmmss}",
DescArticolo = "Nuovo articolo",
@@ -140,7 +140,7 @@ namespace MP.SPEC.Pages
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
protected async Task deleteRecord(AnagArticoli selRec)
protected async Task deleteRecord(AnagArticoliModel selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Eliminazione Articolo: sei sicuro di voler procedere?"))
return;
@@ -193,15 +193,15 @@ namespace MP.SPEC.Pages
await Task.Delay(1);
}
protected async Task selRecord(AnagArticoli selRec)
protected async Task selRecord(AnagArticoliModel selRec)
{
currRecord = selRec;
await Task.Delay(1);
}
protected async Task cloneRecord(AnagArticoli selRec)
protected async Task cloneRecord(AnagArticoliModel selRec)
{
// creo record duplicato...
AnagArticoli newRec = new AnagArticoli()
AnagArticoliModel newRec = new AnagArticoliModel()
{
Azienda = selRec.Azienda,
CodArticolo = selRec.CodArticolo,
@@ -214,7 +214,7 @@ namespace MP.SPEC.Pages
}
protected async Task update(AnagArticoli selRec)
protected async Task update(AnagArticoliModel selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi di voler salvare le modifiche?"))
return;
@@ -236,11 +236,11 @@ namespace MP.SPEC.Pages
#region Private Fields
private string _selAzienda = "*";
private AnagArticoli? currRecord = null;
private AnagArticoliModel? currRecord = null;
private List<AnagGruppi>? ListAziende;
private List<AnagArticoli>? ListRecords;
private List<AnagArticoliModel>? ListRecords;
private List<ListValues>? ListTipoArt;
private List<AnagArticoli>? SearchRecords;
private List<AnagArticoliModel>? SearchRecords;
#endregion Private Fields
+1 -1
View File
@@ -294,7 +294,7 @@ namespace MP.SPEC.Pages
private PODLExpModel? _currRecord = null;
private AnagGruppi currGruppoSel = new AnagGruppi();
private PODLExpModel currRecordControlli = new PODLExpModel();
private List<AnagArticoli>? ListArticoli;
private List<AnagArticoliModel>? ListArticoli;
private List<AnagGruppi>? ListAziende;
private List<AnagGruppi>? ListGruppiFase;
private List<Macchine>? ListMacchine;
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 6.16.2503.2116</h4>
<h4>Versione: 6.16.2504.418</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2503.2116
6.16.2504.418
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2503.2116</version>
<version>6.16.2504.418</version>
<url>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>