626 lines
16 KiB
C#
626 lines
16 KiB
C#
using Newtonsoft.Json;
|
|
using SteamWare;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AppData
|
|
{
|
|
/// <summary>
|
|
/// Classe con metodi di supporto per COMUNICAZIONE
|
|
/// </summary>
|
|
public class ComLib
|
|
{
|
|
|
|
/// <summary>
|
|
/// Wrapper traduzione termini
|
|
/// </summary>
|
|
/// <param name="lemma"></param>
|
|
/// <returns></returns>
|
|
public static string traduci(string lemma)
|
|
{
|
|
return user_std.UtSn.Traduci(lemma);
|
|
}
|
|
#region conf posizioni redis
|
|
|
|
protected static string redOutPath = "NKC:SERV:BREQ";
|
|
protected static string redMsgCount = "NKC:SERV:BREQ:MCount";
|
|
protected static string redMsgList = "NKC:SERV:BREQ:MList";
|
|
|
|
#endregion
|
|
|
|
#region definizione classi impiegate con PROD
|
|
|
|
|
|
/// <summary>
|
|
/// Stati degli oggetti TAKT e Stack
|
|
/// </summary>
|
|
public enum CStatus
|
|
{
|
|
/// <summary>
|
|
/// Programmato
|
|
/// </summary>
|
|
Programmed = 0,
|
|
/// <summary>
|
|
/// In corso
|
|
/// </summary>
|
|
Running,
|
|
/// <summary>
|
|
/// Completato
|
|
/// </summary>
|
|
Done
|
|
}
|
|
/// <summary>
|
|
/// Stati degli oggetti Batch
|
|
/// </summary>
|
|
public enum BatchStatus
|
|
{
|
|
/// <summary>
|
|
/// CSV importato
|
|
/// </summary>
|
|
Imported = 0,
|
|
/// <summary>
|
|
/// Nesting richiesto (In corso)
|
|
/// </summary>
|
|
EstimationRequested,
|
|
/// <summary>
|
|
/// Nesting Completato
|
|
/// </summary>
|
|
EstimationDone,
|
|
/// <summary>
|
|
/// Nesting richiesto (In corso)
|
|
/// </summary>
|
|
NestRequested,
|
|
/// <summary>
|
|
/// Nesting Completato
|
|
/// </summary>
|
|
NestDone,
|
|
/// <summary>
|
|
/// Nesting approvato
|
|
/// </summary>
|
|
Approved,
|
|
/// <summary>
|
|
/// Nesting scartato
|
|
/// </summary>
|
|
Discarded
|
|
}
|
|
/// <summary>
|
|
/// Posizione / Activity degli oggetti Batch
|
|
/// </summary>
|
|
public enum BatchPosition
|
|
{
|
|
/// <summary>
|
|
/// Non iniziato
|
|
/// </summary>
|
|
NotStarted = 0,
|
|
/// <summary>
|
|
/// Stack In corso
|
|
/// </summary>
|
|
StackStarted,
|
|
/// <summary>
|
|
/// Stack Completato
|
|
/// </summary>
|
|
StackDone
|
|
}
|
|
|
|
public static string PositionStatusDescr(object value)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
ComLib.BatchPosition pStatus = (ComLib.BatchPosition)Enum.Parse(typeof(ComLib.BatchPosition), value.ToString());
|
|
switch (pStatus)
|
|
{
|
|
case BatchPosition.NotStarted:
|
|
answ = traduci("NotStarted");
|
|
break;
|
|
case BatchPosition.StackStarted:
|
|
answ = traduci("Stacking");
|
|
break;
|
|
case BatchPosition.StackDone:
|
|
answ = traduci("StackDone");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
public static string BatchStatusDescr(object value)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
ComLib.BatchStatus bStatus = (ComLib.BatchStatus)Enum.Parse(typeof(ComLib.BatchStatus), value.ToString());
|
|
switch (bStatus)
|
|
{
|
|
case BatchStatus.Imported:
|
|
answ = "Imported";
|
|
break;
|
|
case BatchStatus.EstimationRequested:
|
|
answ = "Estimation Requested";
|
|
break;
|
|
case BatchStatus.EstimationDone:
|
|
answ = "Estimation Completed";
|
|
break;
|
|
case BatchStatus.NestRequested:
|
|
answ = "Nesting Requested";
|
|
break;
|
|
case BatchStatus.NestDone:
|
|
answ = "Nesting Completed";
|
|
break;
|
|
case BatchStatus.Approved:
|
|
answ = "Nesting Approved";
|
|
break;
|
|
case BatchStatus.Discarded:
|
|
answ = "Nesting Discarded";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Stati degli oggetti PANEL/SHEET
|
|
/// </summary>
|
|
public enum PStatus
|
|
{
|
|
/// <summary>
|
|
/// Programmato
|
|
/// </summary>
|
|
Programmed = 0,
|
|
/// <summary>
|
|
/// Presente / letto su PROD e pronto su scissor lift
|
|
/// </summary>
|
|
Present,
|
|
/// <summary>
|
|
/// Stampa in corso
|
|
/// </summary>
|
|
Printing,
|
|
/// <summary>
|
|
/// Stampa completata
|
|
/// </summary>
|
|
Printed,
|
|
/// <summary>
|
|
/// Lavorazione in corso
|
|
/// </summary>
|
|
Machining,
|
|
/// <summary>
|
|
/// Lavorazione completata
|
|
/// </summary>
|
|
Machined,
|
|
/// <summary>
|
|
/// Completato / scaricato da macchina (anche su tavola di scarico)
|
|
/// </summary>
|
|
Out
|
|
}
|
|
/// <summary>
|
|
/// dati del materiale
|
|
/// </summary>
|
|
public class MaterialData
|
|
{
|
|
/// <summary>
|
|
/// Identificativo univoco del materiale (DA ANAGRAFICA db)
|
|
/// </summary>
|
|
public int MaterialId { get; set; }
|
|
/// <summary>
|
|
/// Codice P/N del materiale (cliente)
|
|
/// </summary>
|
|
public string MaterialPN { get; set; }
|
|
/// <summary>
|
|
/// Codice P/N del materiale (cliente)
|
|
/// </summary>
|
|
public string MaterialDescription { get; set; }
|
|
}
|
|
/// <summary>
|
|
/// Dati delal lavorazione
|
|
/// </summary>
|
|
public class WorkData
|
|
{
|
|
/// <summary>
|
|
/// Percorso del programma da eseguire
|
|
/// </summary>
|
|
public string ProgramPath { get; set; }
|
|
/// <summary>
|
|
/// Data inizio processing
|
|
/// </summary>
|
|
public DateTime DtStart { get; set; }
|
|
/// <summary>
|
|
/// Data fine processing
|
|
/// </summary>
|
|
public DateTime DtEnd { get; set; }
|
|
/// <summary>
|
|
/// Tempo di lavorazione in minuti decimali
|
|
/// </summary>
|
|
public double WorkTimeMin
|
|
{
|
|
get
|
|
{
|
|
double answ = 0;
|
|
if (DtStart != null && DtEnd != null)
|
|
{
|
|
try
|
|
{
|
|
answ = DtEnd.Subtract(DtStart).TotalMinutes;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singolo Pannello da lavorare
|
|
/// </summary>
|
|
public class Panel
|
|
{
|
|
/// <summary>
|
|
/// Identificativo univoco pannello
|
|
/// </summary>
|
|
public int PanelId { get; set; }
|
|
/// <summary>
|
|
/// Materiale
|
|
/// </summary>
|
|
public MaterialData Material { get; set; }
|
|
/// <summary>
|
|
/// Stato del pannello
|
|
/// </summary>
|
|
public PStatus Status { get; set; }
|
|
/// <summary>
|
|
/// Tempi processo x fase printing
|
|
/// </summary>
|
|
public WorkData Printing { get; set; }
|
|
/// <summary>
|
|
/// Tempi processo x fase CNC
|
|
/// </summary>
|
|
public WorkData Machining { get; set; }
|
|
/// <summary>
|
|
/// Tempi processo x scarico
|
|
/// </summary>
|
|
public WorkData Unloading { get; set; }
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Classe che rappresenta gli stack da lavorare
|
|
/// </summary>
|
|
public class WStack
|
|
{
|
|
/// <summary>
|
|
/// Identificativo univoco stack
|
|
/// </summary>
|
|
public int StackId { get; set; }
|
|
/// <summary>
|
|
/// Stato dello Stack di pannelli
|
|
/// </summary>
|
|
public CStatus Status { get; set; }
|
|
/// <summary>
|
|
/// Codice dataMAtrix dello stack
|
|
/// </summary>
|
|
public string DataMatrix { get; set; }
|
|
/// <summary>
|
|
/// Data inizio processing dello Stack
|
|
/// </summary>
|
|
public DateTime DtStart { get; set; }
|
|
/// <summary>
|
|
/// Data inizio processing dello Stack
|
|
/// </summary>
|
|
public DateTime DtEnd { get; set; }
|
|
/// <summary>
|
|
/// Elenco dei pannelli(sheets) dello Stack
|
|
/// </summary>
|
|
public List<Panel> PanelsList { get; set; }
|
|
/// <summary>
|
|
/// Numero di Panels da lavorare
|
|
/// </summary>
|
|
public int NumPanels
|
|
{
|
|
get
|
|
{
|
|
int answ = 0;
|
|
try
|
|
{
|
|
answ = PanelsList.Count;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Oggetto globale TAKT
|
|
/// </summary>
|
|
public class Takt
|
|
{
|
|
/// <summary>
|
|
/// Codice univoco oggetto TAKT (data.num)
|
|
/// </summary>
|
|
public string TaktId { get; set; }
|
|
/// <summary>
|
|
/// Stato del TAKT
|
|
/// </summary>
|
|
public CStatus Status { get; set; }
|
|
/// <summary>
|
|
/// Elenco degli Stack da lavorare
|
|
/// </summary>
|
|
public List<WStack> StackList { get; set; }
|
|
/// <summary>
|
|
/// Numero di Stack da lavorare
|
|
/// </summary>
|
|
public int NumStack
|
|
{
|
|
get
|
|
{
|
|
int answ = 0;
|
|
try
|
|
{
|
|
answ = StackList.Count;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region definizione classi impiegate con NEST
|
|
|
|
|
|
public class Parte
|
|
{
|
|
public int PartId { get; set; }
|
|
public string DataMatrix { get; set; }
|
|
public string ExtCode { get; set; }
|
|
public string Description { get; set; }
|
|
public int MatId { get; set; }
|
|
public string PostProc { get; set; }
|
|
public string ProcessReq { get; set; }
|
|
public string CadFilePath { get; set; }
|
|
public int Qty { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Classe gestione richeiste di processing per il NESTING
|
|
/// </summary>
|
|
public class Ordine
|
|
{
|
|
public string OrdCod { get; set; }
|
|
public string DestPlant { get; set; }
|
|
public string DataMatrix { get; set; }
|
|
public string ExtCode { get; set; }
|
|
public string Model { get; set; }
|
|
public int Qty { get; set; }
|
|
public List<Parte> Items { get; set; }
|
|
}
|
|
public class Batch
|
|
{
|
|
/// <summary>
|
|
/// ID del batch in esecuzione
|
|
/// </summary>
|
|
public int BatchId { get; set; }
|
|
/// <summary>
|
|
/// tempo amssimo eprmesso x nesting (minuti)
|
|
/// </summary>
|
|
public int maxTime { get; set; }
|
|
/// <summary>
|
|
/// Tipo di processing richeisto
|
|
/// </summary>
|
|
public int procType { get; set; }
|
|
/// <summary>
|
|
/// Elenco degli ordini
|
|
/// </summary>
|
|
public List<Ordine> Orders { get; set; }
|
|
}
|
|
/// <summary>
|
|
/// Salva su redis l'oggetto dei materiali serializzato
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static bool sendMaterials()
|
|
{
|
|
bool answ = false;
|
|
// leggo tab MNATERIALS da DB
|
|
var table = DataLayer.man.taMat.GetData();
|
|
// serializzo
|
|
string redVal = JsonConvert.SerializeObject(table);
|
|
// salvo
|
|
string redKey = $"NKC:SERV:CONF:MATERIALS";
|
|
// scrivo per ora solo su REDIS
|
|
memLayer.ML.setRSV(redKey, redVal);
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Restituisce il prossimo codice di envelope per comunicare con sistemi esterni
|
|
/// </summary>
|
|
/// <param name="BatchID">Batch contenuto nell'envelope</param>
|
|
/// <param name="note">note opzionali (motivo envelope)</param>
|
|
/// <returns></returns>
|
|
public static string getNextEnv(int BatchID, string note)
|
|
{
|
|
// incremento counter
|
|
long nextIndex = memLayer.ML.setRCntI(redMsgCount);
|
|
// salvo contenuto della busta
|
|
string answ = $"Z{nextIndex:000000000000}";
|
|
Dictionary<string, string> lista = new Dictionary<string, string>();
|
|
lista.Add(answ, $"{BatchID}|{note}");
|
|
memLayer.ML.redSaveHashDict(redMsgList, lista);
|
|
// ritorno
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invia una richiesta di esecuzione di Nesting x un Batch
|
|
/// </summary>
|
|
/// <param name="BatchID">Batch di cui si chiede processing</param>
|
|
/// <param name="note">note opzionali</param>
|
|
/// <returns></returns>
|
|
public static bool sendBatchReq(int BatchID, string note)
|
|
{
|
|
bool answ = false;
|
|
// per prima cosa mi serve una "nuova busta" per inviare i messaggi
|
|
string nextEnv = getNextEnv(BatchID, note);
|
|
// preparo il contenuto della busta ed invio i messaggi...
|
|
try
|
|
{
|
|
// in base allo stato del BATCH corrente determino il tempo e le opzioni da inviare...
|
|
var batch = DataLayer.man.taBL.getByKey(BatchID);
|
|
int mTime = 1;
|
|
int pType = 1;
|
|
if (batch[0].STATUS < (int)BatchStatus.EstimationDone)
|
|
{
|
|
mTime = memLayer.ML.cdvi("estimMaxTime");
|
|
}
|
|
else
|
|
{
|
|
mTime = memLayer.ML.cdvi("nestMaxTime");
|
|
pType = 2;
|
|
}
|
|
// leggo tab ORDINI da DB
|
|
var tblOrd = DataLayer.man.taOL.getByBatch(BatchID);
|
|
// serializzo
|
|
string redVal = JsonConvert.SerializeObject(tblOrd);
|
|
// salvo
|
|
string redKey = $"{redOutPath}:{nextEnv}:ORDERS";
|
|
// scrivo su REDIS
|
|
memLayer.ML.setRSV(redKey, redVal);
|
|
|
|
var tblItm = DataLayer.man.taIL.getByBatch(BatchID);
|
|
// serializzo
|
|
redVal = JsonConvert.SerializeObject(tblItm);
|
|
// salvo
|
|
redKey = $"{redOutPath}:{nextEnv}:ITEMS";
|
|
// scrivo su REDIS
|
|
memLayer.ML.setRSV(redKey, redVal);
|
|
// ora versione gerarchica
|
|
var currBatch = new Batch()
|
|
{
|
|
BatchId = BatchID,
|
|
maxTime = mTime,
|
|
procType = pType
|
|
};
|
|
// serializzo
|
|
redVal = JsonConvert.SerializeObject(currBatch);
|
|
// salvo
|
|
redKey = $"{redOutPath}:{nextEnv}:DATA";
|
|
// scrivo su REDIS
|
|
memLayer.ML.setRSV(redKey, redVal);
|
|
|
|
// invio notifica che c'è una busta da processare
|
|
redKey = $"{redOutPath}:CURR";
|
|
// scrivo su REDIS
|
|
memLayer.ML.setRSV(redKey, nextEnv);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
// restituisco ok
|
|
return answ;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region metodi helper di conversione
|
|
|
|
/// <summary>
|
|
/// Helper x serializzare l'oggetto
|
|
/// </summary>
|
|
/// <param name="currData"></param>
|
|
/// <returns></returns>
|
|
public static string serializeTakt(Takt currData)
|
|
{
|
|
string answ = JsonConvert.SerializeObject(currData);
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Helper x deserializzare l'oggetto
|
|
/// </summary>
|
|
/// <param name="rawData"></param>
|
|
/// <returns></returns>
|
|
public static Takt deserializeTakt(string rawData)
|
|
{
|
|
Takt answ = JsonConvert.DeserializeObject<Takt>(rawData);
|
|
return answ;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region metodi x data persistence
|
|
|
|
/// <summary>
|
|
/// Salvo il Takt inviato
|
|
/// </summary>
|
|
/// <param name="origin">Origine del dato: SERV / PROD / NEST</param>
|
|
/// <param name="currData"></param>
|
|
/// <returns></returns>
|
|
public static bool saveTakt(string origin, Takt currData)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// calcolo valori redis
|
|
string redKey = $"NKC:{origin.ToUpper()}:TAKT:{currData.TaktId}";
|
|
string redVal = serializeTakt(currData);
|
|
// scrivo per ora solo su REDIS
|
|
memLayer.ML.setRSV(redKey, redVal);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvo il Takt inviato
|
|
/// </summary>
|
|
/// <param name="origin">Origine del dato: SERV / PROD / NEST</param>
|
|
/// <param name="currData"></param>
|
|
/// <returns></returns>
|
|
public static Takt readTakt(string origin, string TaktId)
|
|
{
|
|
Takt answ = null;
|
|
try
|
|
{
|
|
string redKey = $"NKC:{origin.ToUpper()}:TAKT:{TaktId}";
|
|
string redVal = memLayer.ML.getRSV(redKey);
|
|
answ = deserializeTakt(redVal);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
#region metodi per PROD
|
|
|
|
/// <summary>
|
|
/// Fornisce il prossimo TAKT da elaborare oppure null se non ce ne fossero altri da elaborare per la data CORRENTE
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Takt prodGetNextTakt()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|