using GMW_data;
using SteamWare;
using System;
using System.Globalization;
using System.Web.UI;
using System.Web.UI.WebControls;


namespace GMW.WebUserControls
{
  public partial class mod_postRX_DT_LIST : System.Web.UI.UserControl
  {
    /// <summary>
    /// Oggetto locale gestione classe datamatrix...
    /// </summary>
    protected DataMatrix DataMatrix_mgr = new DataMatrix();
    /// <summary>
    /// flusso associato (hard coded) a RX
    /// </summary>
    protected string flusso = "RX";
    /// <summary>
    /// stato associato (hard coded) a Controllato RX
    /// </summary>
    protected string statoUDC = "ContrRx";
    /// <summary>
    /// codice evento dell'UDC che si crea
    /// </summary>
    protected string codEventoUdc = "UDC_RX_DTE";
    public event EventHandler eh_reqUpdate;
    /// <summary>
    /// stringa UID univoca
    /// </summary>
    public string uid
    {
      get
      {
        return this.UniqueID.Replace("$", "_").Replace("-", "_");
      }
    }
    /// <summary>
    /// caricamento pagina
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
      if (!Page.IsPostBack)
      {
        currParticolare = "";
        lblDTFus.Text = string.Format("{0:ddd dd/MM/yyyy, HH:mm}", dataFus);
        lblLinFus.Text = lineaFus;
        Postazione.messaggiText = "";
        Postazione.warningText = "";
        fixTipoInput();
        fixCella();
        traduciObj();
        divDetDtx.Visible = false;
        showAL(false, false);
      }
      doChecks();
    }
    /// <summary>
    /// qta pezzi x UDC
    /// </summary>
    public int qta
    {
      get
      {
        int qta = 0;
        try
        {
          qta = Convert.ToInt32(txtQta.Text.Trim());
        }
        catch
        { }
        return qta;
      }
      set
      {
        txtQta.Text = value.ToString();
      }
    }
    /// <summary>
    /// data fusione impostata SALVATA SU DB...
    /// </summary>
    public DateTime dataFus
    {
      get
      {
        DateTime answ = Convert.ToDateTime("1900-01-01");
        try
        {

          answ = Convert.ToDateTime(utils.obj.RTVal(user_std.pagCorrente, "dataFus" + Postazione.currCodLinea));
        }
        catch
        { }
        return answ;
      }
      set
      {
        utils.obj.taRTPV.upsert(user_std.pagCorrente, "dataFus" + Postazione.currCodLinea, string.Format("{0:yyyy/MM/dd HH:mm}", value));
        lblDTFus.Text = string.Format("{0:ddd dd/MM/yyyy, HH:mm}", value);
      }
    }
    /// <summary>
    /// LINEA fusione impostata SALVATA SU DB...
    /// </summary>
    public string lineaFus
    {
      get
      {
        string answ = "";
        try
        {

          answ = utils.obj.RTVal(user_std.pagCorrente, "lineaFus" + Postazione.currCodLinea);
        }
        catch
        { }
        //2016.01.25 se vuoto metto ND!!!
        if (string.IsNullOrEmpty(answ))
        {
          answ = "ND";
        }
        return answ;
      }
      set
      {
        utils.obj.taRTPV.upsert(user_std.pagCorrente, "lineaFus" + Postazione.currCodLinea, value);
        lblLinFus.Text = value;
      }
    }
    /// <summary>
    /// aggiorna visualizzazioen dati particolare
    /// </summary>
    private void updatePart()
    {
      if (currParticolare != "")
      {
        lblParticolareAttivo.Text = string.Format("{0} <b>{1}</b>", traduci("particSel"), currParticolare);
        // aggiungo descrizione del particolare
        string descr = "";
        string disegno = "";
        try
        {
          DS_magazzino.AnagParticolariRow riga = MagClass.magazzino.taAnagPart.likeSearch(currParticolare, memLayer.ML.StringSessionObj("CodCS"))[0];
          descr = riga.DescParticolare;
          disegno = string.Format("( {0} )", riga.DisegnoGrezzo);
        }
        catch
        { }
        lblDescrAttivo.Text = descr;
        lblDisegno.Text = disegno;
      }
      else
      {
        lblParticolareAttivo.Text = "...";
        lblDescrAttivo.Text = "";
        lblDisegno.Text = "";
      }
    }
    /// <summary>
    /// sistema modalità input
    /// </summary>
    private void fixTipoInput()
    {
      bool barcodeEnabled = false;
      if (rblInputMode.SelectedValue.ToUpper() == "BARCODE")
      {
        barcodeEnabled = true;
      }
      Postazione.messaggiText = traduci("attesaInput");
      Postazione.warningText = "";
      divElenco.Visible = !barcodeEnabled;
      divBarcode.Visible = barcodeEnabled;
      doUpdate();
    }
    /// <summary>
    /// verifica se si debab mostrare un campo ricerca UDC attivo...
    /// </summary>
    private void fixCella()
    {
      hfCodLinea.Value = Postazione.currCodLinea;
    }
    /// <summary>
    /// richiesta (ri)stampa UDC
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public void ristampa()
    {
      MagClass.magazzino.stampaAL(udcReq, Postazione.printer, Request.UserHostName);
      // registro ri-stampa UDC
      MagClass.magazzino.taSAO.insertQuery(DateTime.Now, MagClass.magazzino.CodSoggCurrUser, Postazione.name, Postazione.IP, udcReq, "", "creaAL", "Ri-Stampato AL Rx NT");
    }
    /// <summary>
    /// udc da stampare
    /// </summary>
    protected string udcReq
    {
      get
      {
        return memLayer.ML.StringSessionObj("udcSelSAO");
      }
    }
    /// <summary>
    /// effettua controlli visibilità
    /// </summary>
    private void doChecks()
    {
      checkBarcode();
    }
    /// <summary>
    /// sistemo labels oggetti
    /// </summary>
    private void traduciObj()
    {

    }
    /// <summary>
    /// wrapper traduzione
    /// </summary>
    /// <param name="lemma"></param>
    /// <returns></returns>
    public string traduci(object lemma)
    {
      return user_std.UtSn.Traduci(lemma.ToString());
    }
    /// <summary>
    /// indica se i caratteri vadano forzati a maiuscoli
    /// </summary>
    public bool forceUppercase
    {
      get
      {
        return memLayer.ML.confReadBool("forceUppercase");
      }
    }
    /// <summary>
    /// Formato Datamatrix della linea selezionata
    /// </summary>
    protected string FormatoDtmxLinea
    {
      get
      {
        string answ = "";
        try
        {
          answ = MagClass.magazzino.taAL.getByKey(Postazione.currCodLinea)[0].FormatoDtmx;
        }
        catch
        { }
        return answ;
      }
    }
    /// <summary>
    /// Formato Datamatrix dell'ultimo barcode letto
    /// </summary>
    protected string FormatoDtmxBarcode
    {
      get
      {
        string answ = "";
        try
        {
          answ = DataMatrix_mgr.taVerifica.GetData(barcodeIn)[0].FormatoDtmx;
        }
        catch
        { }
        return answ;
      }
    }
    /// <summary>
    /// codice particolare da datamatrix
    /// </summary>
    /// <param name="byTable">bollean:
    /// true = utilizza lookUp su tabella dati acquisiti
    /// false = prova a decodificare (da formato Dtmx linea)</param>
    /// <returns></returns>
    protected string partByDtmx(bool byTable)
    {
      string answ = "";
      if (byTable)
      {
        try
        {
          answ = DataMatrix_mgr.taDtxAcquisiti.getByKey(barcodeIn)[0].Particolare; // Decode.GetData(barcodeIn, FormatoDtmxLinea)[0].Particolare;
        }
        catch
        {
          answ = DataMatrix_mgr.taDecode.GetData(barcodeIn, FormatoDtmxLinea)[0].Particolare;
        }
      }
      else
      {
        answ = DataMatrix_mgr.taDecode.GetData(barcodeIn, FormatoDtmxLinea)[0].Particolare;
      }
      return answ;
    }
    /// <summary>
    /// valore barcode
    /// </summary>
    public string barcodeIn
    {
      get
      {
        return txtBarcode.Text.Trim();
      }
      set
      {
        txtBarcode.Text = value;
      }
    }
    /// <summary>
    /// controlla se ci sia un barcode
    /// </summary>
    private void checkBarcode()
    {
      bool okDTL = false;
      if (barcodeIn != "")
      {
        Postazione.messaggiText = string.Format("{0}: {1}", traduci("BCodeIns"), barcodeIn);
        switch (MagClass.tipoBCode_L5(barcodeIn))
        {
          case tipoCodiceBarcode.DateTime:
            // permetto SOLO SE ho già AL --> lo associo
            if (rigaCurr != null && rigaCurr.AL != "")
            {
              string AlOk = rigaCurr.AL;
              okDTL = getDateTimeLine(barcodeIn, false);
              if (okDTL)
              {
                Postazione.messaggiText = traduci("SetDataFus");
                Postazione.warningText = "";
                Postazione.CssClass = "stileComandoOk";
                // aggiunta fusione x tutti UDC dell'AL...
                string AlOut = "";
                DataMatrix_mgr.taL2D.addFusione(Postazione.currCodLinea, FormatoDtmxLinea, DateTime.Now, MagClass.magazzino.CodSoggCurrUser, barcodeIn, ref AlOut);
                if (AlOk != AlOut)
                {
                  Postazione.messaggiText = traduci("ERR-BCD-006");
                  Postazione.warningText = "";
                  Postazione.CssClass = "stileComandoKo";
                }
                barcodeIn = "";
              }
              else
              {
                Postazione.messaggiText = traduci("ERR-BCD-004");
                Postazione.warningText = "";
                Postazione.CssClass = "stileComandoKo";
              }
            }
            else
            {
              Postazione.messaggiText = traduci("ERR-BCD-005");
              Postazione.warningText = "";
              Postazione.CssClass = "stileComandoKo";
            }
            break;
          case tipoCodiceBarcode.DateTimeLine:
            // permetto SOLO SE ho già AL --> lo associo
            if (rigaCurr != null && rigaCurr.AL != "")
            {
              string AlOk = rigaCurr.AL;
              okDTL = getDateTimeLine(barcodeIn, true);
              if (okDTL)
              {
                Postazione.messaggiText = traduci("SetDataFus");
                Postazione.warningText = "";
                Postazione.CssClass = "stileComandoOk";
                // aggiunta fusione x tutti UDC dell'AL...
                string AlOut = "";
                DataMatrix_mgr.taL2D.addFusione(Postazione.currCodLinea, FormatoDtmxLinea, DateTime.Now, MagClass.magazzino.CodSoggCurrUser, barcodeIn, ref AlOut);
                if (AlOk != AlOut)
                {
                  Postazione.messaggiText = traduci("ERR-BCD-006");
                  Postazione.warningText = "";
                  Postazione.CssClass = "stileComandoKo";
                }
                barcodeIn = "";
              }
              else
              {
                Postazione.messaggiText = traduci("ERR-BCD-004");
                Postazione.warningText = "";
                Postazione.CssClass = "stileComandoKo";
              }
            }
            else
            {
              Postazione.messaggiText = traduci("ERR-BCD-005");
              Postazione.warningText = "";
              Postazione.CssClass = "stileComandoKo";
            }
            break;
          case tipoCodiceBarcode.DataMatrixTrovato:
            // controllo che il DTX non sia già assegnato...
            if (DataMatrix_mgr.taDtx2UDC.getByDtx(barcodeIn).Rows.Count == 0)
            {
              // vers 2.9
              // controllo formato datamatrix sia impostato sulla linea (altrimenti errore linea "non battezzata")
              if (string.IsNullOrEmpty(FormatoDtmxLinea))
              {
                // errore poiché non è stato non specificato tipo Dtmx assegnato alla linea!
                Postazione.messaggiText = barcodeIn;
                Postazione.warningText = traduci("ERR-DTX-013");
                Postazione.CssClass = "stileComandoKo";
              }
              else
              {
                // verifico formato datamatrix letto sia quello della linea...
                if (FormatoDtmxBarcode != FormatoDtmxLinea)
                {
                  // errore corrispondenza formato Dtmx
                  Postazione.messaggiText = barcodeIn;
                  Postazione.warningText = traduci("ERR-DTX-014");
                  Postazione.CssClass = "stileComandoKo";
                }
                else
                {
                  // datamatrix ok: setto css e labels
                  Postazione.messaggiText = traduci("partSelected");
                  Postazione.warningText = "";
                  Postazione.CssClass = "stileComandoOk";
                  // controllo il particolare da Dtx + check capienza celle
                  if (Postazione.currCodCella != "")
                  {
                    // calcolo particolare!
                    try
                    {
                      // vers 2.9 modifica per multi-datamatrix
                      currParticolare = partByDtmx(true);
                    }
                    catch (Exception exc)
                    {
                      logger.lg.scriviLog(string.Format("Errore in decodifica particolare da DataMatrix:{0}dtx:{1}{0}Formato Linea:{2}{0}Eccezione:{0}{2}", Environment.NewLine, barcodeIn, exc), tipoLog.EXCEPTION);
                      currParticolare = "";
                    }
                    if (currParticolare != "")
                    {
                      // dataOra timbratura dtx...
                      DateTime dataLett = DateTime.Now;
                      // ricavo dati particolare
                      string descrPart = "";
                      //string disegnoPart = "";
                      try
                      {
                        DS_magazzino.AnagParticolariRow riga = MagClass.magazzino.taAnagPart.likeSearch(currParticolare, memLayer.ML.StringSessionObj("CodCS"))[0];
                        descrPart = riga.DescParticolare;
                      }
                      catch
                      { }

                      // 2016.01.25 aggiunta lettura codice x data-ora + linea fusione
                      // controllo per recuperare da datamatrix i dati di codice linea e data fusione
                      DS_DataMatrix.v_ElencoDmtxDataTable tabDmtx = DataMatrix_mgr.taVED.getByKey(barcodeIn);
                      bool marcaturaOk = false;
                      if (tabDmtx.Rows.Count > 0)
                      {
                        // verifica esitoMarcatura
                        marcaturaOk = (tabDmtx[0].EsitoMarcatura == "OK");
                      }

                      qta = 1; // tanto poi si ricalcola...
                               // 2017.02.21 verifico DTX sia OK
                      if (marcaturaOk)
                      {
                        // verifico SE NON HO ancora un record...
                        bool nuovaLettura = true;
                        try
                        {
                          //nuovaLettura = DataMatrix_mgr.taL2D.getByLineaPart(Postazione.currCodLinea, currParticolare).Rows.Count == 0;
                          nuovaLettura = rigaCurr == null;
                        }
                        catch
                        { }
                        // non ho il record --> creo con NUOVO DTX letto (inizio)
                        if (nuovaLettura)
                        {
                          DataMatrix_mgr.taL2D.insertIni(Postazione.currCodLinea, FormatoDtmxLinea, barcodeIn, MagClass.magazzino.CodSoggCurrUser, dataLett);
                        }
                        // c'è già un record --> chiudo impostando/aggiornando il record di ULTIMO DMTX
                        else
                        {
                          DataMatrix_mgr.taL2D.updateEnd(Postazione.currCodLinea, FormatoDtmxLinea, barcodeIn, MagClass.magazzino.CodSoggCurrUser, dataLett);
                        }

                      }
                      else
                      {
                        Postazione.messaggiText = barcodeIn;
                        Postazione.warningText = traduci("ERR-DTX-012");
                        Postazione.CssClass = "stileComandoKo";
                      }

                      // 2017.07.22 svuoto barcodeIn..
                      barcodeIn = "";
                    }
                  }
                }
              }
            }
            else
            {
              Postazione.messaggiText = barcodeIn;
              Postazione.warningText = traduci("DtxGiaAssegnato");
              Postazione.CssClass = "stileComandoKo";
            }
            break;

          default:
            Postazione.warningText = traduci("ERR-UNK-001");
            Postazione.CssClass = "stileComandoND";
            break;
        }
        barcodeIn = "";
      }
      else
      {
        Postazione.messaggiText = traduci("AttesaBCode");
        Postazione.CssClass = "stileAttesa";
      }
      doUpdate();
    }
    /// <summary>
    /// recupera da barcode dataOra e linea fusione (SE presenti)
    /// </summary>
    /// <param name="val2decode">valore x decodificare dataora - linea</param>
    /// <param name="readline">SE si debba cercare ANCHE linea...</param>
    /// <returns></returns>
    private bool getDateTimeLine(string val2decode, bool readline)
    {
      bool okData = false;
      bool okLinea = false;
      DateTime oldDataFus = new DateTime(1900, 1, 1);
      // imposto NUOVA dataora fusione...
      string newData = "";
      string newLinea = "";
      // tento di recuperare e verifico validità dei 2 valori separatamente...
      try
      {
        newData = val2decode.Replace(memLayer.ML.AppConf["prefDateTime"], "").Substring(0, 10);
        if (newData != "")
        {
          dataFus = DateTime.ParseExact(newData, "yyMMddHHmm", CultureInfo.InvariantCulture);
          okData = true;
        }
      }
      catch
      {
        dataFus = oldDataFus;
      }
      if (readline)
      {
        if (okData)
        {
          try
          {
            newLinea = val2decode.Replace(memLayer.ML.AppConf["prefDateTime"], "").Substring(10, val2decode.Length - 10 - memLayer.ML.AppConf["prefDateTime"].Length);
            if ((newLinea != "") && (DataProxy.obj.taElPost.getByCod(newLinea).Rows.Count > 0))
            {
              lineaFus = newLinea;
              okLinea = true;
            }
            else
            {
              lineaFus = "";
              dataFus = oldDataFus;
            }
          }
          catch
          {
            lineaFus = "";
            dataFus = oldDataFus;
          }
        }
        else
        {
          lineaFus = "";
        }
      }
      else
      {
        okLinea = true;
      }
      return okData && okLinea;
    }
    /// <summary>
    /// aggiorna tabella + focus a barcode
    /// </summary>
    public void doUpdate()
    {
      fixCella();
      grView.DataBind();
      // se selezionato qualcosa mostro dettaglio
      divDetDtx.Visible = (grView.SelectedIndex >= 0);
      grViewDet.DataBind();
      // fix dataFus
      lblDTFus.Text = string.Format("{0:ddd dd/MM/yyyy, HH:mm}", dataFus);
      lblLinFus.Text = lineaFus;
      // aggiorno le qta!
      qta = pezziUdc;
      // update particolare
      updatePart();
      verificaBtnStampa();
      txtBarcode.Focus();
    }
    /// <summary>
    /// reset della selezione
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnReset_Click(object sender, EventArgs e)
    {
      resetSelezione();
    }
    /// <summary>
    /// resetta la selezione dei valori in caso di modifiche su altri controlli
    /// </summary>
    public void resetSelezione()
    {
      grView.SelectedIndex = -1;
      doUpdate();
    }
    /// <summary>
    /// effettua reset dati
    /// </summary>
    private void doResetData()
    {
      // resetto i dati QtaTot e particolare...
      doChecks();
    }
    /// <summary>
    /// indica il codice articolo correntemente selezionato
    /// </summary>
    protected string currParticolare
    {
      get
      {
        return memLayer.ML.StringSessionObj(string.Format("currParticolare_{0}", uid));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("currParticolare_{0}", uid), value, memLayer.ML.confReadBool("keepParticolareSel"));
      }
    }
    /// <summary>
    ///  num pezzi dell'intero AL (temporaneo)
    /// </summary>
    public int pezziUdc
    {
      get
      {
        int answ = 0;
        // calcolo qta a partire da particolare selezionato...
        try
        {
          //DS_DataMatrix.Linea2Dtx_IEDataTable tabL2D = DataMatrix_mgr.taL2D.getByLineaPart(Postazione.currCodLinea, currParticolare);
          //if (tabL2D.Rows.Count > 0)
          //{
          //    answ = tabL2D[0].Qta;
          //}
          DS_DataMatrix.Linea2Dtx_IERow riga = rigaCurr;
          if (riga != null)
          {
            answ = riga.Qta;
          }
        }
        catch (Exception exc)
        {
          if (memLayer.ML.confReadInt("_logLevel") > 5) logger.lg.scriviLog(exc.ToString(), tipoLog.EXCEPTION);
          answ = 0;
        }
        return answ;
      }
    }
    /// <summary>
    /// traduce gli header delle colonne
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void grView_DataBound(object sender, EventArgs e)
    {
      if (grView.Rows.Count > 0)
      {
        LinkButton lb;
        // aggiorno gli headers        
        foreach (TableCell cella in grView.HeaderRow.Cells)
        {
          try
          {
            lb = (LinkButton)cella.Controls[0];
            lb.Text = traduci(lb.Text);
          }
          catch
          { }
        }
        int totRecord = grView.Rows.Count + grView.PageSize * (grView.PageCount - 1);
      }
    }
    /// <summary>
    /// cambiato tipo di richiesta di input
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void rblInputMode_SelectedIndexChanged(object sender, EventArgs e)
    {
      fixTipoInput();
    }
    /// <summary>
    /// salvo il particolare selezionato...
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void lbtAddPart_Click(object sender, EventArgs e)
    {
      // imposto il particolare corrente
      currParticolare = ddlPart.SelectedValue;
      Postazione.messaggiText = traduci("partSelected");
      Postazione.warningText = "";
      Postazione.CssClass = "stileComandoOk";
      // leggo la qta dell'ultimo UDC del particolare, SE C'E', e la imposto...
      if (pezziUdc > 0)
      {
        qta = pezziUdc;
      }
      else // rimette default
      {
        qta = memLayer.ML.cdvi("QtaImballoRX");
      }
      doUpdate();
    }

    /// <summary>
    /// evento selezione: ricarico dati!
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void grView_SelectedIndexChanged(object sender, EventArgs e)
    {
      doUpdate();
    }
    /// <summary>
    /// Numero cesta inserito
    /// </summary>
    public string numCesta
    {
      get
      {
        return txtCesta.Text.Trim();
      }
      set
      {
        txtCesta.Text = value;
      }
    }
    /// <summary>
    /// evento cambio num cesta/grappolo
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void txtCesta_TextChanged(object sender, EventArgs e)
    {
      txtCesta.Text = txtCesta.Text.ToUpper().Trim().PadLeft(4, '0').Substring(0, 4);
      doUpdate();
    }
    /// <summary>
    /// Restituisce record riga corrente
    /// </summary>
    protected DS_DataMatrix.Linea2Dtx_IERow rigaCurr
    {
      get
      {
        DS_DataMatrix.Linea2Dtx_IERow answ = null;
        DS_DataMatrix.Linea2Dtx_IEDataTable tab = null;
        try
        {

          tab = DataMatrix_mgr.taL2D.getByLineFormato(Postazione.currCodLinea, FormatoDtmxLinea);
          if (tab.Rows.Count > 0)
          {
            answ = tab[0];
          }
        }
        catch
        { }
        return answ;
      }
    }
    /// <summary>
    /// verifica visibilità btn stampa UDC
    /// </summary>
    private void verificaBtnStampa()
    {
      // SOLO SE ho la riga..
      if (rigaCurr != null)
      {
        DS_DataMatrix.Linea2Dtx_IERow riga = rigaCurr;
        // controllo cosa posso visualizzare tra CREA UDC e STAMPA AL
        bool hasAL = false;
        bool hasQta = false;
        bool hasPmUm = false;
        try
        {
          if (riga.AL != "") hasAL = true;
          if (riga.Qta > 0) hasQta = true;
          if (riga.DTX_INI != "" && riga.DTX_END != "") hasPmUm = true;
        }
        catch
        { }
        // se ho AL mostro stampa!
        showAL(hasQta && hasPmUm && numCesta != "", hasAL);
      }
    }
    /// <summary>
    /// Determina se mostrare creazione/stampa AL
    /// </summary>
    /// <param name="showCreate"></param>
    /// <param name="showPrint"></param>
    private void showAL(bool showCreate, bool showPrint)
    {
      divNote.Visible = showCreate || showPrint;
      lbtGeneraAl.Visible = showCreate && !showPrint;
      lbtStampaAL.Visible = showPrint;
      txtCesta.Enabled = !showPrint;
    }

    /// <summary>
    /// genera e stampa AL
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void lbtGeneraAl_Click(object sender, EventArgs e)
    {
      // verifico postazione sia valida...
      if (Postazione.name != "" && Postazione.IP != "" && Postazione.currCodCella != "")
      {
        /* generazione AL DA RIVEDERE */
        string AL = "";
        string noteTrim = txtNote.Text.Trim();
        // creazione AL ed associazione UDC / spostamento...
        try
        {
          // creo UDC ed AL
          AL = MagClass.magazzino.creaAssociaAlUdcRxDt(Postazione.currCodLinea, FormatoDtmxLinea, codEventoUdc, statoUDC, tipoAL.AL_RxDt, Postazione.currCodCella, MagClass.magazzino.CodSoggCurrUser, DateTime.Now.Year, numCesta, noteTrim);
        }
        catch
        { }
        if (AL != "")
        {
          Postazione.CssClass = "stileComandoOk";
          Postazione.warningText = "";
          Postazione.messaggiText = traduci("GEN-AL-UDC-OK");
          Response.Redirect(user_std.pagCorrente);
        }
      }
      else
      {
        // ricarico che mi manca postazione!
        Postazione.CssClass = "stileAttesa";
        Postazione.warningText = traduci("ERR-POS-001");
        Postazione.messaggiText = "";
        Response.Redirect(user_std.pagCorrente);
      }
    }

    protected void ods_Deleted(object sender, ObjectDataSourceStatusEventArgs e)
    {
      Postazione.CssClass = "stileAttesa";
      Postazione.warningText = "";
      Postazione.messaggiText = "";
      currParticolare = "";
      qta = 0;
      doUpdate();
      eh_reqUpdate?.Invoke(this, new EventArgs());
    }

    protected void lbtStampaAL_Click(object sender, EventArgs e)
    {
      // verifico postazione sia valida...
      if (Postazione.name != "" && Postazione.IP != "" && Postazione.currCodCella != "")
      {
        string noteTrim = txtNote.Text.Trim();
        /* stampa AL */
        string AlOut = "";
        string AL = rigaCurr.AL;
        // sistemo pre-stampa
        try
        {
          // update pre-stampa...
          DataMatrix_mgr.taL2D.sistemaPreStampa(Postazione.currCodLinea, FormatoDtmxLinea, DateTime.Now, MagClass.magazzino.CodSoggCurrUser, codEventoUdc, noteTrim, ref AlOut);
        }
        catch
        { }
        // se gli AL corrispondono...
        if (AL != AlOut)
        {
          Postazione.messaggiText = traduci("ERR-BCD-006");
          Postazione.warningText = "";
          Postazione.CssClass = "stileComandoKo";
        }
        else
        {
          // lancio stampa
          MagClass.magazzino.stampaAL(AL, Postazione.printer, Request.UserHostName);
          // registro creazione AL
          MagClass.magazzino.taSAO.insertQuery(DateTime.Now, MagClass.magazzino.CodSoggCurrUser, Postazione.name, Postazione.IP, AL, "", "creaAL", string.Format("Creato AL RX su linea {0}, note: {1} ", Postazione.currCodLinea, noteTrim));
          Postazione.CssClass = "stileAttesa";
          Postazione.warningText = "";
          Postazione.messaggiText = traduci("cartAlStampato");
          txtCesta.Text = "";
          // elimino note
          txtNote.Text = "";
          // resetto particolare...
          currParticolare = "";
          qta = 0;
        }
        Response.Redirect(user_std.pagCorrente);
      }
      else
      {
        // ricarico che mi manca postazione!
        Postazione.CssClass = "stileAttesa";
        Postazione.warningText = traduci("ERR-POS-001");
        Postazione.messaggiText = "";
        Response.Redirect(user_std.pagCorrente);
      }
    }
  }
}