Update x gestione chiusura ODL

This commit is contained in:
Samuele Locatelli
2022-10-17 12:01:33 +02:00
parent 7f9685a007
commit de562b1287
10 changed files with 354 additions and 121 deletions
+115 -8
View File
@@ -199,15 +199,18 @@ namespace MP.Data.Controllers
public async Task<List<StatODLModel>> StatOdl(int IdxOdl)
{
List<StatODLModel> dbResult = new List<StatODLModel>();
using (var dbCtx = new MoonProContext(_configuration))
if (IdxOdl > 0)
{
var IdxODL = new SqlParameter("@IdxODL", IdxOdl);
using (var dbCtx = new MoonProContext(_configuration))
{
var IdxODL = new SqlParameter("@IdxODL", IdxOdl);
dbResult = await dbCtx
.DbSetStatOdl
.FromSqlRaw("EXEC stp_STAT_ODL @IdxODL", IdxODL)
.AsNoTracking()
.ToListAsync();
dbResult = await dbCtx
.DbSetStatOdl
.FromSqlRaw("EXEC stp_STAT_ODL @IdxODL", IdxODL)
.AsNoTracking()
.ToListAsync();
}
}
return dbResult;
}
@@ -421,7 +424,7 @@ namespace MP.Data.Controllers
.FirstOrDefault();
if (currRec != null)
{
currRec.Valore= editRec.Valore;
currRec.Valore = editRec.Valore;
dbCtx.Entry(currRec).State = EntityState.Modified;
}
else
@@ -730,6 +733,110 @@ namespace MP.Data.Controllers
return fatto;
}
/// <summary>
/// Stato prod macchina
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
public StatoProdModel StatoProdMacchina(string idxMacchina)
{
StatoProdModel dbResult = new StatoProdModel();
using (var dbCtx = new MoonProContext(_configuration))
{
var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
dbResult = dbCtx
.DbSetStatoProd
.FromSqlRaw("EXEC stp_PzProd_getByMacchina @IdxMacchina", IdxMacchina)
.AsNoTracking()
.FirstOrDefault();
}
return dbResult;
}
/// <summary>
/// Chiusura ODL con eventuale conferma pezzi
/// </summary>
/// <param name="idxOdl">idx odl da chiudere</param>
/// <param name="idxMacchina">idx macchina</param>
/// <param name="matrOpr">matricola operatore</param>
/// <param name="confPezzi">indica se confermare i pezzi prima di chiudere ODL</param>
/// <param name="confRett">Conferma con rettifica (ev 121) x pezzi lasciati in macchina</param>
/// <param name="modoConfProd">Modo conferma produzione (0=periodo, 1=giorno, 2=turno)</param>
/// <returns></returns>
public async Task<bool> ODLClose(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi, bool confRett, int modoConfProd)
{
bool fatto = false;
if (idxOdl > 0)
{
using (var dbCtx = new MoonProContext(_configuration))
{
DateTime adesso = DateTime.Now;
// preparo i parametri
var IdxODL = new SqlParameter("@IdxODL", idxOdl);
var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
// FARE FIXME TODO !!!
// da valutare casi setup/autoconferma...
#if false
// controllo se HO pezzi da confermare...
var statoProd = StatoProdMacchina(idxMacchina);
if (statoProd.pezziNonConfermati < 1)
{ }
#endif
// se richiesto confermo produzione
if (confPezzi)
{
var MatrApp = new SqlParameter("@MatrApp", idxMacchina);
/* ----------------------------------
* CONFERMA PEZZI
*
* condizioni da verificare:
* - gestione rettifica (ev121) / pezzi da LASCIARE in macchina
* - conferma a zero pezzi (setup) oppure con i pezzi fatti e non ancora confermati
*
*
*
* */
// recupero i dati dei pezzi da confermare... con DbSetPzProd + exec stp_PzProd_getByMacchina 'SIMUL_01'
// stp_ConfermaProduzCompletaFull
/*
* @idxMacchina NVARCHAR(50),
@MatrApp INT,
@dataFrom DATETIME,
@dataTo DATETIME,
@pezziConf INT,
@pezziLasciati INT, -- pezzi lasciati = evento 121 (-) pre conferma e (+) dopo --> da lasciare in macchina post conferma
@pezziScar INT = 0, -- pezzi scartati (registrati da 2016.11.20) DA INDICARE COME VALORE > 0!!! sennò faccio ABS...
@TipoConf INT = 0, -- Tipo intervallo conferma: 0 = periodo intero, 1 = per giorni, 2 = per turni
@DataOraApp DATETIME = NULL, -- di norma GETDATE() nel programma - serve per ricalcolo
@TestConferma BIT = 1 -- TestConferma : 1 = verifica conf. duplicata e inserisci in ElencoConfermeProd, 0 = nessuna verifica e inserimento ( per ricalcolo )
*/
}
// ora chiudo ODL
try
{
var dbResult = await dbCtx
.DbSetStatOdl
.FromSqlRaw("EXEC stp_ODL_fineProd @IdxODL, @IdxMacchina", IdxODL, IdxMacchina)
.AsNoTracking()
.ToListAsync();
}
catch (Exception exc)
{
Log.Error($"Eccezione durante ODLClose{Environment.NewLine}{exc}");
}
}
}
return fatto;
}
/// <summary>
/// Annulla modifiche su una specifica entity (cancel update)
/// </summary>
+20
View File
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data.DatabaseModels
{
public partial class StatoProdModel
{
[Key]
public string idxMacchina { get; set; } = "NA";
public int pezziNonConfermati { get; set; } = 0;
public DateTime DataFrom { get; set; } = DateTime.Now;
public DateTime DataTo { get; set; } = DateTime.Now;
}
}
+1
View File
@@ -49,6 +49,7 @@ namespace MP.Data
public virtual DbSet<FluxLog> DbSetFluxLog { get; set; }
public virtual DbSet<Dossiers> DbSetDossiers { get; set; }
public virtual DbSet<StatODLModel> DbSetStatOdl { get; set; }
public virtual DbSet<StatoProdModel> DbSetStatoProd { get; set; }
#endregion Public Properties
+28 -1
View File
@@ -12,10 +12,26 @@ else if (totalCount == 0)
else
{
<div class="row">
@if (currRecord != null && !showStats && isCurrOdl)
{
<div class="col-6 col-lg-8">
</div>
<div class="col-6 col-lg-4 text-end">
@*<div class="px-2 input-group" title="Selezionare Data-Ora chiusura ODL">
<label class="input-group-text" for="dtMax"><i class="fa-regular fa-calendar-minus"></i></label>
<input class="form-control" @bind="@selDtFine" id="dtMax" type="datetime-local">
<button @onclick="() => chiudiOdl()" class="btn btn-danger btn-sm btn-">Registra chiusura ODL <i class="far fa-stop-circle"></i></button>
</div>*@
<button @onclick="() => chiudiOdl()" class="btn btn-danger btn-sm btn-">Registra chiusura ODL <i class="far fa-stop-circle"></i></button>
</div>
}
<div class="col-12">
<table class="table table-sm table-striped">
<thead>
<tr>
<th>
<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
</th>
<th><i class="fa-solid fa-file"></i> Articolo</th>
<th><i class="fa-solid fa-screwdriver-wrench"></i> Fase</th>
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
@@ -28,6 +44,17 @@ else
@foreach (var record in ListRecords)
{
<tr class="@checkSelect(@record.IdxOdl)">
<td>
@if (isCurrOdl)
{
<button class="btn btn-primary btn-sm" @onclick="() => selRecord(record)"><i class="fa-solid fa-magnifying-glass"></i></button>
}
else
{
<button class="btn btn-secondary btn-sm disabled"><i class="fa-solid fa-magnifying-glass"></i></button>
}
</td>
<td>
@record.CodArticolo
<div class="small textConsensed text-secondary">@record.ArticoloNav.DescArticolo</div>
@@ -114,7 +141,7 @@ else
</div>
</div>
<div class="modal-body col-12">
@if (currRecord != null)
@if (currRecord != null && showStats)
{
<div class="d-flex justify-content-between">
<div class="col-8">
+52 -3
View File
@@ -60,6 +60,22 @@ namespace MP.SPEC.Components
#region Protected Methods
/// <summary>
/// Registra chiusura ODL alla data indicata
/// </summary>
/// <returns></returns>
protected async Task chiudiOdl()
{
if (currRecord != null)
{
// effettua chiusura sul DB
await MDService.ODLClose(currRecord.IdxOdl, currRecord.IdxMacchina, 0, true);
// ricarica...
await selectRecord(null);
}
await reloadData();
}
protected override async Task OnInitializedAsync()
{
ListStati = await MDService.AnagStatiComm();
@@ -75,26 +91,43 @@ namespace MP.SPEC.Components
await InvokeAsync(() =>
{
PagerResetReq.InvokeAsync(true);
//currPage = 1;
Task task = UpdateData();
StateHasChanged();
});
}
protected async Task resetSel()
{
await selectRecord(null);
await reloadData();
}
protected async Task selectRecord(ODLModel? currRec)
{
showStats = true;
await Task.Delay(1);
currRecord = currRec;
if (currRec != null)
{
showStats = true;
ListOdlStats = await MDService.StatOdl(currRec.IdxOdl);
}
else
{
showStats = false;
ListOdlStats = null;
}
}
protected async Task selRecord(ODLModel? currRec)
{
await Task.Delay(1);
selDtFine = DateTime.Now;
currRecord = currRec;
showStats = false;
ListOdlStats = null;
}
protected async Task UpdateData()
{
await selectRecord(null);
@@ -106,11 +139,13 @@ namespace MP.SPEC.Components
#region Private Fields
private ODLModel? currRecord = null;
private List<StatODLModel>? ListOdlStats;
private List<double>? ListOdlStatsData = new List<double>();
private List<string>? ListOdlStatsLabels = new List<string>();
private List<ODLModel>? ListRecords;
private List<ListValues>? ListStati;
private List<ODLModel>? SearchRecords;
#endregion Private Fields
@@ -123,6 +158,14 @@ namespace MP.SPEC.Components
set => MessageService.currPage = value;
}
/// <summary>
/// Indica se si tratti di ODL correnti
/// </summary>
private bool isCurrOdl
{
get => currFilter.IsActive;
}
private bool isLoading { get; set; } = false;
private int numRecord
@@ -131,6 +174,12 @@ namespace MP.SPEC.Components
set => MessageService.numRecord = value;
}
private DateTime selDtFine { get; set; } = DateTime.Now;
private bool showStats { get; set; } = false;
#if false
private List<double>? ListOdlStatsData = new List<double>();
private List<string>? ListOdlStatsLabels = new List<string>();
#endif
private int totalCount { get; set; } = 0;
#endregion Private Properties
+134 -105
View File
@@ -127,6 +127,41 @@ namespace MP.SPEC.Data
return result;
}
/// <summary>
/// Elenco Codice articolo con dati dossier gestiti
/// </summary>
/// <returns></returns>
public async Task<List<string>> ArticleWithDossier()
{
List<string>? result = new List<string>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = redisArtByDossier;
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
readType = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ArticleWithDossier());
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<string>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ArticleWithDossier | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Eliminazione record selezionato
/// </summary>
@@ -274,69 +309,6 @@ namespace MP.SPEC.Data
return await Task.FromResult(dbController.ConfigUpdate(updRec));
}
public List<FluxLogDTO> getFluxLog(string Valore)
{
List<FluxLogDTO> answ = new List<FluxLogDTO>();
DossierFluxLogDTO? result = JsonConvert.DeserializeObject<DossierFluxLogDTO>(Valore);
if (result != null)
{
if (result.ODL != null)
{
answ = result
.ODL
.OrderBy(x => x.CodFlux)
.ToList();
// inizializzo SE necessario
foreach (var item in answ)
{
item.ValoreEdit = String.IsNullOrEmpty(item.ValoreEdit) ? item.Valore : item.ValoreEdit;
}
}
}
return answ;
}
public async Task<bool> updateDossierValue(Dossiers currDoss, FluxLogDTO editFL)
{
bool answ = false;
// recupero intero set valori dossier deserializzando...
var fluxLogList = getFluxLog(currDoss.Valore);
await Task.Delay(1);
// se tutto ok
if (fluxLogList != null)
{
// da provare...!!!!
// elimino vecchio record
var currRec = fluxLogList.FirstOrDefault(x => x.CodFlux == editFL.CodFlux && x.dtEvento == editFL.dtEvento);
if (currRec != null)
{
fluxLogList.Remove(currRec);
// aggiungo nuovo
fluxLogList.Add(editFL);
}
// serializzo nuovamente valore
DossierFluxLogDTO? result = new DossierFluxLogDTO();
var ODLflux = result.ODL.ToList();
foreach (var item in fluxLogList)
{
ODLflux.Add(item);
}
DossierFluxLogDTO updatedResult = new DossierFluxLogDTO(){ODL = ODLflux};
string rawVal = JsonConvert.SerializeObject(updatedResult);
currDoss.Valore = rawVal;
// aggiorno record sul DB
await dbController.DossiersUpdateValore(currDoss);
}
return answ;
}
public void Dispose()
{
// Clear database controller
@@ -454,16 +426,6 @@ namespace MP.SPEC.Data
return Task.FromResult(dbController.AnagGruppiAziende());
}
/// <summary>
/// Statistiche ODL calcolate (da stored stp_STAT_ODL)
/// </summary>
/// <returns></returns>
public Task<List<StatODLModel>> StatOdl(int IdxOdl)
{
return dbController.StatOdl(IdxOdl);
}
/// <summary>
/// Restitusice elenco fasi
/// </summary>
@@ -514,6 +476,28 @@ namespace MP.SPEC.Data
return Task.FromResult(currTagConf);
}
public List<FluxLogDTO> getFluxLog(string Valore)
{
List<FluxLogDTO> answ = new List<FluxLogDTO>();
DossierFluxLogDTO? result = JsonConvert.DeserializeObject<DossierFluxLogDTO>(Valore);
if (result != null)
{
if (result.ODL != null)
{
answ = result
.ODL
.OrderBy(x => x.CodFlux)
.ToList();
// inizializzo SE necessario
foreach (var item in answ)
{
item.ValoreEdit = String.IsNullOrEmpty(item.ValoreEdit) ? item.Valore : item.ValoreEdit;
}
}
}
return answ;
}
/// <summary>
/// restituisce il valore da REDIS associato al tag richeisto
/// </summary>
@@ -624,40 +608,38 @@ namespace MP.SPEC.Data
return result;
}
/// <summary>
/// Elenco Codice articolo con dati dossier gestiti
/// Effettua chiusura dell'ODL indicato, andand
/// </summary>
/// <returns></returns>
public async Task<List<string>> ArticleWithDossier()
/// <param name="idxOdl">idx odl da chiudere</param>
/// <param name="idxMacchina">idx macchina</param>
/// <param name="matrOpr">matricola operatore</param>
/// <param name="confPezzi">indica se confermare i pezzi priam di chiudere ODL</param>
public async Task<bool> ODLClose(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi)
{
List<string>? result = new List<string>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string readType = "DB";
string currKey = redisArtByDossier;
// cerco in redis dato valore sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
bool fatto = false;
await Task.Delay(1);
// recupero dati x conf modalità conferma
var configData = await ConfigGetAll();
if (configData != null)
{
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
readType = "REDIS";
bool confRett = false;
var currRec = configData.FirstOrDefault(x => x.Chiave == "confRett");
if (currRec != null)
{
bool.TryParse(currRec.Valore, out confRett);
}
int modoConfProd = 0;
currRec = configData.FirstOrDefault(x => x.Chiave == "modoConfProd");
if (currRec != null)
{
int.TryParse(currRec.Valore, out modoConfProd);
}
// chiamo metodo conferma!
fatto = await dbController.ODLClose(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd);
}
else
{
result = await Task.FromResult(dbController.ArticleWithDossier());
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<string>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ArticleWithDossier | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
return fatto;
}
/// <summary>
@@ -716,6 +698,55 @@ namespace MP.SPEC.Data
return await dbController.PODLUpdateRecord(currRec);
}
/// <summary>
/// Statistiche ODL calcolate (da stored stp_STAT_ODL)
/// </summary>
/// <returns></returns>
public Task<List<StatODLModel>> StatOdl(int IdxOdl)
{
return dbController.StatOdl(IdxOdl);
}
public async Task<bool> updateDossierValue(Dossiers currDoss, FluxLogDTO editFL)
{
bool answ = false;
// recupero intero set valori dossier deserializzando...
var fluxLogList = getFluxLog(currDoss.Valore);
await Task.Delay(1);
// se tutto ok
if (fluxLogList != null)
{
// da provare...!!!!
// elimino vecchio record
var currRec = fluxLogList.FirstOrDefault(x => x.CodFlux == editFL.CodFlux && x.dtEvento == editFL.dtEvento);
if (currRec != null)
{
fluxLogList.Remove(currRec);
// aggiungo nuovo
fluxLogList.Add(editFL);
}
// serializzo nuovamente valore
DossierFluxLogDTO? result = new DossierFluxLogDTO();
var ODLflux = result.ODL.ToList();
foreach (var item in fluxLogList)
{
ODLflux.Add(item);
}
DossierFluxLogDTO updatedResult = new DossierFluxLogDTO() { ODL = ODLflux };
string rawVal = JsonConvert.SerializeObject(updatedResult);
currDoss.Valore = rawVal;
// aggiorno record sul DB
await dbController.DossiersUpdateValore(currDoss);
}
return answ;
}
#endregion Public Methods
#region Protected Fields
@@ -741,6 +772,7 @@ namespace MP.SPEC.Data
#region Private Fields
private const string redisArtByDossier = redisBaseAddr + "SPEC:Cache:ArtByDossier";
private const string redisBaseAddr = "MP:";
private const string redisConfKey = redisBaseAddr + "SPEC:Cache:Config";
@@ -750,9 +782,6 @@ namespace MP.SPEC.Data
private const string redisFluxByMac = redisBaseAddr + "SPEC:Cache:FluxByMac";
private const string redisMacByFlux = redisBaseAddr + "SPEC:Cache:MacByFlux";
private const string redisArtByDossier = redisBaseAddr + "SPEC:Cache:ArtByDossier";
private const string redisMacList = redisBaseAddr + "SPEC:Cache:MacList";
private const string redisStatoCom = redisBaseAddr + "SPEC:Cache:StatoCom";
+1 -1
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP.SPEC</RootNamespace>
<Version>6.16.2210.1417</Version>
<Version>6.16.2210.1711</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 6.16.2210.1417</h4>
<h4>Versione: 6.16.2210.1711</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2210.1417
6.16.2210.1711
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2210.1417</version>
<version>6.16.2210.1711</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>