Files
2025-07-24 13:01:57 +02:00

1481 lines
56 KiB
C#

using MapoDb;
using MapoSDK;
using SteamWare;
using System;
using System.Text;
using System.Web.Routing;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MoonProTablet.WebUserControls
{
public partial class mod_ODL : BaseUserControl
{
#region Public Events
/// <summary>
/// registrato nuovo valore
/// </summary>
public event EventHandler eh_reqUpdate;
#endregion Public Events
#region Public Properties
/// <summary>
/// Cod articolo dell'ODL selezionato
/// </summary>
public string CodArtSel
{
get
{
string CodArticolo = "";
try
{
CodArticolo = DataLayerObj.taODL.getByIdx(idxODLSel, false)[0].CodArticolo;
}
catch
{ }
return CodArticolo;
}
}
/// <summary>
/// Verifica se la macchina NON abbia ODL (valido, > 0)
/// </summary>
public bool emptyOdlAltraMacc
{
get
{
return (idxOdlAltraMacc == "" || idxOdlAltraMacc == "0");
}
}
/// <summary>
/// Verifica se la macchina NON abbia ODL (valido, > 0)
/// </summary>
public bool emptyOdlMacc
{
get
{
return (idxOdlMacc == "" || idxOdlMacc == "0");
}
}
/// <summary>
/// idx macchina selezionata
/// </summary>
public new string idxMacchinaFix
{
get
{
string answ = "";
try
{
answ = memLayer.ML.StringSessionObj(string.Format("idxMacchina-{0}", uid));
}
catch
{ }
return answ;
}
set
{
memLayer.ML.setSessionVal(string.Format("idxMacchina-{0}", uid), value);
cmp_selPODL.idxMacchinaFix = value;
cmp_newODL.idxMacchinaFix = value;
}
}
/// <summary>
/// IdxODL su ALTRA macchina (se multi)
/// </summary>
public string idxOdlAltraMacc
{
get
{
if (_idxOdlAltraMacc == null)
{
_idxOdlAltraMacc = DataLayerObj.currODL(idxMaccAltraTav, true);
}
return _idxOdlAltraMacc;
}
set
{
_idxOdlAltraMacc = value;
}
}
/// <summary>
/// IdxODL sulla macchina
/// </summary>
public string idxOdlMacc
{
get
{
if (_idxOdlMacc == null)
{
_idxOdlMacc = DataLayerObj.currODL(idxMacchinaFix, true);
}
return _idxOdlMacc;
}
set
{
_idxOdlMacc = value;
}
}
/// <summary>
/// codice odl selezionato
/// </summary>
public int idxODLSel
{
get
{
return cmp_selPODL.idxODLSel;
}
}
/// <summary>
/// Determina se sia abilitato il controllo x editing
/// </summary>
public bool isEnabled
{
get
{
bool answ = false;
try
{
answ = memLayer.ML.BoolSessionObj(string.Format("isEnabled-{0}", uid));
}
catch
{ }
return answ;
}
set
{
memLayer.ML.setSessionVal(string.Format("isEnabled-{0}", uid), value);
}
}
/// <summary>
/// Testo x button creazione nuovo ODL
/// </summary>
public string lblCreaOdl
{
get
{
string answ = "CREAZIONE ODL PROVVISORIO";
if (cmp_newODL.Visible)
{
answ = "NASCONDI creazione ODL provvisorio";
}
return answ;
}
}
public bool maccInAttr
{
get
{
bool answ = false;
// controllo se la macchina è in attrezzaggio...
DS_applicazione.StatoMacchineRow rigaStato = null;
try
{
// se è multi controllo parent...
if (isMulti)
{
rigaStato = selData.mng.rigaStato(idxMaccParent);
}
else
{
rigaStato = selData.mng.rigaStato(idxMacchinaFix);
}
answ = (rigaStato.IdxStato == 2);
}
catch (Exception exc)
{
logger.lg.scriviLog(string.Format("Eccezione in recupero dati rigaStato! {0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION);
}
return answ;
}
}
#endregion Public Properties
#region Public Methods
public void checkAll()
{
lblOut.Text = "";
checkBtnStatus();
divOdlProvv.Visible = showOdlProvvVal;
divOpRiattr.Visible = (showSplitOdlOnTavVal || showReopOdlTav);
lbtSplitOdlSuTav.Visible = showSplitOdlOnTavVal;
lbtReopOdlSuTav.Visible = showReopOdlTav;
lbtFixEndSetup.Visible = !maccInAttr && memLayer.ML.CRB("OptEnableFixSetup");
}
public void hideAll()
{
divDettPOdl.Visible = false;
}
#endregion Public Methods
#region Internal Methods
internal void fixODL()
{
cmp_dettODL.fixODL();
}
#endregion Internal Methods
#region Protected Fields
/// <summary>
/// Valore protected idxODL
/// </summary>
protected string _idxOdlAltraMacc;
/// <summary>
/// Valore protected idxODL
/// </summary>
protected string _idxOdlMacc;
#endregion Protected Fields
#region Protected Properties
/// <summary>
/// Verifica chiave chkCloseOdl in tab Config
/// </summary>
protected bool chkCloseOdlVal
{
get
{
return memLayer.ML.cdvb("chkCloseOdl");
}
}
/// <summary>
/// Verifica chiave enableAnnullaSetup in tab Config
/// </summary>
protected bool enableAnnullaSetup
{
get
{
return memLayer.ML.cdvb("enableAnnullaSetup");
}
}
/// <summary>
/// Restituisce il codice IdxMacchina dell'altra tavola (se multi) altrimenti la stessa macchina...
/// </summary>
protected string idxMaccAltraTav
{
get
{
string answ = "";
try
{
// verifico se SIA una tavola (ha char "#")
int iSharp = idxMacchinaFix.IndexOf('#');
if (iSharp > 0)
{
// ora verifico SE ALTRA TAVOLA ha ODL...
string nomeTav = idxMacchinaFix.Substring(iSharp);
string altraTav = nomeTav.Substring(0, nomeTav.Length - 1);
altraTav += nomeTav.EndsWith("1") ? "2" : "1";
// sistemo nome
answ = idxMacchinaFix.Replace(nomeTav, altraTav);
}
}
catch
{ }
return answ;
}
}
/// <summary>
/// valore INT di num Pz per Pallet...
/// </summary>
protected int PzPallet
{
get
{
int answ = 1;
try
{
answ = cmp_selPzPallet.pzPallet;
}
catch (Exception exc)
{
logger.lg.scriviLog($"Eccezione in recupero PzPallet{Environment.NewLine}{exc}");
}
return answ;
}
set
{
cmp_selPzPallet.pzPallet = value;
}
}
/// <summary>
/// Verifica chiave showChkCloseOdl in tab Config
/// </summary>
protected bool showChkCloseOdlVal
{
get
{
return memLayer.ML.cdvb("showChkCloseOdl");
}
}
/// <summary>
/// Verifica chiave showOdlProvv in tab Config
/// </summary>
protected bool showOdlProvvVal
{
get
{
return memLayer.ML.cdvb("showOdlProvv");
}
}
/// <summary>
/// Verifica visibilità btn riprendi ODL su 2° tavola SE:
/// - sia un impianto MULTI (= con + tavole)
/// - sia disattrezzata la tavola
/// - in tab congif: se sia abilitato la ripresa ODL sulla seconda tavola
/// - in tab config: sia il grace period
/// - NON SIANO passati i minuti indicati dalla chiusura
/// </summary>
protected bool showReopOdlTav
{
get
{
bool answ = false;
// se è multi controllo
if (isMulti)
{
// verifico se NON HA ODL...
if (emptyOdlMacc)
{
// verifico SE siamo nel gracePeriod
int gPeriod = memLayer.ML.cdvi("gPeriodReopenOdlTav");
DateTime adesso = DateTime.Now;
DateTime dtChiusura = DateTime.Now.AddHours(-1);
try
{
dtChiusura = DataLayerObj.taODL.getLastByMacc(idxMacchinaFix)[0].DataFine;
}
catch
{ }
// ora verifico SE E SOLO SE è ANCORA in attrezzaggio
if (maccInAttr)
{
// ora verifico SE ALTRA TAVOLA ha ODL...
if (dtChiusura.AddMinutes(gPeriod) > adesso)
{
answ = memLayer.ML.cdvb("showReopenOdlTav");
}
}
}
}
return answ;
}
}
/// <summary>
/// Verifica visibilità btn split ODL su 2° tavola SE:
/// - sia un impianto MULTI (= con + tavole)
/// - sia già attrezzata la prima tavola
/// - in tab Congif: se sia abilitato lo split ODL sulla seconda tavola
/// - la macchina SIA ANCORA in attrezzaggio (2019.07.08) = 2
/// </summary>
protected bool showSplitOdlOnTavVal
{
get
{
bool answ = false;
// se è multi controllo
if (isMulti)
{
// verifico se NON HA ODL ma ce l'ha altra tavola...
if (emptyOdlMacc)
{
// ora verifico SE ALTRA TAVOLA ha ODL...
if (!emptyOdlAltraMacc)
{
// ora verifico SE E SOLO SE è ANCORA in attrezzaggio
if (maccInAttr)
{
answ = memLayer.ML.cdvb("showSplitOdlOnTav");
}
}
}
}
return answ;
}
}
/// <summary>
/// Verifica se la tavola SIA in fase di attrezzaggio, ovvero SE:
/// - sia un impianto MULTI (= con + tavole)
/// - sia già attrezzata
/// </summary>
protected bool tavHasOdl
{
get
{
bool answ = false;
// se è multi controllo
if (isMulti)
{
answ = !emptyOdlMacc;
}
return answ;
}
}
/// <summary>
/// valore decimal del TC richiesto...
/// </summary>
protected decimal TCRichAttr
{
get
{
decimal answ = 0;
try
{
answ = mod_tempoMSMC.tempoMC;
}
catch
{ }
return answ;
}
set
{
mod_tempoMSMC.tempoMC = value;
}
}
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Sistema CSS x status enabled/disabled
/// </summary>
/// <param name="lbtn"></param>
protected void fixWCtrStatus(object lbtn)
{
// tolgo (eventuale) classe
try
{
((WebControl)lbtn).CssClass = ((WebControl)lbtn).CssClass.Replace("disabled", "");
// se richiesto metto disabled...
if (!((WebControl)lbtn).Enabled)
{
((WebControl)lbtn).CssClass += " disabled";
}
}
catch
{ }
}
/// <summary>
/// Annulla setup ODL (come se avesse fatto FINE PROD)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtAnnullaSetup_Click(object sender, EventArgs e)
{
// leggo idxOdl da ultimo odl attivo x macchina
int idxODLCurr = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL;
int idxEvento = 7; // !!!HARD CODED
try
{
// confermo prod vecchio ODL
confermaProdOdl(true);
// processo x macchina selezionata
DataLayerObj.taODL.fineProd(idxODLCurr, idxMacchinaFix);
string evText = "Registrata ANNULLAMENTO ATTREZZAGGIO per ODL {0}";
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format(evText, idxODLCurr));
processaEvento(idxMacchinaFix, idxEvento, sb.ToString(), idxODLCurr);
// resetta PODL e rimuove ODL x poi TOGLIERE info di setup su macchina corrente
DataLayerObj.taODL.clearSetup(idxODLCurr, idxMacchinaFix);
// se è master --> chiamo update child!
if (isMaster)
{
DataLayerObj.taODL.fixMachineSlave(idxMacchina, 30, 1);
}
// cancella dati correnti ODL
doRemoveCurrOdlData();
// aggiorna dettaglio ODL
cmp_selPODL.DataBind();
}
catch
{ }
// refresh finale
checkAll();
// sollevo evento!
if (eh_reqUpdate != null)
{
eh_reqUpdate(this, new EventArgs());
}
}
protected void lbtConfNewRevProd_Click(object sender, EventArgs e)
{
// chiamo stored x allineare revProd a revUT
string CodArticolo = DataLayerObj.taODL.getByIdx(idxODLSel, false)[0].CodArticolo;
DataLayerObj.taAnagArt.setNewRev(CodArticolo);
checkBtnStatus();
}
/// <summary>
/// fine prod
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtEndProd_Click(object sender, EventArgs e)
{
// leggo idxOdl da ultimo odl attivo x macchina
int idxODLCurr = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL;
int idxEvento = 7; // !!!HARD CODED
// confermo prod vecchio ODL
confermaProdOdl(false);
// se chk flaggato ovvero richiesta di chiudere ODL procedo come prima (chiudendo ODL senza averne altri...)
if (chkCloseOdl.Checked)
{
// aggiungo try/catch x capire se sia qui che si "impasta" in chiusura ODL
try
{
// processo x macchina selezionata
DataLayerObj.taODL.fineProd(idxODLCurr, idxMacchinaFix);
string evText = "Registrata fine produzione per ODL {0}";
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format(evText, idxODLCurr));
processaEvento(idxMacchinaFix, idxEvento, sb.ToString(), idxODLCurr);
// se è multi processo ANCHE x altra tavola...
if (isMulti)
{
sb.AppendLine("---");
int idxOdlAltra = 0;
string _idxOdl = idxOdlAltraMacc;
int.TryParse(_idxOdl, out idxOdlAltra);
DataLayerObj.taODL.fineProd(idxOdlAltra, idxMaccAltraTav);
sb.AppendLine(String.Format(evText, idxOdlAltra));
processaEvento(idxMaccAltraTav, idxEvento, String.Format(evText, idxOdlAltra), idxOdlAltra);
}
// se è master --> chiamo update child!
if (isMaster)
{
DataLayerObj.taODL.fixMachineSlave(idxMacchina, 30, 1);
}
// riporto stringa
lblOut.Text = sb.ToString().Replace("---", "<br/>");
}
catch (Exception exc)
{
logger.lg.scriviLog(string.Format("Eccezione in operazione chiusura ODL! {0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION);
Response.Redirect("~/DettaglioMacchina.aspx");
}
}
// altrimenti split ODL x completare IN FUTURO la produzione...
else
{
try
{
// effettuo split su nuovo ODL
DataLayerObj.taODL.splitODL(idxODLCurr, DataLayerObj.MatrOpr, idxMacchinaFix, TCAssegnato(idxODLCurr), PzPallet, string.Format("Fine Produzione, Sospensione ODL {0}, generato residuo con pari TCiclo: {1}", idxODLCurr, TCAssegnato(idxODLCurr)), false, 0);
// processo chiusura setup
processaEvento(idxMacchinaFix, idxEvento, String.Format("Registrata fine produzione per ODL {0}, nuovo ODL per quantità residua", idxODLCurr), idxODLCurr);
// se è multi processo ANCHE x altra tavola...
if (isMulti)
{
int idxOdlAltra = 0;
string _idxOdl = idxOdlAltraMacc;
int.TryParse(_idxOdl, out idxOdlAltra);
// effettuo split su nuovo ODL
DataLayerObj.taODL.splitODL(idxOdlAltra, DataLayerObj.MatrOpr, idxMaccAltraTav, TCAssegnato(idxOdlAltra), PzPallet, string.Format("Fine Produzione, Sospensione ODL {0}, generato residuo con pari TCiclo: {1}", idxOdlAltra, TCAssegnato(idxOdlAltra)), false, 0);
// processo chiusura setup
processaEvento(idxMaccAltraTav, idxEvento, String.Format("Registrata fine produzione per ODL {0}, nuovo ODL per quantità residua", idxOdlAltra), idxOdlAltra);
}
// se è master --> chiamo update child!
if (isMaster)
{
DataLayerObj.taODL.fixMachineSlave(idxMacchina, 30, 1);
}
// sistemo buttons!
fixSplitBtn(false);
}
catch (Exception exc)
{
logger.lg.scriviLog(string.Format("Eccezione in operazione Chiusura + Split ODL su nuovo! {0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION);
Response.Redirect("~/DettaglioMacchina.aspx");
}
}
doRemoveCurrOdlData();
// refresh finale
checkAll();
// sollevo evento!
if (eh_reqUpdate != null)
{
eh_reqUpdate(this, new EventArgs());
}
}
protected void lbtFixEndSetup_Click(object sender, EventArgs e)
{
string ts = string.Format("{0:yyMMdd}T{0:HHmmss.fff}Z", DateTime.Now);
string outData = $"TS:{ts}|MATR:{DataLayerObj.MatrOpr}|ODL:{idxOdlMacc}";
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.fixStopSetup, outData);
outData = "Inserita richiesta invio Fix chiusura attrezzaggio " + outData;
lblOut.Text = outData;
// se è master --> chiamo update child!
if (isMaster)
{
// calcolo gli slave...
var slaveList = DataLayerObj.taM2S.getByMaster(idxMacchina);
foreach (var machine in slaveList)
{
outData = $"TS:{ts}|MATR:{DataLayerObj.MatrOpr}|ODL:{idxOdlMacc}|master machine:{idxMacchinaFix}";
// invio task x end produzione...
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.fixStopSetup, outData);
}
}
}
/// <summary>
/// Effettua ripresa ODL su tavola
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtReopOdlSuTav_Click(object sender, EventArgs e)
{
// chiamo stored x riprendere ODL (toglie data chiusura...)
DS_ProdTempi.ODLDataTable tabRes = DataLayerObj.taODL.reopenGetLast(idxMacchinaFix);
if (tabRes.Rows.Count > 0)
{
var riga = tabRes[0];
// messaggio utente
string evText = "Registrato riapertura ODL {0} | art {1}";
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format(evText, riga.IdxODL, riga.CodArticolo));
lblOut.Text = sb.ToString();
}
// update buttons...
checkAll();
// sollevo evento!
if (eh_reqUpdate != null)
{
eh_reqUpdate(this, new EventArgs());
}
}
/// <summary>
/// toggle visualizzazione creazione ODL provvisorio
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtShowCreaOdlProvv_Click(object sender, EventArgs e)
{
cmp_newODL.Visible = !cmp_newODL.Visible;
}
protected void lbtShowOdlDet_Click(object sender, EventArgs e)
{
divDettOdl.Visible = !divDettOdl.Visible;
}
/// <summary>
/// mostra dati ed opzione x split ODL
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtShowSplitODL_Click(object sender, EventArgs e)
{
fixSplitBtn(true);
// recupero current idx
int currODL = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL;
updateTempoTc(currODL, true);
updateNoteTC(currODL);
}
/// <summary>
/// split ODL con creazione nuovo ODL
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtSplitODL_Click(object sender, EventArgs e)
{
// chiamo stored che genera nuovo ODL, mette note e tempo, chiude vecchi e assegna nuovo...
int currODL = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL;
int idxEvento = 1; // !!!HARD CODED
// controllo se TC è valorizzato..
if (TCRichAttr == 0)
{
mod_tempoMSMC.checkTC();
}
// confermo prod vecchio ODL
confermaProdOdl(false);
// effettuo split su nuovo ODL
DataLayerObj.taODL.splitODL(currODL, DataLayerObj.MatrOpr, idxMacchinaFix, TCRichAttr, PzPallet, txtNote.Text, true, 0);
// se c'è gestione SchedaTecnica --> chiamo procedura update x lotti
if (enableSchedaTecnica)
{
int newODL = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL;
DataLayerObj.taMagELotti.UpsertByOdl(newODL, true);
}
// resetto ODL su redis...
DataLayerObj.emptyCurrODL(idxMacchinaFix);
// invio email!
DataLayerObj.sendWarnTcChangeReq(memLayer.ML.CRS("_adminEmail"));
// processo chiusura setup
processaEvento(idxMacchinaFix, idxEvento, String.Format("Registrato Riattrezzaggio ODL (old: {0})", currODL), currODL);
// sistemo buttons!
fixSplitBtn(false);
// sollevo evento!
if (eh_reqUpdate != null)
{
eh_reqUpdate(this, new EventArgs());
}
}
/// <summary>
/// Effettua split ODL da ALTRA tavola su tav corrente
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtSplitOdlSuTav_Click(object sender, EventArgs e)
{
// chiamo stored x splittare ODL...
int idxOdlAltra = 0;
int.TryParse(idxOdlAltraMacc, out idxOdlAltra);
// se ho trovato...
if (idxOdlAltra > 0)
{
DataLayerObj.taODL.dividiDaAltraTav(idxOdlAltra, DataLayerObj.MatrOpr, idxMacchinaFix);
// messaggio utente
string evText = "Registrata inizio attrezzaggio da split ODL {0} (come da altra tavola)";
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format(evText, idxOdlAltra));
lblOut.Text = sb.ToString();
}
// update button x setup da altra tavola...
checkAll();
// sollevo evento!
if (eh_reqUpdate != null)
{
eh_reqUpdate(this, new EventArgs());
}
}
/// <summary>
/// dichiara inizio attrezzaggio ODL indicato..
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtStartAttr_Click(object sender, EventArgs e)
{
/***************************************************
* comprende gestione machineSlave x fix ODL master --> slave
*
***************************************************/
bool inAttr = false;
// se è multi mi chiedo se sia DAVVERO in attrezzaggio...
if (isMulti)
{
try
{
// controllo se NON SONO già in attrezzaggio...
DS_applicazione.StatoMacchineRow rigaStato = selData.mng.rigaStato(idxMaccParent);
inAttr = (rigaStato.IdxStato == 2);
}
catch
{ }
}
// proseguo
int idxODL_curr = 0;
confermaProdOdl(false);
if (idxODLSel > 0)
{
// se vedesse TCRich a zero lo reimposta a quello assegnato...
if (TCRichAttr == 0)
{
TCRichAttr = TCAssegnato(idxODLSel);
}
int idxODLTemp = 0;
if (enableSplitODL)
{
// splitto VECCHIO ODL (se è rimasto qualcosa da produrre e se ce ne è rimasto uno.......)
try
{
idxODLTemp = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL;
DataLayerObj.taODL.splitODL(idxODLTemp, DataLayerObj.MatrOpr, idxMacchinaFix, TCAssegnato(idxODLTemp), PzPallet, string.Format("inizio attrezzaggio, Sospensione ODL {0}, generato residuo con pari TCiclo: {1}", idxODLTemp, TCAssegnato(idxODLTemp)), false, 0);
// se è multi processo ANCHE x altra tavola...
if (isMulti)
{
int _idxOdl = DataLayerObj.taODL.getByMacchina(idxMaccAltraTav)[0].IdxODL;
DataLayerObj.taODL.splitODL(_idxOdl, DataLayerObj.MatrOpr, idxMaccAltraTav, TCAssegnato(_idxOdl), PzPallet, string.Format("inizio attrezzaggio, Sospensione ODL {0}, generato residuo con pari TCiclo: {1}", _idxOdl, TCAssegnato(_idxOdl)), false, 0);
}
}
catch
{ }
}
// 2018.07.24 verifico se devo lavorare come ODL classico o come RPO (Richiesta / Promessa / ODL)
if (enableRPO)
{
// creo nuovo ODL da promessa ed associo
DateTime adesso = DateTime.Now;
DataLayerObj.taODL.inizioSetupPromessa(idxODLSel, DataLayerObj.MatrOpr, idxMacchinaFix, TCRichAttr, PzPallet, txtNote.Text, adesso);
// salvo ODL attrezzato
idxODL_curr = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL;
}
// ODL classico
else
{
// avvio NUOVO ODL
DataLayerObj.taODL.inizioSetup(idxODLSel, DataLayerObj.MatrOpr, idxMacchinaFix, TCRichAttr, PzPallet, txtNote.Text);
// salvo ODL Current
idxODL_curr = idxODLSel;
}
// process evento
int idxEvento = 2; // !!!HARD CODED
string evText = "Registrato inizio attrezzaggio per ODL {0}";
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format(evText, idxODL_curr));
processaEvento(idxMacchinaFix, idxEvento, sb.ToString(), idxODL_curr);
// indico INIZIO SETUP su REDIS come EXE della macchina...
string ts = string.Format("{0:yyMMdd}T{0:HHmmss.fff}Z", DateTime.Now);
string outData = $"TS:{ts}|MATR:{DataLayerObj.MatrOpr}|ODL:{idxODL_curr}";
// aggiungo articolo, commessa, richiesta pezzi...
try
{
var datiODL = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0];
string setArtVal = $"{datiODL.CodArticolo}";
string setPzCommVal = $"{datiODL.NumPezzi}";
string setCommVal = $"ODL{datiODL.IdxODL:000000}";
// FIXME TODO: scrivere come sotto? testare valvital x linea LASCO
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.startSetup, outData);
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.setArt, setArtVal);
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.setComm, setCommVal);
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.setPzComm, setPzCommVal);
DataLayerObj.updateMachineParameter(idxMacchinaFix, "setArt", setArtVal);
DataLayerObj.updateMachineParameter(idxMacchinaFix, "setComm", setCommVal);
DataLayerObj.updateMachineParameter(idxMacchinaFix, "setPzComm", setPzCommVal);
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.setParameter, "ForceUpdate");
// li aggiungo ANCHE sui PLC slave se ci sono...
if (isMaster)
{
// calcolo gli slave...
var slaveList = DataLayerObj.taM2S.getByMaster(idxMacchina);
foreach (var machine in slaveList)
{
outData = $"TS:{ts}|MATR:{DataLayerObj.MatrOpr}|Master Machine: {idxMacchinaFix}";
// invio chiusura attrezzaggio
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.startSetup, outData);
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.setArt, setArtVal);
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.setComm, setCommVal);
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.setPzComm, setPzCommVal);
DataLayerObj.updateMachineParameter(machine.IdxMacchinaSlave, "setArt", setArtVal);
DataLayerObj.updateMachineParameter(machine.IdxMacchinaSlave, "setComm", setCommVal);
DataLayerObj.updateMachineParameter(machine.IdxMacchinaSlave, "setPzComm", setPzCommVal);
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.setParameter, "ForceUpdate");
}
}
}
catch
{ }
// se è multi CHIUDO ODL x altra tavola...
if (isMulti)
{
// se NON sono in attrezzaggio...
if (!inAttr)
{
int idxOdlAltra = 0;
try
{
var tabOdl = DataLayerObj.taODL.getByMacchina(idxMaccAltraTav);
if (tabOdl.Rows.Count > 0)
{
idxOdlAltra = DataLayerObj.taODL.getByMacchina(idxMaccAltraTav)[0].IdxODL;
}
}
catch (Exception exc)
{
logger.lg.scriviLog("Durante recupero idxOdlAltra " + exc.ToString(), tipoLog.EXCEPTION);
}
// procedo se ho ODL
if (idxOdlAltra > 0)
{
sb.AppendLine("---");
DataLayerObj.taODL.fineProd(idxOdlAltra, idxMaccAltraTav);
evText = "Registrato inizio attrezzaggio per ODL {0} (setup seconda tavola)";
sb.AppendLine(String.Format(evText, idxOdlAltra));
processaEvento(idxMaccAltraTav, idxEvento, String.Format(evText, idxOdlAltra), idxOdlAltra);
}
lblOut.Text = sb.ToString().Replace("---", "<br/>");
}
// update buttons...
checkAll();
}
// se è master --> chiamo update child!
if (isMaster)
{
DataLayerObj.taODL.fixMachineSlave(idxMacchina, 30, 1);
}
// resetto contapezzi redis...
DataLayerObj.saveCounter(idxMacchinaFix, "0");
// imposto ODL su redis...
DataLayerObj.saveCurrODL(idxMacchinaFix, idxODL_curr.ToString());
// salvo odl selezionato
idxOdl = idxODL_curr;
}
else
{
lblOut.Text = "Selezionare un ORDINE valido!";
}
// refresh finale
checkBtnStatus();
fixSplitBtn(false);
// sollevo evento!
if (eh_reqUpdate != null)
{
eh_reqUpdate(this, new EventArgs());
}
}
/// <summary>
/// inizio prod
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtStartProd_Click(object sender, EventArgs e)
{
confermaProdOdl(true);
// se vedesse TCRich a zero lo reimposta a quello assegnato...
if (TCRichAttr == 0)
{
TCRichAttr = TCAssegnato(idxODLSel);
}
// leggo idxOdl da ultimo odl attivo x macchina
int idxODLStart = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL;
int idxEvento = 1; // !!!HARD CODED
// se le note sono visibili
if (divNote.Visible)
{
// aggiorno (se necessario) note e tempo setup
DataLayerObj.taODL.updateSetup(idxODLStart, DataLayerObj.MatrOpr, TCRichAttr, PzPallet, txtNote.Text);
}
// controllo se TC Assegnato != TCRichiesto allora invio email x verifiche...
DS_ProdTempi.ODLRow rigaOdl = DataLayerObj.taODL.getByIdx(idxODLStart, false)[0];
if (rigaOdl.TCAssegnato != TCRichAttr)
{
// invio email!
DataLayerObj.sendWarnTcChangeReq(memLayer.ML.CRS("_adminEmail"));
}
// processo chiusura setup
string evText = "Registrata inizio produzione per ODL {0}";
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format(evText, idxODLStart));
processaEvento(idxMacchinaFix, idxEvento, sb.ToString(), idxODLStart);
// indico INIZIO SETUP su REDIS come EXE della macchina...
string ts = string.Format("{0:yyMMdd}T{0:HHmmss.fff}Z", DateTime.Now);
//DataLayerObj.addTask4Machine(idxMacchina, "stopSetup", $"TS:{ts}|MATR:{DataLayerObj.MatrOpr}|ODL:{idxODL}");
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.stopSetup, $"TS:{ts}|MATR:{DataLayerObj.MatrOpr}|ODL:{idxODLStart}");
// se è multi processo chiusura setup x altra tavola...
if (isMulti)
{
sb.AppendLine("---");
int idxOdlAltra = DataLayerObj.taODL.getByMacchina(idxMaccAltraTav)[0].IdxODL;
sb.AppendLine(String.Format(evText, idxOdlAltra));
processaEvento(idxMaccAltraTav, idxEvento, String.Format(evText, idxOdlAltra), idxOdlAltra);
// invio eventi ad IOB slave...
var slaveList = DataLayerObj.taM2S.getByMaster(idxMacchina);
foreach (var machine in slaveList)
{
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.stopSetup, $"TS:{ts}|MATR: {DataLayerObj.MatrOpr}| Master Machine: {idxMacchinaFix}");
}
}
// se è master --> chiamo update child!
if (isMaster)
{
// calcolo gli slave...
var slaveList = DataLayerObj.taM2S.getByMaster(idxMacchina);
foreach (var machine in slaveList)
{
// invio chiusura attrezzaggio
ts = string.Format("{0:yyMMdd}T{0:HHmmss.fff}Z", DateTime.Now);
string outData = $"TS:{ts}|MATR:{DataLayerObj.MatrOpr}|ODL:{idxODLStart}";
processaEvento(machine.IdxMacchinaSlave, idxEvento, sb.ToString(), idxODLStart);
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.fixStopSetup, outData);
}
// sistemo gli ODL
DataLayerObj.taODL.fixMachineSlave(idxMacchina, 30, 1);
}
// se c'è gestione SchedaTecnica --> chiamo procedura update x lotti
if (enableSchedaTecnica)
{
DataLayerObj.taMagELotti.UpsertByOdl(idxODLStart, true);
}
// riporto stringa
lblOut.Text = sb.ToString().Replace("---", "<br/>");
// nascondo note!
showNoteTC(false);
// update buttons...
checkAll();
// imposto odl...
idxOdl = idxODLStart;
// sollevo evento!
if (eh_reqUpdate != null)
{
eh_reqUpdate(this, new EventArgs());
}
}
/// <summary>
/// avvio pagina
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// fix modo tempo...
if (memLayer.ML.cdvb("TAB_TC_MinSec"))
{
mod_tempoMSMC.modoTempo = timeMode.MS;
}
else
{
mod_tempoMSMC.modoTempo = timeMode.MC;
}
// fix buttons
fixSplitBtn(false);
chkCloseOdl.Checked = chkCloseOdlVal;
checkTcNote();
}
cmp_newODL.eh_newVal += Cmp_newODL_eh_newVal;
cmp_selPODL.eh_doUpdate += Cmp_selPODL_eh_doUpdate;
cmp_selPODL.eh_selVal += Cmp_selPODL_eh_selVal;
}
/// <summary>
/// valore decimal del TC ASSEGNATO...
/// </summary>
protected decimal TCAssegnato(int idxODL)
{
decimal answ = 0;
try
{
if (enableRPO)
{
// leggo info da promessa...
var rigaProm = DataLayerObj.taPODL.getByKey(idxODL)[0];
answ = rigaProm.TCAssegnato;
}
else
{
// leggo idxOdl da ultimo odl attivo x macchina
DS_ProdTempi.ODLRow rigaOdl = DataLayerObj.taODL.getByIdx(idxODL, false)[0];
answ = rigaOdl.TCAssegnato;
}
}
catch
{ }
return answ;
}
#endregion Protected Methods
#region Private Methods
/// <summary>
/// controlla stato bottoni abilitato
/// </summary>
private void checkBtnStatus()
{
// di default rendo abilitato / disabilitato tutto in base al valore "isEnabled"
lbtShowSplitODL.Enabled = isEnabled && enableRiattrezzaggio;
lbtSplitODL.Enabled = isEnabled;
fixWCtrStatus(lbtShowSplitODL);
fixWCtrStatus(lbtSplitODL);
// condizioni booleane
bool inAttr = false;
bool currHasOdl = false;
// controllo se la macchina è in attrezzaggio...
DS_applicazione.StatoMacchineRow rigaStato = null;
try
{
// se è multi controllo parent...
if (isMulti)
{
rigaStato = selData.mng.rigaStato(idxMaccParent);
inAttr = (rigaStato.IdxStato == 2 && tavHasOdl);
}
else
{
rigaStato = selData.mng.rigaStato(idxMacchinaFix);
if (rigaStato != null)
{
inAttr = (rigaStato.IdxStato == 2);
}
}
}
catch (Exception exc)
{
logger.lg.scriviLog(string.Format("Eccezione in recupero dati rigaStato! {0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION);
}
try
{
currHasOdl = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL != 0;
}
catch (Exception exc)
{
logger.lg.scriviLog(string.Format("Eccezione in recupero dati currHasOdl! {0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION);
}
// deve controllare abbia ODL o PROMESSE odl...
bool hasNewOdl = DataLayerObj.taSelOdlFree.getUnused(idxMacchinaFix, cmp_selPODL.checkAll, numDaySelOdl).Rows.Count > 1;
// sistemo buttons!
lbtStartAttr.Enabled = (isEnabled && (!inAttr && hasNewOdl));
lbtEndProd.Enabled = (isEnabled && (!inAttr && currHasOdl));
// verifico condizioni annullamento setup
lbtAnnullaSetup.Visible = false;
if (isEnabled && enableAnnullaSetup && inAttr && enableSchedaTecnica)
{
// verifico condizione pz da confermare
var tabProd = DataLayerObj.taStatoProd.GetData(idxMacchinaSel, DateTime.Now);
if (tabProd != null && tabProd.Rows.Count > 0)
{
var rigaProd = tabProd[0];
lbtAnnullaSetup.Visible = rigaProd.PzTotODL == 0;
}
}
// controllo se ci sia da verificare scheda tecnica
if (enableSchedaTecnica)
{
var tabRichieste = DataLayerObj.taSTAR.getPendingByOdl(idxOdl);
bool okCheckST = tabRichieste.Count == 0;
if (okCheckST)
{
hlNeedStar.Visible = false;
lbtStartProd.Enabled = (isEnabled && inAttr);
}
else
{
hlNeedStar.Visible = (isEnabled && inAttr);
lbtStartProd.Enabled = false;
}
}
else
{
lbtStartProd.Enabled = (isEnabled && inAttr);
}
cmp_selPODL.Enabled = (isEnabled && (!inAttr && hasNewOdl));
// sistemo anche come css..
fixWCtrStatus(lbtStartAttr);
fixWCtrStatus(lbtStartProd);
fixWCtrStatus(lbtEndProd);
// sistemo show tempo/note attrezzaggio..
if (inAttr)
{
showNoteTC(true);
int idxOdl = 0;
try
{
idxOdl = DataLayerObj.taODL.getByMacchina(idxMacchinaFix)[0].IdxODL;
updateTempoTc(idxOdl, inAttr);
updateNoteTC(idxOdl);
}
catch (Exception exc)
{
logger.lg.scriviLog(string.Format("Eccezione in recupero dati ODL! {0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION);
}
}
// verifico se l'articolo corrente sia in revisione x mostrare conferma modifica revisione...
if (CodArtSel != "")
{
bool showWarn = false;
try
{
showWarn = DataLayerObj.taAnagArt.getByCod(CodArtSel)[0].FlagIsNew;
}
catch (Exception exc)
{
logger.lg.scriviLog(string.Format("Eccezione in recupero dati showWarn! {0}{1}", Environment.NewLine, exc), tipoLog.EXCEPTION);
}
divWarningArt.Visible = showWarn;
}
}
/// <summary>
/// Verifica se mostrare note
/// </summary>
private void checkTcNote()
{
if (cmp_selPODL.SelectedIndex > 0)
{
showNoteTC(true);
updateTempoTc(idxODLSel, false);
updateNoteTC(idxODLSel);
}
else
{
showNoteTC(false);
}
}
private void Cmp_newODL_eh_newVal(object sender, EventArgs e)
{
// creato nuovo ODL, faccio refresh ricaricando pagina!
Response.Redirect("~/ODL");
}
private void Cmp_selPODL_eh_doUpdate(object sender, EventArgs e)
{
checkBtnStatus();
}
private void Cmp_selPODL_eh_selVal(object sender, EventArgs e)
{
checkTcNote();
}
/// <summary>
/// verifica se sia necessario confermare la prod dell'ODL precedente prima di chiudere e lo fa in automatico...
/// </summary>
/// <param name="confZero">boolean, true = deve confermare 0 pezzi (es. in setup)</param>
private void confermaProdOdl(bool confZero)
{
// 2016.11.17 NOTA: introdotti scarti, li confermiamo SEMPRE a zero se in setup, però da valutare SE a FINE ATTREZZAGGIO chiedere num pezzi e num scarti (saldo zero buoni) da inserire...
bool fatto = false;
DateTime adesso = DateTime.Now;
if (confZero)
{
// confermo produzione ZERO pezzi (in setup)
if (confRett)
{
// confermo al netto dei pezzi lasciati...
fatto = DataLayerObj.confermaProdMacchinaFull(idxMacchinaFix, memLayer.ML.CRI("modoConfProd"), 0, 0, 0, adesso, DataLayerObj.MatrOpr);
}
else
{
fatto = DataLayerObj.confermaProdMacchina(idxMacchinaFix, memLayer.ML.CRI("modoConfProd"), 0, 0, adesso, DataLayerObj.MatrOpr);
}
}
else // se NON sono in setup verifico se ho pz da confermare
{
// recupero pz da confermare
DS_ProdTempi.stp_PzProd_getByMacchinaRow rigaProd = DataLayerObj.taPzProd2conf.GetData(idxMacchinaFix)[0];
if (rigaProd.pezziNonConfermati > 0)
{
// confermo produzione ZERO pezzi (in setup)
if (confRett)
{
// confermo al netto dei pezzi lasciati...
fatto = DataLayerObj.confermaProdMacchinaFull(idxMacchinaFix, memLayer.ML.CRI("modoConfProd"), rigaProd.pezziNonConfermati, 0, 0, adesso, DataLayerObj.MatrOpr);
}
else
{
fatto = DataLayerObj.confermaProdMacchina(idxMacchinaFix, memLayer.ML.CRI("modoConfProd"), rigaProd.pezziNonConfermati, 0, adesso, DataLayerObj.MatrOpr);
}
}
}
}
/// <summary>
/// Rimozione dati e parametri (TAB e su PLC) x ODL corrente
/// </summary>
private void doRemoveCurrOdlData()
{
// invio task x end produzione...
string setArtVal = "NO ART";
string setPzCommVal = "0";
string setCommVal = $"NO ODL";
// FIXME TODO: scrivere come sotto? testare valvital x linea LASCO
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.endProd, "");
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.setArt, setArtVal);
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.setPzComm, setPzCommVal);
DataLayerObj.addTask4Machine(idxMacchinaFix, taskType.setComm, setCommVal);
// se è master --> chiamo update child!
if (isMaster)
{
// calcolo gli slave...
var slaveList = DataLayerObj.taM2S.getByMaster(idxMacchina);
foreach (var machine in slaveList)
{
// invio task x end produzione...
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.endProd, "");
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.setArt, setArtVal);
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.setPzComm, setPzCommVal);
DataLayerObj.addTask4Machine(machine.IdxMacchinaSlave, taskType.setComm, setCommVal);
}
}
// resetto contapezzi redis...
DataLayerObj.saveCounter(idxMacchinaFix, "0");
// resetto ODL su redis...
DataLayerObj.emptyCurrODL(idxMacchinaFix);
// reset ODL!...
idxOdl = -1;
}
/// <summary>
/// sistema buttons split
/// </summary>
/// <param name="splitOdl"></param>
private void fixSplitBtn(bool splitOdl)
{
lbtShowSplitODL.Visible = !splitOdl && enableRiattrezzaggio;
lbtSplitODL.Visible = splitOdl;
chkCloseOdl.Visible = showChkCloseOdlVal && !splitOdl;
chkCloseOdl.Enabled = isEnabled;
fixWCtrStatus(chkCloseOdl);
showNoteTC(splitOdl);
cmp_selPODL.CtrlVisible = !splitOdl;
lbtStartAttr.Visible = !splitOdl;
lbtShowOdlDet.Visible = !lbtStartAttr.Visible;
lbtStartProd.Visible = !splitOdl;
lbtEndProd.Visible = !splitOdl;
}
/// <summary>
/// processa evento richiesto
/// </summary>
/// <param name="idxMaccCurr"></param>
/// <param name="idxEvento"></param>
/// <param name="userMsg"></param>
/// <param name="idxODL"></param>
private void processaEvento(string idxMaccCurr, int idxEvento, string userMsg, int idxODL)
{
inputComandoMapo inCmd;
inputComandoMapo inCmd2;
DS_applicazione.StatoMacchineRow rigaStato = selData.mng.rigaStato(idxMaccCurr);
// ricavo codice articolo...
string CodArticolo = DataLayerObj.taODL.getByIdx(idxODL, false)[0].CodArticolo;
// processo evento...
inCmd = DataLayerObj.scriviRigaEventoBarcode(idxMaccCurr, idxEvento, CodArticolo, "", DataLayerObj.MatrOpr, rigaStato.pallet);
// se la macchina è MULTI (cod#tavola) e sonoa INIZIO/FINE attrezzaggio (idxEv <=2) oppure FINE PROD processo ANCHE per la macchina madre...
if (idxMaccCurr.IndexOf('#') > 0 && (idxEvento <= 2 || idxEvento == 7))
{
inCmd2 = DataLayerObj.scriviRigaEventoBarcode(idxMaccParent, idxEvento, CodArticolo, "", DataLayerObj.MatrOpr, rigaStato.pallet);
}
// chiamo refresh MSE
DataLayerObj.taMSE.forceRecalc(0, idxMaccCurr);
// invalido la cache di selData
selData.mng.invalidateCache();
lblOut.Text = userMsg;
// loggo USR MSG
logger.lg.scriviLog(userMsg, tipoLog.INFO);
checkBtnStatus();
}
/// <summary>
/// mostra/nasconde note
/// </summary>
private void showNoteTC(bool show)
{
// mostra/nasconde note da compilare
divTempo.Visible = show;
divNote.Visible = show;
divPzPallet.Visible = show;
lbtStartAttr.Visible = show;
lbtShowOdlDet.Visible = !show;
cmp_dettPODL.idxODLSel = idxODLSel;
divDettPOdl.Visible = show && idxODLSel > 0;
// se abilitato da config su DB mostro selezione del numPzPallet...
cmp_selPzPallet.enableSet = enableTabSetPzPallet;
}
/// <summary>
/// aggiorna note ODL
/// </summary>
/// <param name="idxOdl"></param>
private void updateNoteTC(int idxOdl)
{
string testo = "";
if (idxOdl > 0)
{
try
{
testo = DataLayerObj.taODL.getByIdx(idxOdl, false)[0].Note;
}
catch
{ }
}
txtNote.Text = testo;
}
/// <summary>
/// update TC mostrato
/// </summary>
/// <param name="idxOdlPodl">idx dell'ODL / PODL</param>
/// <param name="inAttr"></param>
private void updateTempoTc(int idxOdlPodl, bool inAttr)
{
// riporta TC
decimal _TCRichAttr = 0;
int pzPallet = 1;
if (enableRPO && !inAttr)
{
var rigaProm = DataLayerObj.taPODL.getByKey(idxOdlPodl)[0];
_TCRichAttr = rigaProm.TCAssegnato;
pzPallet = rigaProm.PzPallet;
}
else
{
DS_ProdTempi.ODLRow rigaOdl = DataLayerObj.taODL.getByIdx(idxOdlPodl, false)[0];
if (rigaOdl.TCRichAttr > 0)
{
_TCRichAttr = rigaOdl.TCRichAttr;
}
else
{
_TCRichAttr = rigaOdl.TCAssegnato;
}
pzPallet = rigaOdl.PzPallet;
}
// aggiorno dati!
TCRichAttr = _TCRichAttr;
PzPallet = pzPallet;
}
#endregion Private Methods
}
}