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 : 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_DT";
    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();
      }
      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()
    {
      lblIdxCella.Text = Postazione.currIdxCella.ToString();
    }
    /// <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:
            okDTL = getDateTimeLine(barcodeIn, false);
            if (okDTL)
            {
              Postazione.messaggiText = traduci("SetDataFus");
              Postazione.warningText = "";
              Postazione.CssClass = "stileComandoOk";
            }
            else
            {
              Postazione.messaggiText = traduci("ERR-BCD-004");
              Postazione.warningText = "";
              Postazione.CssClass = "stileComandoKo";
            }
            break;
          case tipoCodiceBarcode.DateTimeLine:
            okDTL = getDateTimeLine(barcodeIn, true);
            if (okDTL)
            {
              Postazione.messaggiText = traduci("SetDataFus");
              Postazione.warningText = "";
              Postazione.CssClass = "stileComandoOk";
            }
            else
            {
              Postazione.messaggiText = traduci("ERR-BCD-004");
              Postazione.warningText = "";
              Postazione.CssClass = "stileComandoKo";
            }
            break;
          case tipoCodiceBarcode.Particolare:
            // imposto il particolare corrente
            currParticolare = barcodeIn;
            // controllo esista il particolare scansionato
            if (DataProxy.obj.taAnagParticolari.getByParticolare(currParticolare).Rows.Count == 0)
            {
              currParticolare = "";
              Postazione.messaggiText = traduci("partNotFound");
              Postazione.CssClass = "stileComandoKo";
            }
            else
            {
              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");
            }
            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
                {
                  // controllo esito marcatura...
                  bool marcaturaOk = false;
                  string formatiSbloccati = memLayer.ML.cdv(string.Format("sbloccoKO#{0}", user_std.pagCorrente)); // sbloccoKO#PostRX_DT
                                                                                                                   // verifico da conf SE il formato ha controllo KO sbloccato (default: KO BLOCCATI!!!) in tal caso è già OK!!! ATTENZIONE CERCA #codice#
                  if (formatiSbloccati.IndexOf("#" + FormatoDtmxLinea + "#") > 0)
                  {
                    marcaturaOk = true;
                  }
                  if (!marcaturaOk)
                  {
                    // recupero elenco datamatrix
                    DS_DataMatrix.v_ElencoDmtxDataTable tabDmtx = DataMatrix_mgr.taVED.getByKey(barcodeIn);
                    if (tabDmtx.Rows.Count > 0)
                    {
                      // verifica esitoMarcatura OK
                      marcaturaOk = (tabDmtx[0].EsitoMarcatura == "OK");
                    }
                  }

                  // verifico se datamatrix SIA KO (marcatura NON OK...)
                  if (!marcaturaOk)
                  {
                    // errore corrispondenza formato Dtmx
                    Postazione.messaggiText = barcodeIn;
                    Postazione.warningText = traduci("ERR-DTX-012");
                    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);
                        //currParticolare = DataMatrix_mgr.taDecode.GetData(barcodeIn, FormatoDtmxLinea)[0].Particolare;
                      }
                      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 != "")
                      {
                        // 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);
                        if (tabDmtx.Rows.Count > 0)
                        {
                          if (tabDmtx[0].EtichettaFusione != "")
                          {
                            try
                            {
                              // imposto dataOra e linea fusione
                              okDTL = getDateTimeLine(tabDmtx[0].EtichettaFusione, true);
                              if (okDTL)
                              {
                                Postazione.warningText = traduci("SetDataFus");
                              }
                            }
                            catch
                            { }
                          }
                        }

                        // genera eventuale UDC del particolare su cella/posizione corrente
                        qta = 1; // tanto poi si ricalcola...
                        checkCreaUDC();
                        // verifico se devo fare gestione con intervallo dtx... da tab config DB)
                        if (memLayer.ML.configDbVal("CreaDtxByInt") == "1")
                        //if (utils.obj.configDbVal("CreaDtxByInt") == "1")
                        {
                          // ora chiamo la stored che fa il check x tutti i particolari nell'intervallo dei Dtx associati alla cella e (se almeno 2) nel caso crea UDC
                          checkIntervalloDtx();
                        }
                        /*-------------------------------------------------------------------------------------------------
                        * chiamo la stored che in blocco
                        * - associa Dtx a UDC
                        * - fa controllo, se ho almeno 2 Dtx ok associo tutti i Dtx compresi nell'intervallo min-MAX
                        *--------------------------------------------------------------------------------------------------
                        */
                        DataMatrix_mgr.taDtx2UDC.RxSetDtx2Udc(barcodeIn, MagClass.magazzino.CodSoggCurrUser, statoUDC, memLayer.ML.cdvi("IdxPosizioneRxTemp"), Postazione.currIdxCella);

                        // 2017.07.22 svuoto barcodeIn..
                        barcodeIn = "";
                      }
                    }
                  }
                }
              }
            }
            else
            {
              Postazione.messaggiText = barcodeIn;
              Postazione.warningText = traduci("DtxGiaAssegnato");
              Postazione.CssClass = "stileComandoKo";
            }
            break;
          case tipoCodiceBarcode.DataMatrixDecodificato:
            // SEGNALO che ho trovato un partnumber che è un possibile datamatrix, ma che non è nell'elenco dei datamatrix acquisiti...
            Postazione.warningText = traduci("partNumFoundNoDtx");
            Postazione.CssClass = "stileComandoWarn";
            // faccio le verifiche... verifico formato datamatrix sia COMPATIBILE con formato datamatrix della linea corrente...
            if (FormatoDtmxBarcode != FormatoDtmxLinea)
            {
              // errore corrispondenza formato Dtmx
              Postazione.messaggiText = barcodeIn;
              Postazione.warningText = traduci("ERR-DTX-014");
              Postazione.CssClass = "stileComandoKo";
            }
            else
            {
              // se da web.config permesso il "force" di acquisizione
              if (!memLayer.ML.confReadBool("enableDtxNotAcq"))
              {
                //errore gestione dmtx non acquisizione NON E' permessa
                Postazione.messaggiText = barcodeIn;
                Postazione.warningText = traduci("ERR-DTX-015");
                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(false);
                  }
                  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 != "")
                  {
                    // genera eventuale UDC del particolare su cella/posizione corrente
                    qta = 1; // tanto poi si ricalcola...
                    checkCreaUDC();
                    /*-------------------------------------------------------------------------------------------------
                    * chiamo la stored che in blocco
                    * - associa Dtx a UDC
                    * - fa controllo, se ho almeno 2 Dtx ok associo tutti i Dtx compresi nell'intervallo min-MAX
                    *--------------------------------------------------------------------------------------------------
                    */
                    DataMatrix_mgr.taDtx2UDC.RxSetDtx2Udc(barcodeIn, MagClass.magazzino.CodSoggCurrUser, statoUDC, memLayer.ML.cdvi("IdxPosizioneRxTemp"), Postazione.currIdxCella);
                  }
                }
              }
            }
            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();
      // 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();
      // raise dell'evento
      if (eh_reqUpdate != null)
      {
        eh_reqUpdate(this, new EventArgs());
      }
      verificaBtnStampa();
      txtBarcode.Focus();
    }
    /// <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;
        try
        {
          DS_magazzino.v_UdcDetailDataTable tabUdc = MagClass.magazzino.taDettUDC.getUdcDetailByIdxCella(Convert.ToInt32(lblIdxCella.Text));
          if (tabUdc.Rows.Count > 0)
          {
            answ = Convert.ToInt32(float.Parse(tabUdc.Compute("Sum(Qta)", "").ToString()));
          }
        }
        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);
        lblNumRec.Text = string.Format("{0} / 6", totRecord);
      }
      else
      {
        lblNumRec.Text = "";
      }
    }
    /// <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>
    /// creo il nuovo UDC da particolare corrente!
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void lbtAddUdc_Click(object sender, EventArgs e)
    {
      // controlli preliminari
      if (Postazione.currCodCella != "")
      {
        if (currParticolare != "")
        {
          if (qta > 0)
          {
            checkCreaUDC();
          }
          else
          {
            Postazione.warningText = traduci("ErroreNoQta");
            Postazione.CssClass = "stileComandoKo";
          }
        }
        else
        {
          Postazione.warningText = traduci("ErroreNoPart");
          Postazione.CssClass = "stileComandoKo";
        }
      }
      else
      {
        Postazione.warningText = traduci("ErroreNoSelLinea");
        Postazione.CssClass = "stileComandoKo";
      }
      doUpdate();
    }

    /// <summary>
    /// verifica tutti i DTX associati e se almeno 2 verifica ci siano UDC x tutti i particolari definiti nell'intervallo...
    /// </summary>
    /// <exception cref="System.NotImplementedException"></exception>
    private void checkIntervalloDtx()
    {
      // recupero elenco intervallo e se ho almeno 2 particolari faccio check...
      DS_DataMatrix.stp_conteggioDtxDataTable tabConteggi = DataMatrix_mgr.taConteggio.getByCodCella(Postazione.currCodCella);
      if (tabConteggi.Rows.Count > 1)
      {
        // salvo particoalre x riassegnarlo alla fine...
        string partSel = currParticolare;
        // per ogni cella
        foreach (DS_DataMatrix.stp_conteggioDtxRow riga in tabConteggi)
        {
          // imposto particolare corrente
          currParticolare = riga.Particolare;
          // faccio check...
          checkCreaUDC();
        }
        currParticolare = partSel;
      }
    }
    /// <summary>
    /// crea eventualmente UDC per particolare
    /// </summary>
    /// <param name="qty"></param>
    /// <param name="particolare"></param>
    private void checkCreaUDC()
    {
      string newUdcChild = "";
      string noteTrim = "";
      DateTime adesso = DateTime.Now;
      // verifico se ho già quel particolare tra quelli inseriti in linea...
      try
      {
        newUdcChild = DataProxy.obj.taCartellini.getByParticolareIdxPosIdxCella(currParticolare, memLayer.ML.cdvi("IdxPosizioneRxTemp"), Postazione.currIdxCella)[0].UDC;
      }
      catch
      {
        newUdcChild = "";
      }
      if (string.IsNullOrEmpty(newUdcChild))
      {
        // controllo NON ci siano troppi UDC in posizione... da capienza ed assegnati
        DS_magazzino.V_statoCelleCapienzaAssegnatiRow riga;
        bool piena = false;
        try
        {
          riga = MagClass.magazzino.taStatoCelle.getByIdxCella(Postazione.currIdxCella)[0];
          if (riga.UdcAssegnati >= riga.Capienza) piena = true;
        }
        catch
        {
        }
        if (!piena)
        {
          try
          {
            // forzo qta a 0 x generare nuovo UDC
            qta = 0;
            // creo nuovo UDC RX
            newUdcChild = MagClass.magazzino.creaUdc(flusso, "", currParticolare, "", "", "", "", "", 0, memLayer.ML.cdv("CodImballoRX"), "U", MagClass.magazzino.CodSoggCurrUser, qta, 0, 0, adesso, 0, statoUDC, memLayer.ML.cdvi("IdxPosizioneRxTemp"), "IdxPosizioneRxTemp", codEventoUdc, noteTrim, "", adesso.Year, Request.UserHostName);

          }
          catch (Exception exc)
          {
            logger.lg.scriviLog(string.Format("Errore in creazione UDC temp RX: {0}{1}", Environment.NewLine, exc));
          }
        }
        else
        {
          Postazione.warningText = traduci("ErroreAL-Full");
          doUpdate();
        }
      }
      if (newUdcChild != "")
      {
        // lo posiziono nella cella corrente...
        MagClass.magazzino.spostaUDC(memLayer.ML.StringSessionObj("CodCS"), newUdcChild, Postazione.currIdxCella, memLayer.ML.confReadBool("spostaUdcResettaLdp"), Request.UserHostName);
        Postazione.CssClass = "stileAttesa";
        Postazione.warningText = "";
        Postazione.messaggiText = traduci("partAdded");

        // 2014.07.10 aggiungo attributo della data di fusione...
        MagClass.magazzino.taAtt2UDC.upsertVal(newUdcChild, "DF", string.Format("{0:yyyy/MM/dd HH:mm}", dataFus), adesso, MagClass.magazzino.CodSoggCurrUser);

        // 2015.06.03 aggiunto attributo linea fusione!
        MagClass.magazzino.taAtt2UDC.upsertVal(newUdcChild, "LF", string.Format("{1} - {0:yy/MM/dd HH:mm}", dataFus, lineaFus), adesso, MagClass.magazzino.CodSoggCurrUser);

        currParticolare = "";
        doUpdate();
      }
    }
    /// <summary>
    /// evento selezione: ricarico dati!
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void grView_SelectedIndexChanged(object sender, EventArgs e)
    {
      // ricarico dati dell'UDC come particolare e quantità...
      string UDC = grView.SelectedDataKey["UDC"].ToString();
      if (MagClass.magazzino.checkUDC(UDC))
      {
        currParticolare = DataProxy.obj.taCartellini.stp_getByUdc(UDC)[0].Particolare;
#if false
                qta = Convert.ToInt32(DataProxy.obj.taCartellini.stp_getByUdc(UDC)[0].Qta); 
#endif
      }
      Postazione.messaggiText = traduci("partSelected");
      Postazione.warningText = "";
      Postazione.CssClass = "stileComandoOk";
      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>
    /// verifica visibilità btn stampa UDC
    /// </summary>
    private void verificaBtnStampa()
    {
      bool showBtnStampa = false;
      // se ho ALMENO 1 UDC
      DS_magazzino.V_statoCelleCapienzaAssegnatiRow riga;
      bool hasUdc = false;
      try
      {
        riga = MagClass.magazzino.taStatoCelle.getByIdxCella(Postazione.currIdxCella)[0];
        if (riga.UdcAssegnati > 0) hasUdc = true;
      }
      catch
      {
      }
      if (hasUdc)
      {
        // se ho num cesta...
        if (numCesta != "")
        {
          showBtnStampa = true;
        }
      }
      divNote.Visible = showBtnStampa;
    }
    /// <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 e stampa AL */
        string AL = "";
        string noteTrim = txtNote.Text.Trim();
        // creazione AL ed associazione UDC / spostamento...
        try
        {
          AL = MagClass.magazzino.creaAssociaAlRxNt(tipoAL.AL_RxNt, Postazione.currCodCella, MagClass.magazzino.CodSoggCurrUser, DateTime.Now.Year, numCesta, noteTrim);
        }
        catch
        { }
        // 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 = "";
        // resetto particolare...
        currParticolare = "";
        doUpdate();
      }
      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)
    {
      // aggiorno le qta!
      qta = pezziUdc;
    }

  }
}