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

namespace GMW.WebUserControls
{
  public partial class mod_LiqDtAnom : GMW_data.UserControl
  {
    /// <summary>
    /// Oggetto locale gestione classe datamatrix...
    /// </summary>
    protected DataMatrix DataMatrix_mgr = new DataMatrix();
    /// <summary>
    /// flusso associato (hard coded) a LI (finiti)
    /// </summary>
    protected string flusso = "FI";
    /// <summary>
    /// flusso associato (hard coded) ad ancestor TT (Trattati)
    /// </summary>
    protected string flussoAnc = "TT";
    /// <summary>
    /// flusso associato (hard coded) a temporaneo TL (Trattati/Liquidi)
    /// </summary>
    protected string flussoTemp = "TL";
    /// <summary>
    /// flusso associato (hard coded) a temporaneo TL (Trattati/Liquidi)
    /// </summary>
    protected string flussoRX = "RX";
    /// <summary>
    /// stato associato (hard coded) a UDC in OUT: Finito
    /// </summary>
    protected string statoUdcOut = "Fin";
    /// <summary>
    /// stato associato (hard coded) a UDC in IN: Trattato da travaso AL
    /// </summary>
    protected string statoUdcIn = "Tratt";
    /// <summary>
    /// codice evento dell'UDC definitivo (OUT) che si crea
    /// </summary>
    protected string codEventoUdcOut = "UDC_TL_DT";
    /// <summary>
    /// codice evento dell'UDC temporaneo (IN) che si crea
    /// </summary>
    protected string codEventoUdcIn = "UDC_TRATT";
    protected string cssOk = "stileComandoOk";
    protected string cssErr = "stileComandoKo";
    protected string cssWait = "stileComandoND";
    protected string cssAtt = "stileAttesa";
    protected string cssWarn = "stileComandoWarn";
    protected string cssAdd = "stileComandoAdd";
    public event EventHandler eh_reqUpdate;
    /// <summary>
    /// ultimo valore barcode letto (x confronto conferme doppio input...)
    /// </summary>
    protected string lastBarcodeIn
    {
      get
      {
        return memLayer.ML.StringSessionObj(string.Format("lastBCode_{0}", uid));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("lastBCode_{0}", uid), value, false);
      }
    }
    /// <summary>
    /// Codice AL della cella corrente
    /// </summary>
    protected string destAL
    {
      get
      {
        return lblDestAL.Text.Trim();
      }
      set
      {
        lblDestAL.Text = value;
      }
    }
    /// <summary>
    /// Codice AL associato alla cella corrente...
    /// </summary>
    protected string AlByCella
    {
      get
      {
        string answ = "";
        try
        {
          answ = string.Format("ALF00{0}", Postazione.currCodCella);
          // controllo se esista AL sennò lo creo...
          if (MagClass.magazzino.taEA.getByAL(answ).Rows.Count == 0)
          {
            MagClass.magazzino.taEA.Insert(answ, true, DateTime.Now, MagClass.magazzino.CodSoggCurrUser, "", "", "", 0);
          }
        }
        catch
        { }
        return answ;
      }
    }
    /// <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>
    /// indica UDC correntemente selezionato
    /// </summary>
    protected string currUDC
    {
      get
      {
        return memLayer.ML.StringSessionObj(string.Format("UDC_{0}", uid));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("UDC_{0}", uid), value, memLayer.ML.confReadBool("keepParticolareSel"));
      }
    }
    /// <summary>
    ///  num pezzi dell'ultimo UDC di uguale particolare e stato fatto...
    /// </summary>
    public int pezziUdc
    {
      get
      {
        int answ = 0;
        try
        {
          answ = (int)MagClass.magazzino.taCartellini.getLastByParticolareStatoConImb(memLayer.ML.StringSessionObj("CodCS"), currParticolare, statoUdcOut)[0].Qta;
        }
        catch
        {
          answ = memLayer.ML.cdvi("QtaImballoFiniti");
        }
        return answ;
      }
    }
    /// <summary>
    /// cod imballo dell'ultimo UDC del particolare generato
    /// </summary>
    public string lastCodImb
    {
      get
      {
        string answ = "";
        try
        {
          answ = MagClass.magazzino.taCartellini.getLastByParticolareStatoConImb(memLayer.ML.StringSessionObj("CodCS"), currParticolare, statoUdcOut)[0].CodImballo;
        }
        catch
        { }
        return answ;
      }
    }
    /// <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>
    /// valore barcode
    /// </summary>
    public string barcodeIn
    {
      get
      {
        return txtBarcode.Text.Trim();
      }
      set
      {
        txtBarcode.Text = value;
      }
    }
    /// <summary>
    /// definisce se mostrare controlli x ri-assegnazione storia al Dtx
    /// </summary>
    public bool showForceUdcTratt
    {
      get
      {
        return memLayer.ML.BoolSessionObj(string.Format("showForceUdcTratt_{0}", uid));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("showForceUdcTratt_{0}", uid), value, memLayer.ML.confReadBool("keepParticolareSel"));
      }
    }
    /// <summary>
    /// caricamento pagina
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
      if (!Page.IsPostBack)
      {
        Postazione.messaggiText = "";
        Postazione.warningText = "";
        qta = 0;
        currUDC = "";
        txtNumTT.Text = string.Format("{0:yy}000000", DateTime.Now);
        calcolaUdcTT();
        string AL = string.Format("ALT{0:yy}000000000", DateTime.Now);
        MagClass.magazzino.taET.checkEmptyYear(memLayer.ML.cdv("CodCS"), AL, lblUDC.Text, txtNumTT.Text);
        showForceUdcTratt = false;
        setDefaultVal();
      }
      setVisibility();
      checkBarcode();
    }
    /// <summary>
    /// imposta i valori di default ad avvio
    /// </summary>
    private void setDefaultVal()
    {
      destAL = AlByCella;
    }
    /// <summary>
    /// sistema modalità input
    /// </summary>
    private void setVisibility()
    {
      bool showBtn = false;
      // ora controllo btn quantità
      if (grViewDest.SelectedIndex >= 0)
      {
        showBtn = true;
      }
      divQta.Visible = showBtn;
      divImballi.Visible = showBtn;
      if (showBtn)
      {
        selezionaImballo();
      }
      // definisce se mostrare controlli x forzare trattamento / UDC di riferimento 0000 oppure uno vero...
      divForceUdcTratt.Visible = showForceUdcTratt;
    }
    /// <summary>
    /// reset maschera...
    /// </summary>
    protected void doReset()
    {
      // resetta
      lastBarcodeIn = "";
      Postazione.messaggiText = "";
      Postazione.warningText = "";
      Postazione.CssClass = cssAtt;
      doUpdate();
    }
    /// <summary>
    /// Verifica l'AL se sia ok x procedere:
    /// - Attivo
    /// </summary>
    /// <param name="AL"></param>
    /// <param name="Tipo">T/L</param>
    /// <returns></returns>
    protected bool checkAL(string AL, string tipo)
    {
      bool answ = false;
      try
      {
        answ = MagClass.magazzino.taEA.getByAL_TipoAttivo(AL, tipo).Rows.Count > 0;
      }
      catch
      { }
      if (answ)
      {
        Postazione.warningText = "";
        Postazione.CssClass = "stileComandoOk";
      }
      else
      {
        Postazione.warningText = traduci("ErroreAlNonTtAttivo");
        Postazione.CssClass = "stileComandoKo";
      }

      return answ;
    }
    /// <summary>
    /// Verifica l'AL se abbia datamatrix
    /// </summary>
    /// <param name="AL"></param>
    /// <returns></returns>
    protected bool checkDtxAL(string AL)
    {
      bool answ = false;
      try
      {
        answ = DataMatrix_mgr.taDtx2UDC.getByAL(AL).Rows.Count > 0;
      }
      catch
      { }
      if (!answ)
      {
        Postazione.warningText = traduci("ErroreAlNonDtx");
        Postazione.CssClass = "stileComandoKo";
      }
      else
      {
        Postazione.warningText = "";
        Postazione.CssClass = "stileComandoOk";
      }
      return answ;
    }
    /// <summary>
    /// controlla se ci sia un barcode e cosa farne...
    /// </summary>
    private void checkBarcode()
    {
      if (barcodeIn != "")
      {
        Postazione.messaggiText = string.Format("{0}: {1}", traduci("BCodeIns"), barcodeIn);
        switch (MagClass.tipoBCode_L5(barcodeIn))
        {
          case tipoCodiceBarcode.Imballo:
            // cerco di selezionare!
            try
            {
              ddlImballi.SelectedValue = barcodeIn;
            }
            catch
            {
              Postazione.warningText = traduci("ERR-IMB-001");
              Postazione.CssClass = "stileComandoKo";
            }
            break;
          case tipoCodiceBarcode.Comando:
            // se è reset cancello tutto!
            if (barcodeIn == memLayer.ML.cdv("cmdReset"))
            {
              doReset();
            }
            break;
          case tipoCodiceBarcode.UDC:
            // controllo di avere destAL valido, sennò ricarico pagina...
            if (destAL.Length > 5)
            {
              // controllo se sia un UDC valido...
              if (MagClass.magazzino.checkUDC(barcodeIn))
              {
                // controllo se sia un UDC di finiti LIQ in posizione 4...
                DS_magazzino.ElencoCartelliniRow cartUDC = MagClass.magazzino.taCartellini.getByUdc(barcodeIn)[0];
                if (cartUDC.CodStato == statoUdcOut && cartUDC.IdxPosizione == memLayer.ML.cdvi("IdxPosizioneFiniti"))
                {
                  // controllo NON ci sia già un UDC di pari particolare caricato nella postazione corrente (non posso avere 2 UDC a pari particolare da riempire...)
                  if (MagClass.magazzino.taCartellini.getByParticolareAL(cartUDC.Particolare, destAL).Rows.Count == 0)
                  {
                    // controllo NON sia UDC in LDP e già PRELEVATO
                    if (MagClass.magazzino.taRigheListePrelievo.getByUdc(barcodeIn).Select("Prelevato = 1").Length == 0)
                    {
                      // controllo NON abbia blocco x FinDtx...
                      if (MagClass.magazzino.udcHasAttr(barcodeIn, "BL"))
                      {
                        Postazione.messaggiText = "";
                        Postazione.warningText = traduci("ERR-LIQ-006");
                        Postazione.CssClass = cssErr;
                      }
                      else
                      {
                        // se è ok RICARICO UDC in posizione corrente...
                        bool fatto = MagClass.magazzino.liquidiRiprendiInCaricoUDC(barcodeIn, MagClass.magazzino.CodSoggCurrUser, destAL, Postazione.currIdxCella);
                        if (fatto)
                        {
                          Postazione.messaggiText = traduci("RiCaricatoUdcLiq");
                          Postazione.warningText = "";
                          Postazione.CssClass = cssOk;
                        }
                        else
                        {
                          Postazione.messaggiText = "";
                          Postazione.warningText = traduci("ERR-LIQ-001");
                          Postazione.CssClass = cssErr;
                        }
                      }
                    }
                    else
                    {
                      Postazione.messaggiText = "";
                      Postazione.warningText = traduci("ERR-LIQ-005");
                      Postazione.CssClass = cssErr;
                    }
                  }
                  else
                  {
                    Postazione.messaggiText = "";
                    Postazione.warningText = traduci("ERR-LIQ-004");
                    Postazione.CssClass = cssErr;
                  }
                }
                else
                {
                  Postazione.messaggiText = "";
                  Postazione.warningText = traduci("ERR-LIQ-002");
                  Postazione.CssClass = cssErr;
                }
              }
              else
              {
                Postazione.messaggiText = "";
                Postazione.warningText = traduci("ERR-LIQ-003");
                Postazione.CssClass = cssErr;
              }
            }
            else
            {
              Postazione.messaggiText = "";
              Postazione.warningText = traduci("ERR-ALF-001");
              Postazione.CssClass = cssErr;
            }
            break;
          case tipoCodiceBarcode.DataMatrixTrovato:
            string NewUDC = "";
            string udcRX = "";
            bool dtxBloccato = false;
            bool dtxInUdcDest = false;
            DateTime adesso = DateTime.Now;

            /*---------------------------------------------------
             * verifico DTX: per procedere deve  !!! NON ESSERE associato ad un UDC spedito / in lista di prelievo !!!
             * ed avere almeno una di queste condizioni
             * - essere tra i Missing In Action (con o senza TT)
             * - essere nuovo (mai associato ad UDC)
             * 
             * abbiamo i seguenti casi
             * 1) il datamatrix HA un UDC collegato con un trattamento (TT) --> la sua storia viene tenuta
             * 2) il datamatrix NON HA alcun UDC collegato (nemmeno RX)
             * 3) il datamatrix HA un UDC collegato SOLO RX (SENZA un trattamento)
             * 
             * nei casi (2) e (3) NON HA un trattamento, a questo abbiamo 2 opzioni x ricostruire la sua storia
             * a) copiandola da  quella di un UDC esistente 
             * b) copiandola da un UDC/trattamento fittizio (0000 dell'anno)
             * 
             ---------------------------------------------------*/

            // recupero record DataMatrix (se presenti)
            DS_DataMatrix.Dtx2UDCDataTable tabDtx2Udc = DataMatrix_mgr.taDtx2UDC.getByDtx(barcodeIn);
            // se ho storia
            if (tabDtx2Udc.Rows.Count > 0)
            {
              // cerco NON sia stato spedito o in LDP
              if (DataMatrix_mgr.taDtxBlocked.GetData(barcodeIn).Rows.Count > 0)
              {
                dtxBloccato = true;
              }
            }
            // controllo datamatrix sia OK
            bool isOk = false;
            try
            {
              isOk = DataMatrix_mgr.taVerifica.GetData(barcodeIn)[0].StatoDtx == "OK";
            }
            catch
            { }

            // IN PRIMIS verifico NON SIA KO...
            if (!isOk)
            {
              Postazione.messaggiText = barcodeIn;
              Postazione.warningText = traduci("ERR-DTX-012");
              Postazione.CssClass = cssErr;
            }
            // POI verifico Dtx NON sia spedito / LDP
            else if (dtxBloccato)
            {
              // mostro errore poiché spedito / in LDP...
              Postazione.messaggiText = "";
              Postazione.warningText = traduci("ERR-DTX-009");
              Postazione.CssClass = cssErr;
            }
            else
            {
              // calcolo UDC di destinazione x particolare del Dtx letto
              NewUDC = getUdcDest(tabDtx2Udc);
              udcRX = currUdcTT.Replace(flussoAnc, flussoRX);
              // verifico se posso procedere: in caso NON ci fosse UDC di destinazione
              if (string.IsNullOrEmpty(NewUDC))
              {
                // richiedo di caricare un UDC valido per il particolare richiesto...
                Postazione.messaggiText = "";
                Postazione.warningText = traduci("ERR-DTX-007");
                Postazione.CssClass = cssErr;
              }
              else // mentre se ho un UDC di destinazione cui legare il Dtx...
              {

                // verifico che il DataMatrix NON SIA già nell'UDC di destinazione...
                dtxInUdcDest = DataMatrix_mgr.taDtx2UDC.getByDtx(barcodeIn).Select(string.Format("UDC = '{0}'", NewUDC)).Length > 0;
                if (dtxInUdcDest)
                {
                  // errore: già spostato!
                  Postazione.warningText = "";
                  Postazione.messaggiText = traduci("ERR-DTX-006");
                  Postazione.CssClass = cssOk;
                }
                else
                {
                  // se zero record = niente storia...
                  if (tabDtx2Udc.Rows.Count == 0)
                  {
                    // verifico se sono GIA' in modo forzatura UdcTratt: con 2 letture è verifica che si VUOLE ri-assegnare la storia dell'UDC/trattamento indicato al datamatrix letto
                    if (showForceUdcTratt)
                    {
                      // assegno datamatrix a Udc Destinazione, TT ed RX
                      assignDtx2UDC(barcodeIn, NewUDC, currUdcTT, udcRX);
                      // tolgo modalità forza trattamento
                      showForceUdcTratt = false;
                      Postazione.warningText = "";
                      Postazione.messaggiText = traduci("DatamatrixSpostato");
                      Postazione.CssClass = cssOk;
                    }
                    else
                    {
                      // non ha storia! mostro opzione x forzare un certo codice UDC da un datamatrix "buono" con relativo TT oppure usare un trattamento fittizio(di default 0000 dell'anno)
                      showForceUdcTratt = true;
                      Postazione.warningText = traduci("ConfermareTrattamento");
                      Postazione.CssClass = cssAdd;
                    }
                  }
                  else
                  {
                    // verifico se il datamatrix ha UDC con TT
                    if (tabDtx2Udc.Select("CodStato = 'Tratt'").Length != 0)
                    {
                      // se ce l'ha sposto Dtx in UDC finale e associo UDC TT ad UDC FI
                      assignDtx2UDC(barcodeIn, NewUDC);
                    }
                    else
                    {
                      // verifico se sono GIA' in modo forzatura UdcTratt: con 2 letture è verifica che si VUOLE ri-assegnare la storia dell'UDC/trattamento indicato al datamatrix letto
                      if (showForceUdcTratt)
                      {
                        // se avevo già RX NON lo cambio...
                        if (tabDtx2Udc.Select("CodStato = 'ContrRx'").Length != 0)
                        {
                          udcRX = "";
                        }
                        // assegno datamatrix a Udc Destinazione, TT ed RX
                        assignDtx2UDC(barcodeIn, NewUDC, currUdcTT, udcRX);
                        // tolgo modalità forza trattamento
                        showForceUdcTratt = false;
                        Postazione.warningText = "";
                        Postazione.messaggiText = traduci("DatamatrixSpostato");
                        Postazione.CssClass = cssOk;
                      }
                      else
                      {
                        // non ha storia! mostro opzione x forzare un certo codice UDC da un datamatrix "buono" con relativo TT oppure usare un trattamento fittizio(di default 0000 dell'anno)
                        showForceUdcTratt = true;
                        Postazione.warningText = traduci("ConfermareTrattamento");
                        Postazione.CssClass = cssAdd;
                      }
                    }
                  }
                }
              }
            }
            break;
          default:
            Postazione.warningText = traduci("ERR-BCD-001");
            Postazione.CssClass = cssErr;
            break;
        }
        barcodeIn = "";
      }
      doUpdate();
    }
    /// <summary>
    /// calcolo/ricavo UDC di destinazione (se presente)
    /// </summary>
    /// <param name="tabDtx2Udc"></param>
    /// <returns></returns>
    private string getUdcDest(DS_DataMatrix.Dtx2UDCDataTable tabDtx2Udc)
    {
      string NewUDC = "";
      // verifico di avere un UDC destinazione x il particolare del datamatrix letto... altrimenti NON possiamo procedere...
      try
      {
        currParticolare = tabDtx2Udc[0].Particolare;
      }
      catch
      {
        currParticolare = "";
      }
      // se non ho particolare PROVO a decodificare da codice datamatrix
      if (string.IsNullOrEmpty(currParticolare))
      {
        try
        {
          // vers 2.9 modifica per multi-datamatrix
          currParticolare = DataMatrix_mgr.taDtxAcquisiti.getByKey(barcodeIn)[0].Particolare;
          // vers vecchia
          //currParticolare = DataMatrix_mgr.taDecode.GetData(barcodeIn, "")[0].Particolare;
        }
        catch
        { }
      }
      if (currParticolare != "")
      {
        try
        {
          NewUDC = MagClass.magazzino.taCartellini.getByParticolareAL(currParticolare, destAL)[0].UDC;
        }
        catch
        {
          NewUDC = "";
        }
      }
      else
      {
        // datamatrix NON riconosciuto
        Postazione.messaggiText = "";
        Postazione.warningText = traduci("ERR-DTX-008");
        Postazione.CssClass = cssErr;
      }
      return NewUDC;
    }
    /// <summary>
    /// rappresenta il codice UDC del corrente TT per resettare history pezzo DataMatrix
    /// </summary>
    private string currUdcTT
    {
      get
      {
        // ricalcolo
        calcolaUdcTT();
        // default: cartellino TT "nullo"
        string UdcTT = "";
        // cerco di recuperare valore UDC in caso sia stato inserito nel textBox
        try
        {
          UdcTT = lblUDC.Text;
        }
        catch
        {
          UdcTT = "";
        }
        // restituisco risposta
        return UdcTT;
      }
    }
    /// <summary>
    /// evento cambio num TT
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void txtNumTT_TextChanged(object sender, EventArgs e)
    {
      // se non inizia per anno aggiunge anno e formatta anno + 6 cifre...
      if (!txtNumTT.Text.Trim().StartsWith(string.Format("{0:yy}", DateTime.Now)))
      {
        // aggiungo anno e formatto numero 6 cifre...
        try
        {
          int numTT = Convert.ToInt32(txtNumTT.Text.Trim());
          txtNumTT.Text = txtNumTT.Text = string.Format("{0:yy}{1:000000}", DateTime.Now, numTT);
        }
        catch
        {
          txtNumTT.Text = "";
        }
      }
      calcolaUdcTT();
    }
    /// <summary>
    /// ricalcolo UDC da num TT
    /// </summary>
    private void calcolaUdcTT()
    {
      string UdcTT = "";
      try
      {
        // cerco UDC da num tratt...
        UdcTT = MagClass.magazzino.taCartellini.getByParticolareTT(currParticolare, txtNumTT.Text.Trim())[0].UDC;
      }
      catch
      {
        UdcTT = "";
      }
      if (string.IsNullOrEmpty(UdcTT))
      {
        // se non lo trovo uso UDC e trattamento "undef" a 0000, eventualmente creando UDC annuale
        UdcTT = string.Format("U{0}{1}{2:yy}000000", memLayer.ML.cdv("CodCS"), flussoAnc, DateTime.Now);
      }
      lblUDC.Text = UdcTT;
    }
    /// <summary>
    /// assegno un Dtx ad un codice UDC fin con eventuale reset storia (e copia da udcTratt)
    /// </summary>
    /// <param name="codDtx">Codice DataMatrix da processare</param>
    /// <param name="UDCFin">UDC finiti di destinazione</param>
    /// <param name="UDCTratt">UDC dei trattamenti da cui ricavare la stodia da associare, anche "fasullo"/0000 (se VUOTO NON riassocia)</param>
    /// <param name="UDCRx">UDC Rx da riassociare (se vuoto NON riassocia)</param>
    /// <returns></returns>
    private bool assignDtx2UDC(string codDtx, string UDCFin)
    {
      // assegno datamatrix a Udc Destinazione e associo UDC TT ad UDC FI
      bool spostaDtx = false;
      // se lo trovo chiamo procedura di spostamento Dtx tra UDC sorgente --> dest 
      DataMatrix_mgr.taDtx2UDC.UpdateUDC(UDCFin, barcodeIn, statoUdcOut, DateTime.Now, MagClass.magazzino.CodSoggCurrUser, true, true);
      return spostaDtx;
    }
    /// <summary>
    /// assegno un Dtx ad un codice UDC fin con eventuale reset storia (e copia da udcTratt)
    /// </summary>
    /// <param name="codDtx">Codice DataMatrix da processare</param>
    /// <param name="UDCFin">UDC finiti di destinazione</param>
    /// <param name="UDCTratt">UDC dei trattamenti da cui ricavare la stodia da associare, anche "fasullo"/0000 (se VUOTO NON riassocia)</param>
    /// <param name="UDCRx">UDC Rx da riassociare (se vuoto NON riassocia)</param>
    /// <returns></returns>
    private bool assignDtx2UDC(string codDtx, string UDCFin, string UDCTratt, string UDCRx)
    {
      // assegno datamatrix a Udc Destinazione e associo UDC TT ad UDC FI
      bool spostaDtx = false;
      // se ho UdcRX lo cambio...
      if (UDCRx != "")
      {
        DataMatrix_mgr.taDtx2UDC.UpdateUDC(UDCRx, barcodeIn, "ContrRx", DateTime.Now, MagClass.magazzino.CodSoggCurrUser, true, true);
      }
      // sostituisco UDC TT e Fin..
      DataMatrix_mgr.taDtx2UDC.UpdateUDC(UDCTratt, barcodeIn, statoUdcIn, DateTime.Now, MagClass.magazzino.CodSoggCurrUser, true, true);
      DataMatrix_mgr.taDtx2UDC.UpdateUDC(UDCFin, barcodeIn, statoUdcOut, DateTime.Now, MagClass.magazzino.CodSoggCurrUser, true, true);
      return spostaDtx;
    }
    /// <summary>
    /// aggiorna tabella + focus a barcode
    /// </summary>
    public void doUpdate()
    {
      setDefaultVal();
      setVisibility();
      grViewDest.DataBind();
      // raise dell'evento
      if (eh_reqUpdate != null)
      {
        eh_reqUpdate(this, new EventArgs());
      }
      verificaBtnStampa();
      txtBarcode.Focus();
    }
    /// <summary>
    /// evento selezione grView destinazione: ricarico dati!
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void grViewDest_SelectedIndexChanged(object sender, EventArgs e)
    {
      // ricarico dati dell'UDC come particolare e quantità...
      currUDC = grViewDest.SelectedDataKey["UDC"].ToString();
      int qtaDtx = 0;
      if (MagClass.magazzino.checkUDC(currUDC))
      {
        currParticolare = DataProxy.obj.taCartellini.stp_getByUdc(currUDC)[0].Particolare;
        qta = Convert.ToInt32(DataProxy.obj.taCartellini.stp_getByUdc(currUDC)[0].Qta);
        qtaDtx = Convert.ToInt32(MagClass.magazzino.taA2U2D.getByUDC(currUDC)[0].QtaDtx);
        // imposto particolare...
        lblPart.Text = currParticolare;
        ddlImballi.DataBind();
      }
      Postazione.messaggiText = traduci("partSelected");
      Postazione.warningText = "";
      Postazione.CssClass = "stileComandoOk";
      setVisibility();
      doUpdate();
      // fisso focus su note!
      txtNote.Focus();
    }
    /// <summary>
    /// Verifica se Assieme sia vuoto (no DTX negli UDC)
    /// </summary>
    /// <param name="AL">Codice AL</param>
    /// <returns></returns>
    protected bool assiemeIsEmpty(string AL)
    {
      bool answ = false;
      try
      {
        answ = DataMatrix_mgr.taDtx2UDC.getByAL(AL).Rows.Count == 0;
      }
      catch { }
      return answ;
    }
    /// <summary>
    /// reset della selezione
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnReset_Click(object sender, EventArgs e)
    {
      grViewDest.SelectedIndex = -1;
      qta = 0;
      currUDC = "";
      setVisibility();
      doUpdate();
    }
    /// <summary>
    /// update Qty x UDC selezionato...
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void lbtUpdQty_Click(object sender, EventArgs e)
    {
      MagClass.magazzino.taCartellini.updateQty(currUDC, MagClass.magazzino.CodSoggCurrUser, "U", codEventoUdcOut, qta);
      // fix tablet
      currUDC = "";
      currParticolare = "";
      grViewDest.SelectedIndex = -1;
      doUpdate();
    }
    /// <summary>
    /// richiesta (ri)stampa UDC
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public void ristampa()
    {
      bool fatto = false;
      fatto = MagClass.magazzino.ristampaUdc(udcReq, Postazione.printer, Request.UserHostName);
      // registro ri-stampa UDC
      if (fatto) MagClass.magazzino.taSAO.insertQuery(DateTime.Now, MagClass.magazzino.CodSoggCurrUser, Postazione.name, Postazione.IP, udcReq, "", "stampaUDC", string.Format("Ri-Stampato UDC Dtx {0} su linea anomalie {1}", currUDC, Postazione.currCodLinea));
    }
    /// <summary>
    /// verifica visibilità btn stampa UDC
    /// </summary>
    private void verificaBtnStampa()
    {
      bool showBtnStampa = false;
      // se ho selezionato udc...
      if (currUDC != "")
      {
        DS_magazzino.v_A2U2DRow riga;
        int qtaUDC = 0;
        int qtaDtx = 0;
        try
        {
          riga = MagClass.magazzino.taA2U2D.getByUDC(currUDC)[0];
          qtaUDC = Convert.ToInt32(riga.Qta);
          qtaDtx = riga.QtaDtx;
        }
        catch
        { }
        if (qtaUDC > 0)
        {
          // se le qta voluta e dtx sono uguali...
          if (qtaUDC == qtaDtx)
          {
            showBtnStampa = true;
          }
        }
      }
      divNote.Visible = showBtnStampa;
    }
    /// <summary>
    /// fornisce in output la corretta classe css x icona
    /// </summary>
    /// <param name="qta"></param>
    /// <param name="qtaDtx"></param>
    /// <returns></returns>
    public string cssGlyphByQty(object _qta, object _qtaDtx)
    {
      string answ = "fa fa-pencil fa-2x";
      int qtaUDC = 0;
      int qtaDtx = -1;
      try
      {
        qtaUDC = Convert.ToInt32(_qta);
      }
      catch { }
      try
      {
        qtaDtx = Convert.ToInt32(_qtaDtx);
      }
      catch { }
      if (qtaUDC == qtaDtx)
      {
        answ = "fa fa-print fa-2x";
      }
      return answ;
    }
    /// <summary>
    /// effettua processo di sistemazione UDC e stampa
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void lbtStampaUDC_Click(object sender, EventArgs e)
    {
      // verifico postazione sia valida...
      if (Postazione.name != "" && Postazione.IP != "" && Postazione.currCodCella != "")
      {
        // in base ad AL sorgente e destinazione, fa le operazioni di update x UDC e poi lo stampa
        bool fatto = false;
        string noteTrim = txtNote.Text.Trim();
        try
        {
          // update UDC!
          fatto = MagClass.magazzino.liquidiFullUpdate("", flussoAnc, currUDC, ddlImballi.SelectedValue, noteTrim, MagClass.magazzino.CodSoggCurrUser);
        }
        catch
        { }
        if (fatto)
        {
          // lancio stampa
          MagClass.magazzino.stampaUdc(currUDC, Postazione.printer, tipoCartellino.cartFinitiSP, Request.UserHostName);
          // registro creazione AL
          MagClass.magazzino.taSAO.insertQuery(DateTime.Now, MagClass.magazzino.CodSoggCurrUser, Postazione.name, Postazione.IP, currUDC, currParticolare, "stampaUDC", string.Format("Stampato UDC Dtx {0} su linea anomalie {1}, note: {2} ", currUDC, Postazione.currCodLinea, noteTrim));
          Postazione.CssClass = cssAtt;
          Postazione.warningText = "";
          Postazione.messaggiText = traduci("cartUDCStampato");
          // calcolo particolare completo di descrizione
          DS_Applicazione.ElencoCartelliniRow riga = DataProxy.obj.taCartellini.stp_getByUdc(currUDC)[0];
          string particolare = string.Format("{0} - {1}", riga.Particolare, riga.DescParticolare);
          // resetto...
          grViewDest.SelectedIndex = -1;
          qta = 0;
          currUDC = "";
        }
        doUpdate();
      }
      else
      {
        // ricarico che mi manca postazione!
        Postazione.CssClass = cssAtt;
        Postazione.warningText = traduci("ERR-POS-001");
        Postazione.messaggiText = "";
        Response.Redirect(user_std.pagCorrente);
      }
    }
    /// <summary>
    /// udc da stampare
    /// </summary>
    protected string udcReq
    {
      get
      {
        return memLayer.ML.StringSessionObj("udcSelSAO");
      }
    }
    /// <summary>
    /// preseleziono (se possibile) imballo...
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void ddlImballi_DataBound(object sender, EventArgs e)
    {
      selezionaImballo();
    }
    /// <summary>
    /// seleziona imballo corretto
    /// </summary>
    private void selezionaImballo()
    {
      string codImb = "";
      // cerco se c'è un imballo x particolare corrente...
      if (currParticolare != "")
      {
        codImb = lastCodImb;
      }
      else
      {
        codImb = memLayer.ML.cdv("CodImballoFiniti");
      }
      try
      {
        // preseleziono
        ddlImballi.SelectedValue = codImb;
      }
      catch
      { }
    }

  }
}