Completato fix metodo AutoODL (da testare!)
This commit is contained in:
@@ -78,6 +78,7 @@ namespace MP.Core
|
||||
|
||||
public const string redisTipoArt = redisBaseAddr + "Cache:TipoArt";
|
||||
|
||||
public const string redisVetoSplitOdl = redisBaseAddr + "Cache:VetoOdlMacc";
|
||||
public const string redisVocabolario = redisBaseAddr + "Cache:Vocabolario";
|
||||
|
||||
public const string redisXdlData = redisBaseAddr + "Cache:XDL:";
|
||||
|
||||
@@ -96,6 +96,140 @@ namespace MP.Data.Controllers
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apre in automatico un nuovo PODL/ODL chiudendo l'attuale (aperto)
|
||||
/// </summary>
|
||||
/// <param name="idxOdl">Idx ODL corrente</param>
|
||||
/// <param name="MatrOpr">Matricola operatore</param>
|
||||
/// <param name="idxMacchina">idx macchina da confermare</param>
|
||||
/// <param name="tCRich">TempoCiclo richiesto in attrezzaggio</param>
|
||||
/// <param name="pzPallet"># pz pallet</param>
|
||||
/// <param name="note">note ODL</param>
|
||||
/// <param name="startNewOdl">bool per avvio nuovo ODL (def: true)</param>
|
||||
/// <param name="qtyRich">Qty da produrre, deve essere >0</param>
|
||||
/// <param name="keyRich">KeyRich esterno, se vuoto uso vecchia, se KIT sovrascritto con KeyKit</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> AutoStartOdlAsync(int idxOdl, int MatrOpr, string idxMacchina, decimal tCRich, int pzPallet, string note, bool startNewOdl, int qtyRich, string keyRich)
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
var IdxOdl = new SqlParameter("@idxOdl ", idxOdl);
|
||||
var MatrApp = new SqlParameter("@MatrApp ", MatrOpr);
|
||||
var IdxMacchina = new SqlParameter("@idxMacchina", idxMacchina);
|
||||
var TCRich = new SqlParameter("@TCRichAttr", tCRich);
|
||||
var PzPallet = new SqlParameter("@PzPallet", pzPallet);
|
||||
var Note = new SqlParameter("@Note", note);
|
||||
var StartNewOdl = new SqlParameter("@StartNewOdl", startNewOdl);
|
||||
var QtyRich = new SqlParameter("@QtyRich", qtyRich);
|
||||
var KeyRichiesta = new SqlParameter("@KeyRichiesta", keyRich);
|
||||
|
||||
var result = await dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRawAsync("EXEC stp_ODL_AutoStart @idxOdl, @MatrApp, @idxMacchina, @TCRichAttr, @PzPallet, @Note, @StartNewOdl, @QtyRich, @KeyRichiesta", IdxOdl, MatrApp, IdxMacchina, TCRich, PzPallet, Note, StartNewOdl, QtyRich, KeyRichiesta);
|
||||
|
||||
// indico eseguito!
|
||||
answ = result > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in ConfermaProdMacchina:{Environment.NewLine}{exc}");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma - dtEvent)
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina">idx macchina da confermare</param>
|
||||
/// <param name="modoConfProd">0=periodo, 1 = giorno, 2 = turno</param>
|
||||
/// <param name="numPzConfermati">qta pezzi BUONI da confermare</param>
|
||||
/// <param name="numPzScarto">qta pezzi SCARTO da confermare</param>
|
||||
/// <param name="DataOraApp">DataOra in cui registrare approvazione</param>
|
||||
/// <param name="MatrOpr">Matricola operatore</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> ConfermaProdMacchinaAsync(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzScarto, DateTime DataOraApp, int MatrOpr)
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
var rigaProd = await StatoProdMacchinaAsync(idxMacchina, DateTime.Now);
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
var IdxMacchina = new SqlParameter("@idxMacchina", idxMacchina);
|
||||
var MatrApp = new SqlParameter("@MatrApp ", MatrOpr);
|
||||
var DataFrom = new SqlParameter("@dataFrom ", rigaProd.DataFrom);
|
||||
var DataTo = new SqlParameter("@dataTo", DataOraApp);
|
||||
var PezziConf = new SqlParameter("@pezziConf", numPzConfermati);
|
||||
var PezziScar = new SqlParameter("@pezziScar", numPzScarto);
|
||||
var TipoConf = new SqlParameter("@TipoConf", modoConfProd);
|
||||
var DtOraApp = new SqlParameter("@DataOraApp", DataOraApp);
|
||||
var TestConferma = new SqlParameter("@TestConferma", true);
|
||||
|
||||
var result = await dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRawAsync("EXEC stp_ConfermaProduzCompleta @idxMacchina, @MatrApp, @dataFrom, @dataTo, @pezziConf, @pezziScar, @TipoConf, @DataOraApp, @TestConferma ", IdxMacchina, MatrApp, DataFrom, DataTo, PezziConf, PezziScar, TipoConf, DtOraApp, TestConferma);
|
||||
|
||||
// indico eseguito!
|
||||
answ = result > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in ConfermaProdMacchina:{Environment.NewLine}{exc}");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma - dtEvent)
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina">idx macchina da confermare</param>
|
||||
/// <param name="modoConfProd">0=periodo, 1 = giorno, 2 = turno</param>
|
||||
/// <param name="numPzConfermati">qta pezzi BUONI da confermare</param>
|
||||
/// <param name="numPzLasciati">qta pezzi LASCIATI da confermare</param>
|
||||
/// <param name="numPzScarto">qta pezzi SCARTO da confermare</param>
|
||||
/// <param name="DataOraApp">DataOra in cui registrare approvazione</param>
|
||||
/// <param name="MatrOpr">Matricola operatore</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> ConfermaProdMacchinaFullAsync(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzLasciati, int numPzScarto, DateTime DataOraApp, int MatrOpr)
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
var rigaProd = await StatoProdMacchinaAsync(idxMacchina, DateTime.Now);
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
var IdxMacchina = new SqlParameter("@idxMacchina", idxMacchina);
|
||||
var MatrApp = new SqlParameter("@MatrApp ", MatrOpr);
|
||||
var DataFrom = new SqlParameter("@dataFrom ", rigaProd.DataFrom);
|
||||
var DataTo = new SqlParameter("@dataTo", DataOraApp);
|
||||
var PezziConf = new SqlParameter("@pezziConf", numPzConfermati);
|
||||
var PezziLasc = new SqlParameter("@pezziLasciati", numPzLasciati);
|
||||
var PezziScar = new SqlParameter("@pezziScar", numPzScarto);
|
||||
var TipoConf = new SqlParameter("@TipoConf", modoConfProd);
|
||||
var DtOraApp = new SqlParameter("@DataOraApp", DataOraApp);
|
||||
var TestConferma = new SqlParameter("@TestConferma", true);
|
||||
var Force = new SqlParameter("@Force", false);
|
||||
|
||||
var result = await dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRawAsync("EXEC stp_ConfermaProduzCompletaFull @idxMacchina, @MatrApp, @dataFrom, @dataTo, @pezziConf, @pezziLasciati, @pezziScar, @TipoConf, @DataOraApp, @TestConferma,@Force", IdxMacchina, MatrApp, DataFrom, DataTo, PezziConf, PezziLasc, PezziScar, TipoConf, DtOraApp, TestConferma, Force);
|
||||
|
||||
// indico eseguito!
|
||||
answ = result > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in ConfermaProdMacchinaAsync:{Environment.NewLine}{exc}");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Record ConfFlux dato macchina (oppure tutti se vuoto)
|
||||
/// </summary>
|
||||
@@ -326,6 +460,65 @@ namespace MP.Data.Controllers
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
/// <summary>
|
||||
/// Fix ODL per macchine SLAVE
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina"></param>
|
||||
/// <param name="numDayPrev"></param>
|
||||
/// <param name="doInsert"></param>
|
||||
/// <returns></returns>
|
||||
public bool OdlFixMachineSlave(string idxMacchina, int numDayPrev, int doInsert)
|
||||
{
|
||||
bool fatto = false;
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina);
|
||||
var NumDayPrev = new SqlParameter("@NumDayPrev", numDayPrev);
|
||||
var DoInsert = new SqlParameter("@DoInsert", doInsert);
|
||||
var result = dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRaw("EXEC stp_ODL_fixMachineSlave @IdxMacchina, @NumDayPrev, @DoInsert", IdxMacc, NumDayPrev, DoInsert);
|
||||
fatto = result != 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante OdlFixMachineSlave{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fix ODL per macchine SLAVE Async
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina"></param>
|
||||
/// <param name="numDayPrev"></param>
|
||||
/// <param name="doInsert"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> OdlFixMachineSlaveAsync(string idxMacchina, int numDayPrev, int doInsert)
|
||||
{
|
||||
bool fatto = false;
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina);
|
||||
var NumDayPrev = new SqlParameter("@NumDayPrev", numDayPrev);
|
||||
var DoInsert = new SqlParameter("@DoInsert", doInsert);
|
||||
var result = await dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRawAsync("EXEC stp_ODL_fixMachineSlave @IdxMacchina, @NumDayPrev, @DoInsert", IdxMacc, NumDayPrev, DoInsert);
|
||||
fatto = result != 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante OdlFixMachineSlaveAsync{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiamata x stored recupero FluxLog x macchina (first)
|
||||
@@ -1130,7 +1323,38 @@ namespace MP.Data.Controllers
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in RicalcMse:{Environment.NewLine}{exc}");
|
||||
Log.Error($"Eccezione in RecalcMse:{Environment.NewLine}{exc}");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
/// <summary>
|
||||
/// Effettua ricalcolo MSE x macchina indicata
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina">idx macchina da confermare</param>
|
||||
/// <param name="maxAgeSec">Num massimo secondi di "vecchiaia" del dato</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> RecalcMseAsync(string idxMacchina, int maxAgeSec)
|
||||
{
|
||||
bool answ = false;
|
||||
try
|
||||
{
|
||||
var rigaProd = await StatoProdMacchinaAsync(idxMacchina, DateTime.Now);
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
var MaxAgeSec = new SqlParameter("@maxAgeSec ", maxAgeSec);
|
||||
var IdxMacchina = new SqlParameter("@idxMacchina", idxMacchina);
|
||||
|
||||
var result = await dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRawAsync("EXEC stp_MSE_recalc @maxAgeSec, @idxMacchina ", MaxAgeSec, IdxMacchina);
|
||||
|
||||
// indico eseguito!
|
||||
answ = result > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in RecalcMseAsync:{Environment.NewLine}{exc}");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
@@ -326,6 +326,37 @@ namespace MP.IOC.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiude ODL precedente ed avvia uno nuovo (duplicandolo e sitemando quantità RIMANENTE),
|
||||
/// e CONFERMA produzione...
|
||||
///
|
||||
/// GET: IOB/forceSplitOdl/SIMUL_03
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns>Esito chiamata (OK/vuoto)</returns>
|
||||
|
||||
[HttpGet("forceSplitOdl/{id}")]
|
||||
public async Task<IActionResult> ForceSplitOdl(string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID");
|
||||
|
||||
// Multi: gestione carattere "|" trasformato in "#"
|
||||
id = id.Replace("|", "#");
|
||||
|
||||
string answ = "";
|
||||
|
||||
try
|
||||
{
|
||||
answ = await DService.AutoStartOdlAsync(id, true, true, 100, 0, "");
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in ForceSplitOdl{Environment.NewLine}{exc}");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, "NO");
|
||||
}
|
||||
return Ok(answ);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupera ArtNum dato CodXdl (per impianti che accettano solo INT in scrittura):
|
||||
/// GET: IOB/getArtNum/SIMUL_03?CodXdl=ABC123
|
||||
|
||||
@@ -246,6 +246,70 @@ namespace MP.IOC.Data
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiunge un set di task x macchina all'elenco di quelli salvati (in modalità upsert)
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina"></param>
|
||||
/// <param name="taskKey"></param>
|
||||
/// <param name="taskVal"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> AddTask4MacListAsync(string idxMacchina, Dictionary<Enums.taskType, string> taskDict)
|
||||
{
|
||||
bool answ = false;
|
||||
bool needSaveParams = false;
|
||||
var currHash = Utils.RedKeyTask2ExeMacc(idxMacchina, MpIoNS);
|
||||
var currSavedParHash = Utils.RedKeySavedTask2ExeMacc(idxMacchina, MpIoNS);
|
||||
Dictionary<string, string> currTask = new Dictionary<string, string>();
|
||||
Dictionary<string, string> savedTask = new Dictionary<string, string>();
|
||||
|
||||
// leggo valori attuali...
|
||||
currTask = await mTaskMacchinaAsync(idxMacchina);
|
||||
// verifico processing dei ricevuti
|
||||
foreach (var item in taskDict)
|
||||
{
|
||||
if (currTask.ContainsKey($"{item.Key}"))
|
||||
{
|
||||
currTask[$"{item.Key}"] = item.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
currTask.Add($"{item.Key}", item.Value);
|
||||
}
|
||||
Log.Trace($"Task ADD | hash: {currHash} | idxMacchina: {idxMacchina} | taskKey: {item.Key} | taskVal: {item.Value}");
|
||||
|
||||
// verifico in base al tipo di tName se fare backup...
|
||||
switch (item.Key)
|
||||
{
|
||||
case Enums.taskType.setArt:
|
||||
case Enums.taskType.setComm:
|
||||
case Enums.taskType.setPzComm:
|
||||
case Enums.taskType.setProg:
|
||||
// leggo tName SALVATI attuali...
|
||||
savedTask = mSavedTaskMacchina(idxMacchina);
|
||||
savedTask[item.Key.ToString()] = item.Value;
|
||||
needSaveParams = true;
|
||||
break;
|
||||
|
||||
case Enums.taskType.endProd:
|
||||
// salvo un DICT vuoto x resettare
|
||||
savedTask = new Dictionary<string, string>();
|
||||
needSaveParams = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// salvo!
|
||||
answ = await RedisSetHashDictAsync(currHash, currTask);
|
||||
|
||||
if (needSaveParams)
|
||||
{
|
||||
answ = await RedisSetHashDictAsync(currSavedParHash, savedTask);
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert record allarme
|
||||
/// </summary>
|
||||
@@ -549,6 +613,308 @@ namespace MP.IOC.Data
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua split ODL
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina">macchina</param>
|
||||
/// <param name="doConfirm">effettuare conferma qty</param>
|
||||
/// <param name="qtyFromLast">imposta la qty prox ODL da ODL che si chiude</param>
|
||||
/// <param name="matrOpr">matricola operatore</param>
|
||||
/// <param name="roundStep">Round Step quantità prox ODL (corrente come riferimento)</param>
|
||||
/// <param name="keyRichiesta">Cod ext da associare all'ODL</param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> AutoStartOdlAsync(string idxMacchina, bool doConfirm, bool qtyFromLast, int matrOpr, int roundStep = 100, string keyRichiesta = "")
|
||||
{
|
||||
string answ = "KO";
|
||||
DateTime adesso = DateTime.Now;
|
||||
|
||||
// verifico NON CI SIA un veto a NUOVI split...
|
||||
string redKey = $"{Utils.redisVetoSplitOdl}:{idxMacchina}";
|
||||
var rawData = await redisDb.StringGetAsync(redKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
Log.Info($"VETO ATTIVO | Richiesto forceSplitOdl per impianto {idxMacchina} | impossibile procedere");
|
||||
}
|
||||
else
|
||||
{
|
||||
// registro VETO x altri split... 5 minuti
|
||||
await redisDb.StringSetAsync(redKey, $"Inizio SPLIT-ODL {adesso}", TimeSpan.FromMinutes(5));
|
||||
// setup dati da config
|
||||
bool confRett = false;
|
||||
int modoConfProd = -1;
|
||||
bool slaveConfirmPzProd = false;
|
||||
var configData = await ConfigGetAllAsync();
|
||||
if (configData != null)
|
||||
{
|
||||
var currRec = configData.FirstOrDefault(x => x.Chiave == "confRett");
|
||||
if (currRec != null)
|
||||
{
|
||||
bool.TryParse(currRec.Valore, out confRett);
|
||||
}
|
||||
currRec = configData.FirstOrDefault(x => x.Chiave == "modoConfProd");
|
||||
if (currRec != null)
|
||||
{
|
||||
int.TryParse(currRec.Valore, out modoConfProd);
|
||||
}
|
||||
currRec = configData.FirstOrDefault(x => x.Chiave == "SlaveConfirmPzProd");
|
||||
if (currRec != null)
|
||||
{
|
||||
bool.TryParse(currRec.Valore, out slaveConfirmPzProd);
|
||||
}
|
||||
}
|
||||
// calcolo la qta da gestire
|
||||
int qtyConf = 0;
|
||||
int qtyNew = 0;
|
||||
int qtyScarto = 0;
|
||||
if (doConfirm)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rigaProd = await IocDbController.PezziProdMacchinaAsync(idxMacchina);
|
||||
var statoProd = await IocDbController.StatoProdMacchinaAsync(idxMacchina, adesso);
|
||||
qtyConf = rigaProd.pezziNonConfermati;
|
||||
qtyScarto = statoProd.Pz2RecScarto;
|
||||
// calcolo nuovi pezzi da confermare
|
||||
if (qtyFromLast)
|
||||
{
|
||||
roundStep = roundStep == 0 ? 1 : roundStep;
|
||||
double ratio = (double)qtyConf / roundStep;
|
||||
qtyNew = (int)Math.Round(Math.Ceiling(ratio) * roundStep, 0);
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"AutoStartOdlAsync | Errore recupero pezzi da confermare | idxMacchina {idxMacchina}{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
|
||||
// chiamo metodo redis/db...
|
||||
try
|
||||
{
|
||||
// recupero ODL corrente
|
||||
var currData = await IocDbController.OdlCurrByMaccAsync(idxMacchina);
|
||||
if (currData != null && currData.IdxOdl > 0)
|
||||
{
|
||||
// preparo var x master/slave
|
||||
bool isMachMaster = await IobIsMasterAsync(idxMacchina);
|
||||
List<Macchine2SlaveModel> slaveList = new();
|
||||
if (isMachMaster)
|
||||
{
|
||||
List<Macchine2SlaveModel> allSlaveList = await IocDbController.Macchine2SlaveAsync();
|
||||
slaveList = allSlaveList.Where(x => x.IdxMacchina == idxMacchina).ToList();
|
||||
}
|
||||
|
||||
// registro un evento di inizio attrezzaggio (idxTipoEv = 2)
|
||||
int idxEvento = 2;
|
||||
Log.Info($"Invio evento ODL-SPLIT per macchina {idxMacchina} | ev: {idxEvento} | art: {currData.CodArticolo} | qty conf: {qtyConf} | sty sca: {qtyScarto} | new qty: {qtyNew}");
|
||||
|
||||
// creo evento
|
||||
EventListModel newRecEv = new EventListModel()
|
||||
{
|
||||
CodArticolo = currData.CodArticolo,
|
||||
IdxMacchina = idxMacchina,
|
||||
IdxTipo = idxEvento,
|
||||
InizioStato = adesso,
|
||||
MatrOpr = matrOpr,
|
||||
pallet = "",
|
||||
Value = "ODL-SPLIT"
|
||||
};
|
||||
inputComandoMapo resCmd = await scriviRigaEventoBarcodeAsync(newRecEv);
|
||||
|
||||
// era 100, messo 50...
|
||||
int wTime = 50;
|
||||
|
||||
// eventuale conferma produzione
|
||||
if (doConfirm)
|
||||
{
|
||||
await Task.Delay(wTime);
|
||||
adesso = DateTime.Now;
|
||||
// chiamo conferma produzione...
|
||||
try
|
||||
{
|
||||
string chiamata = confRett ? "confermaProdMacchinaFull" : "confermaProdMacchina";
|
||||
Log.Info($"Chiamata a {chiamata} con parametri {currData.IdxMacchina} |{matrOpr} | {DateTime.Now.AddDays(-10)} | {DateTime.Now} | {qtyConf} | 0 | {qtyScarto} | {DateTime.Now} | false");
|
||||
string idxMacchinaSel = currData.IdxMacchina;
|
||||
bool fatto = false;
|
||||
if (confRett)
|
||||
{
|
||||
// confermo al netto dei pezzi lasciati...
|
||||
fatto = await IocDbController.ConfermaProdMacchinaFullAsync(idxMacchinaSel, modoConfProd, qtyConf, 0, qtyScarto, adesso, matrOpr);
|
||||
if (slaveConfirmPzProd)
|
||||
{
|
||||
foreach (var machine in slaveList)
|
||||
{
|
||||
await IocDbController.ConfermaProdMacchinaFullAsync(machine.IdxMacchinaSlave, modoConfProd, qtyConf, 0, qtyScarto, adesso, matrOpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fatto = await IocDbController.ConfermaProdMacchinaAsync(idxMacchinaSel, modoConfProd, qtyConf, qtyScarto, adesso, matrOpr);
|
||||
if (slaveConfirmPzProd)
|
||||
{
|
||||
foreach (var machine in slaveList)
|
||||
{
|
||||
await IocDbController.ConfermaProdMacchinaAsync(idxMacchinaSel, modoConfProd, qtyConf, qtyScarto, adesso, matrOpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fatto)
|
||||
{
|
||||
Log.Error($"ERRORE in chiamata {chiamata}");
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in ConfermaProduzione{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
// 2025.02.19 portato da 100 a 1000 ms attesa x evitare che ODL sia avviato PRIMA della conferma
|
||||
// attendo 1000 msec x chiudere ODL
|
||||
await Task.Delay(1000);
|
||||
// chiamo splitOdl
|
||||
await IocDbController.AutoStartOdlAsync(currData.IdxOdl, 0, idxMacchina, currData.TCRichAttr, currData.PzPallet, $"Nuovo ODL da forceSplitOdl.autoStart", true, qtyNew, keyRichiesta);
|
||||
|
||||
// elimino eventuale ODL precedente...
|
||||
string currKey = $"{Utils.redisOdlCurrByMac}:{idxMacchina}";
|
||||
await redisDb.KeyDeleteAsync(currKey);
|
||||
|
||||
// ricalcola ODL macchina
|
||||
var newOdl = await GetCurrOdlAsync(idxMacchina);
|
||||
// attendo 1000 msec
|
||||
await Task.Delay(1000);
|
||||
|
||||
adesso = DateTime.Now;
|
||||
// registro fine ODL (idxTipoEv = 1)
|
||||
idxEvento = 1;
|
||||
Log.Info($"Invio evento FINE ODL-SPLIT | idx: {idxMacchina} | ev: {idxEvento} | art: {currData.CodArticolo}");
|
||||
// costruisco nuovo evento
|
||||
newRecEv = new EventListModel()
|
||||
{
|
||||
CodArticolo = currData.CodArticolo,
|
||||
IdxMacchina = idxMacchina,
|
||||
IdxTipo = idxEvento,
|
||||
InizioStato = adesso,
|
||||
MatrOpr = matrOpr,
|
||||
pallet = "",
|
||||
Value = "ODL-START"
|
||||
};
|
||||
resCmd = await scriviRigaEventoBarcodeAsync(newRecEv);
|
||||
// invio eventi setup a macchina....
|
||||
string setArtVal = $"{currData.CodArticolo}";
|
||||
string setPzCommVal = $"{qtyNew}";
|
||||
string setCommVal = $"ODL{newOdl}";
|
||||
if (!string.IsNullOrEmpty(keyRichiesta))
|
||||
{
|
||||
setCommVal = $"{keyRichiesta} ODL{newOdl}";
|
||||
}
|
||||
try
|
||||
{
|
||||
// invio task caricamento dati ODL
|
||||
Dictionary<taskType, string> updDict = new Dictionary<taskType, string>();
|
||||
updDict.Add(taskType.setArt, setArtVal);
|
||||
updDict.Add(taskType.setComm, setCommVal);
|
||||
updDict.Add(taskType.setPzComm, setPzCommVal);
|
||||
#if false
|
||||
addTask4Machine(idxMacchina, taskType.setArt, setArtVal);
|
||||
addTask4Machine(idxMacchina, taskType.setComm, setCommVal);
|
||||
addTask4Machine(idxMacchina, taskType.setPzComm, setPzCommVal);
|
||||
|
||||
updateMachineParameter(idxMacchina, "setArt", setArtVal);
|
||||
updateMachineParameter(idxMacchina, "setComm", setCommVal);
|
||||
updateMachineParameter(idxMacchina, "setPzComm", setPzCommVal);
|
||||
#endif
|
||||
// recupero set attuale parametri
|
||||
var currMachPar = await MachineParamListAsync(idxMacchina);
|
||||
List<ObjItemDTO> list2upd = new();
|
||||
// aggiorno i valori interessati tra quelli nel dizionario
|
||||
foreach (var item in updDict)
|
||||
{
|
||||
var cRec = currMachPar.FirstOrDefault(x => x.uid == $"{item.Key}");
|
||||
if (cRec != null)
|
||||
{
|
||||
list2upd.Add(cRec);
|
||||
}
|
||||
}
|
||||
// aggiungo task di setParameters x la commessa...
|
||||
updDict.Add(taskType.setParameter, setCommVal);
|
||||
// salvo
|
||||
await AddTask4MacListAsync(idxMacchina, updDict);
|
||||
await MachineParamUpsertAsync(idxMacchina, list2upd);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
// chiamo refresh MSE
|
||||
await IocDbController.RecalcMseAsync(idxMacchina, 0);
|
||||
// resetto stato macchina...
|
||||
var kStatoMacc = $"{Utils.redisStatoMacch}:{idxMacchina}";
|
||||
await redisDb.KeyDeleteAsync(kStatoMacc);
|
||||
answ = "OK";
|
||||
Log.Info($"Effettuato reset e ricalcoli x split ODL per macchina {idxMacchina}");
|
||||
// se è una master richiamo fix x child...
|
||||
if (isMachMaster)
|
||||
{
|
||||
Dictionary<taskType, string> updDict = new Dictionary<taskType, string>();
|
||||
string ts = "";
|
||||
string outData = "";
|
||||
await IocDbController.OdlFixMachineSlaveAsync(idxMacchina, 30, 1);
|
||||
foreach (var machine in slaveList)
|
||||
{
|
||||
// invio chiusura attrezzaggio
|
||||
ts = string.Format("{0:yyMMdd}T{0:HHmmss.fff}Z", DateTime.Now);
|
||||
outData = $"TS:{ts}|MATR:{matrOpr}|ODL:{newOdl}";
|
||||
|
||||
updDict.Clear();
|
||||
updDict.Add(taskType.setArt, setArtVal);
|
||||
updDict.Add(taskType.setComm, setCommVal);
|
||||
updDict.Add(taskType.setPzComm, setPzCommVal);
|
||||
|
||||
|
||||
#if false
|
||||
addTask4Machine(machine.IdxMacchinaSlave, taskType.fixStopSetup, outData);
|
||||
addTask4Machine(machine.IdxMacchinaSlave, taskType.forceResetPzCount, outData);
|
||||
// invio task caricamento dati ODL
|
||||
addTask4Machine(machine.IdxMacchinaSlave, taskType.setArt, setArtVal);
|
||||
addTask4Machine(machine.IdxMacchinaSlave, taskType.setComm, setCommVal);
|
||||
addTask4Machine(machine.IdxMacchinaSlave, taskType.setPzComm, setPzCommVal);
|
||||
|
||||
updateMachineParameter(machine.IdxMacchinaSlave, "setArt", setArtVal);
|
||||
updateMachineParameter(machine.IdxMacchinaSlave, "setComm", setCommVal);
|
||||
updateMachineParameter(machine.IdxMacchinaSlave, "setPzComm", setPzCommVal);
|
||||
#endif
|
||||
|
||||
// recupero set attuale parametri
|
||||
var currMachPar = await MachineParamListAsync(machine.IdxMacchinaSlave);
|
||||
List<ObjItemDTO> list2upd = new();
|
||||
// aggiorno i valori interessati tra quelli nel dizionario
|
||||
foreach (var item in updDict)
|
||||
{
|
||||
var cRec = currMachPar.FirstOrDefault(x => x.uid == $"{item.Key}");
|
||||
if (cRec != null)
|
||||
{
|
||||
list2upd.Add(cRec);
|
||||
}
|
||||
}
|
||||
// aggiungo task di setParameters x la commessa...
|
||||
updDict.Add(taskType.fixStopSetup, outData);
|
||||
updDict.Add(taskType.forceResetPzCount, outData);
|
||||
updDict.Add(taskType.setParameter, setCommVal);
|
||||
// salvo
|
||||
await AddTask4MacListAsync(machine.IdxMacchinaSlave, updDict);
|
||||
await MachineParamUpsertAsync(machine.IdxMacchinaSlave, list2upd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione in forceSplitOdl{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
|
||||
public string CalcRecipe(RecipeModel currRecipe)
|
||||
{
|
||||
return mongoController.CalcRecipe(currRecipe);
|
||||
@@ -1379,6 +1745,31 @@ namespace MP.IOC.Data
|
||||
return val != null && (val == "1" || val.ToLower() == "true");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce il valore booleano se la macchina sia master
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> IobIsMasterAsync(string idxMacchina)
|
||||
{
|
||||
var key = Utils.RedKeyDatiMacc(idxMacchina, MpIoNS);
|
||||
|
||||
// 1. Tentativo ottimizzato: leggiamo solo il campo che ci serve
|
||||
// Supponendo che tu usi StackExchange.Redis direttamente o un wrapper
|
||||
string? val = await redisDb.HashGetAsync(key, "Master");
|
||||
|
||||
// 2. Se non c'è in cache, carichiamo/resettiamo tutto
|
||||
if (val == null)
|
||||
{
|
||||
//var data = ResetDatiMacchina(idxMacchina);
|
||||
var data = await ResetDatiMacchinaAsync(idxMacchina);
|
||||
data.TryGetValue("Master", out val);
|
||||
}
|
||||
|
||||
// 3. Parsing sicuro
|
||||
return val != null && (val == "1" || val.ToLower() == "true");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="IdxOdl">idxMacc odl da cercare</param>
|
||||
@@ -2042,10 +2433,24 @@ namespace MP.IOC.Data
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Info(string.Format("Errore in mTaskMacchina | idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina));
|
||||
Log.Error(string.Format("Errore in mTaskMacchina | idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina));
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
/// <summary>
|
||||
/// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Dictionary<string, string>> mTaskMacchinaAsync(string idxMacchina)
|
||||
{
|
||||
// hard coded dimensione vettore DatiMacchine
|
||||
Dictionary<string, string> answ = new Dictionary<string, string>();
|
||||
// ORA recupero da memoria redis...
|
||||
var currHash = Utils.RedKeyTask2ExeMacc(idxMacchina, MpIoNS);
|
||||
answ = await RedisGetHashDictAsync(currHash);
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generazione autoOdl
|
||||
@@ -4650,6 +5055,32 @@ namespace MP.IOC.Data
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scrive una riga di evento manuale (barcode) nel db + check cambio stato DiarioDiBordo
|
||||
/// </summary>
|
||||
/// <param name="newRec">codice macchina</param>
|
||||
/// <returns></returns>
|
||||
private async Task<inputComandoMapo> scriviRigaEventoBarcodeAsync(EventListModel newRec)
|
||||
{
|
||||
bool inserito = false;
|
||||
try
|
||||
{
|
||||
// inserisco evento
|
||||
inserito = await IocDbController.EvListInsertAsync(newRec);
|
||||
// faccio controllo per eventuale cambio stato da tab transizioni...
|
||||
checkCambiaStatoBatch(tipoInputEvento.barcode, newRec.IdxMacchina, newRec.InizioStato ?? DateTime.Now, newRec.IdxTipo, newRec.CodArticolo, newRec.Value, newRec.MatrOpr, newRec.pallet);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Errore in scriviRigaEvento | IdxMacchina {newRec.IdxMacchina} | IdxTipo {newRec.IdxTipo} | codArticolo {newRec.CodArticolo} | Value {newRec.Value} | MatrOpr {newRec.MatrOpr} | Pallet {newRec.pallet} | dTime {newRec.InizioStato}{Environment.NewLine}{exc}");
|
||||
}
|
||||
// formatto output
|
||||
inputComandoMapo answ = new inputComandoMapo();
|
||||
answ.outValue = inserito.ToString();
|
||||
answ.needStatusRefresh = true;
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce il valore booleano se la macchina sia abilitata all'inserimento COMPLETO nel
|
||||
/// Signal Log
|
||||
@@ -4751,7 +5182,6 @@ namespace MP.IOC.Data
|
||||
{
|
||||
answ = currRec.Valore;
|
||||
}
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>6.16.2604.1618</Version>
|
||||
<Version>6.16.2604.1708</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MP-IOC </i>
|
||||
<h4>Versione: 6.16.2604.1618</h4>
|
||||
<h4>Versione: 6.16.2604.1708</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.16.2604.1618
|
||||
6.16.2604.1708
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>6.16.2604.1618</version>
|
||||
<version>6.16.2604.1708</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>
|
||||
|
||||
Reference in New Issue
Block a user