private string ObtenerHitos(int iPlant)
    {// Devuelve el código HTML del catalogo de hitos de la plantilla que se pasa por parámetro
        StringBuilder sb = new StringBuilder();
        string        sIdTarea, sDesc, sHito, sOrden, sResul;
        int           iId = 0;

        try
        {
            sb.Append("<table id='tblDatos2' class='texto' style='width:470px;' mantenimiento='1'>");
            sb.Append("<colgroup><col style='width:20px' /><col style='width:450px' /></colgroup>");
            sb.Append("<tbody>");
            if (iPlant > 0)
            {
                SqlDataReader dr = HITOE_PLANT.CatalogoHitos(iPlant);
                while (dr.Read())
                {
                    sIdTarea = iId.ToString();
                    iId++;
                    sDesc  = dr["t369_deshito"].ToString();
                    sHito  = dr["t369_idhito"].ToString();
                    sOrden = dr["t369_orden"].ToString();

                    sb.Append("<tr id='" + sIdTarea + "' style='height:20px;' est='N' ord='" + sOrden + "' codH='" + sHito + "'");
                    sb.Append(" onclick='mm(event)' onkeydown='accionLineaHito(event)'>");

                    //Columna 1
                    sb.Append("<td ondblclick='mostrarDetalleHito()' style='vertical-align:middle;'>");
                    sb.Append("<img src='../../../../Images/imgHitoOff.gif' border='0' title='Hito grabado' style='CURSOR: url(../../../../images/imgManoAzul2.cur),pointer;vertical-align:middle'></td>");
                    //Columna 2
                    sb.Append("<td><input type='text' class='txtL' style='width:440px;' MaxLength='50' value='" + sDesc + "' onfocus='this.select()' onkeydown='modificarNombreHito(event)' >");
                    sb.Append("</td></tr>");
                }
                dr.Close();
                dr.Dispose();
            }
            sb.Append("</tbody>");
            sb.Append("</table>");

            sResul = sb.ToString();
            this.strTablaHTMLHito = sResul;
            return("@#@" + sResul);
        }
        catch (Exception ex)
        {
            Master.sErrores = Errores.mostrarError("Error al obtener los hitos especiales", ex);
            return("error@#@Error al obtener los hitos especiales " + ex.Message);
        }
    }
        private void listaTareas(int nIdPlant)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("<table id='tblDatos' class='texto MA' style='WIDTH: 380px;'>");
            sb.Append("<colgroup><col style='width:50px' /><col style='width:330px' /></colgroup>");
            sb.Append("<tbody>");
            SqlDataReader dr = HITOE_PLANT.CatalogoTareasPlantilla(nIdPlant);

            while (dr.Read())
            {
                sb.Append("<tr id='" + dr["codTarea"].ToString() + "' onclick='mm(event)' ondblclick='aceptar()' onmouseover='TTip(event);'>");
                sb.Append("<td style='width:50px;'>" + dr["codTarea"].ToString() + "</td>");
                sb.Append("<td><nobr style='width:320px;' class='NBR'>" + dr["desTarea"].ToString() + "</nobr></td></tr>");
            }
            dr.Close();
            dr.Dispose();
            sb.Append("</tbody>");
            sb.Append("</table>");
            strTablaHtml = sb.ToString();
        }
Exemplo n.º 3
0
    private void ObtenerDatosHito()
    {
        try
        {
            HITOE_PLANT o = HITOE_PLANT.Select(null, nIdHito);

            txtIdHito.Text      = o.t369_idhito.ToString("#,###");
            txtDesHito.Text     = o.t369_deshito;
            txtDescripcion.Text = o.t369_deshitolong;
            hdnOrden.Text       = o.t369_orden.ToString();
            if (o.t369_alerta)
            {
                chkAlerta.Checked = true;
            }
            else
            {
                chkAlerta.Checked = false;
            }
        }
        catch (Exception ex)
        {
            sErrores += Errores.mostrarError("Error al obtener los datos del hito", ex);
        }
    }
Exemplo n.º 4
0
    protected string Grabar(string strDatosHito, string sTareas)
    {
        string sResul = "", sDesHito, sDesHitoLong, sAlerta, sTipoLinea, sCad, sCodTarea;

        string[] aDatosHito;
        int      iCodHito;
        short    iOrden;
        bool     bAlerta = false;

        try
        {
            oConn = Conexion.Abrir();
            tr    = Conexion.AbrirTransaccion(oConn);
        }
        catch (Exception ex)
        {
            sResul = "Error@#@" + Errores.mostrarError("Error al abrir la conexión", ex);
            return(sResul);
        }
        try
        {
            aDatosHito   = Regex.Split(strDatosHito, "##");
            iCodHito     = int.Parse(aDatosHito[0]);
            sDesHito     = Utilidades.unescape(aDatosHito[1]);
            sDesHitoLong = Utilidades.unescape(aDatosHito[2]);
            sAlerta      = aDatosHito[3];
            if (sAlerta == "1")
            {
                bAlerta = true;
            }
            iOrden = short.Parse(aDatosHito[4]);
            HITOE_PLANT.Update(tr, iCodHito, sDesHito, sDesHitoLong, bAlerta, iOrden);

            //Grabamos las tareas asociadas al hito
            if (sTareas != "")
            {
                string[] aTareas = Regex.Split(sTareas, @"##");

                for (int i = 0; i < aTareas.Length - 1; i++)
                {
                    sCad       = aTareas[i];
                    sTipoLinea = sCad.Substring(0, 1);
                    sCodTarea  = sCad.Substring(1);
                    if (sTipoLinea == "D")
                    {//Borrar hito-tarea
                        HITOE_PLANT_TAREA.Delete(tr, iCodHito, int.Parse(sCodTarea));
                    }
                    else
                    {
                        if (sTipoLinea == "I")
                        {//Insertar hito-tarea
                            HITOE_PLANT_TAREA.Insert(tr, iCodHito, int.Parse(sCodTarea));
                        }
                    }
                }
            }
            Conexion.CommitTransaccion(tr);
            sResul = "OK@#@" + iCodHito.ToString() + "@#@";
        }
        catch (Exception ex)
        {
            Conexion.CerrarTransaccion(tr);
            sResul = "Error@#@" + Errores.mostrarError("Error al grabar los datos del hito", ex);
        }
        finally
        {
            Conexion.Cerrar(oConn);
        }
        return(sResul);
    }
Exemplo n.º 5
0
    private string Procesar(string sForzar, string sAnno, string strDatos)
    {
        string    sResul = "";
        int       nSubnodo = 0, nPE = 0, nPSN = 0;//, nDesde = 0, nHasta = 0, nAux = 0
        Hashtable htSubnodos = new Hashtable();
        Hashtable htNodos    = new Hashtable();
        NODO      oNodoAux   = null;

        int[] nDatosNodo;
        int?  idFicepiValidador = null;

        try
        {
            #region abrir conexión y transacción
            try
            {
                oConn = Conexion.Abrir();
                tr    = Conexion.AbrirTransaccionSerializable(oConn);
            }
            catch (Exception ex)
            {
                if (oConn.State == ConnectionState.Open)
                {
                    Conexion.Cerrar(oConn);
                }
                sResul = "Error@#@" + Errores.mostrarError("Error al abrir la conexión", ex);
                return(sResul);
            }
            #endregion

            string[] aProyectos = Regex.Split(strDatos, "///");
            foreach (string oProyecto in aProyectos)
            {
                if (oProyecto == "")
                {
                    continue;
                }
                string[] aValores = Regex.Split(oProyecto, "##");
                /// aValores[0] = idNodo
                /// aValores[1] = idNaturaleza
                /// aValores[2] = FIV
                /// aValores[3] = FFV
                /// aValores[4] = idPlantilla
                /// aValores[5] = Denominación Naturaleza
                /// aValores[6] = Esreplicable
                ///
                /// aValores[7] = Hereda Nodo
                /// aValores[8] = Id Usuario responsable
                /// aValores[9] = Imputable GASVI
                /// aValores[10] = Id Ficepi Validador GASVI

                if (sForzar == "N" && PROYECTOSUBNODO.ExistePIG(tr, int.Parse(aValores[0]), int.Parse(aValores[1]), short.Parse(sAnno)))
                {
                    continue;
                }
                #region Datos de nodo y subnodo
                nDatosNodo = (int[])htSubnodos[int.Parse(aValores[0])];
                if (nDatosNodo == null)
                {
                    int nCountSubnodosManiobra2  = 0;
                    int idSubnodoManiobra2       = 0;
                    int nCountSubnodosNoManiobra = 0;
                    int idSubnodoNoManiobra      = 0;

                    DataSet dsSubNodos = SUBNODO.CatalogoActivos(tr, int.Parse(aValores[0]), true);
                    foreach (DataRow oSN in dsSubNodos.Tables[0].Rows)
                    {
                        if ((byte)oSN["t304_maniobra"] == 2)
                        {
                            nCountSubnodosManiobra2++;
                            idSubnodoManiobra2 = (int)oSN["t304_idsubnodo"];
                        }
                        else if ((byte)oSN["t304_maniobra"] == 0)
                        {
                            nCountSubnodosNoManiobra++;
                            idSubnodoNoManiobra = (int)oSN["t304_idsubnodo"];
                        }
                    }
                    dsSubNodos.Dispose();

                    //nSubnodo = SUBNODO.ObtenerSubnodoManiobra2(tr, int.Parse(aValores[0]));
                    NODO oNodo = NODO.Select(tr, int.Parse(aValores[0]));

                    if (nCountSubnodosNoManiobra == 1)
                    {
                        nSubnodo = idSubnodoNoManiobra;
                    }
                    else if (nCountSubnodosManiobra2 >= 1)
                    {
                        nSubnodo = idSubnodoManiobra2;
                    }
                    else
                    {
                        nSubnodo = SUBNODO.Insert(tr, "Improductivos genéricos", int.Parse(aValores[0]), 0, true, 2, oNodo.t314_idusuario_responsable, null);
                    }
                    htSubnodos.Add(int.Parse(aValores[0]), new int[3] {
                        int.Parse(aValores[0]),
                        nSubnodo,
                        oNodo.t314_idusuario_responsable
                    });
                    nDatosNodo = (int[])htSubnodos[int.Parse(aValores[0])];
                }


                oNodoAux = (NODO)htNodos[int.Parse(aValores[0])];
                if (oNodoAux == null)
                {
                    oNodoAux = NODO.Select(tr, int.Parse(aValores[0]));
                    htNodos.Add(int.Parse(aValores[0]), oNodoAux);
                }
                #endregion
                string sDenominacion = sAnno + " " + Utilidades.unescape(aValores[5]) + " (" + oNodoAux.t303_denabreviada + ")";
                int    nIdClientePIG = CLIENTE.ObtenerClientePIG(tr, int.Parse(aValores[0]));

                nPE = PROYECTO.Insert(tr, "A", sDenominacion.Substring(0, (sDenominacion.Length > 70) ? 70 : sDenominacion.Length), "",
                                      nIdClientePIG, null, null, int.Parse(aValores[1]), 4, DateTime.Parse(aValores[2]),
                                      DateTime.Parse(aValores[3]), "S", "J", "J", short.Parse(sAnno), false, false,
                                      (aValores[6] == "1")? true:false, null, false, null, null, Constantes.gIdNLO_Defecto);

                //nPSN = PROYECTOSUBNODO.Insert(tr, nPE, nDatosNodo[1], false, "C", true, nDatosNodo[2],
                //                            sAnno + " " + Utilidades.unescape(aValores[5]),
                //                            "X", "X", false, true, false, false, false, "", "", "", null, null, null, null,
                //                            null, null, false, 0);
                //Mikel 30/12/2011. Pongo como seudónimo del subnodo la misma denominación que para el proyecto
                if (aValores[10] != "" && aValores[10] != "null")
                {
                    idFicepiValidador = int.Parse(aValores[10]);
                }
                else
                {
                    idFicepiValidador = null;
                }
                //Mikel 02/02/2016 Los PIG deben llevar el admite recurso PST a cero
                nPSN = PROYECTOSUBNODO.Insert(tr, nPE, nDatosNodo[1], false, "C", (aValores[7] == "1") ? true : false,
                                              int.Parse(aValores[8]),                        //nDatosNodo[2],//Id Usuario Responsable
                                              sDenominacion.Substring(0, (sDenominacion.Length > 70) ? 70 : sDenominacion.Length),
                                              "X", "X", (aValores[9] == "1") ? true : false, //Imputable GASVI
                                              false,                                         //Admite recurso PST
                                              false, false, false, "", "", "", null, null, null, null, null,
                                              idFicepiValidador,                             //Id Ficepi Validador GASVI
                                              false, 0);

                //A falta de tener en cuenta si la naturaleza tiene plantilla.
                TAREAPSP.UpdateVigenciaByPSN(tr, nPSN, DateTime.Parse(aValores[2]), DateTime.Parse(aValores[3]));

                #region Grabación de plantilla
                if (aValores[4] != "0")
                {
                    //Hay que grabar la plantilla de PE.
                    int       iPos, iMargen, iPT = -1, iFase = -1, iActiv = -1, iTarea = -1, iHito = -1, iAux = -1, iOrden = 0, idItemHitoPl;
                    double    fDuracion;
                    decimal   fPresupuesto;
                    string    sTipo, sDesc, sFiniPL, sFfinPL, sFiniV, sFfinV, sAux, sAvisos, sIdTareaPL, sCad;
                    bool      bFacturable, bObligaEst, bAvanceAutomatico, bEstadoTarea;
                    ArrayList alTareas = new ArrayList();

                    PROYECTOSUBNODO.BorrarPTByPSN(tr, nPSN);

                    #region 1º Se insertan las filas de la estructura
                    SqlDataReader dr = PlantTarea.Catalogo(int.Parse(aValores[4]));
                    while (dr.Read())
                    {
                        sTipo = dr["Tipo"].ToString();
                        if (sTipo == "H")
                        {
                            sTipo = "HT";
                        }
                        sDesc   = Utilidades.escape(dr["Nombre"].ToString());
                        iMargen = int.Parse(dr["margen"].ToString());

                        //Si la linea es de hito compruebo si el hito es de tarea o no para actualizar la variable iTarea
                        if (sTipo == "HT" || sTipo == "HM" || sTipo == "HF")
                        {
                            switch (iMargen)
                            {
                            case 80:    //es un hito de tarea por lo que mantengo el código de tarea
                                break;

                            case 60:    //es un hito de fase y actividad o de tarea con actividad sin fase
                                if (iFase != -1)
                                {
                                    iTarea = -1;
                                }
                                break;

                            case 40:    //es un hito de fase o de tarea sin actividad ni fase o de actividad sin fase
                                if (iFase != -1)
                                {
                                    iTarea = -1;
                                    iActiv = -1;
                                }
                                else
                                {
                                    if (iActiv != -1)
                                    {
                                        iTarea = -1;
                                    }
                                }
                                break;

                            case 20:   //es un hito proyecto técnico
                            case 0:    //es un hito de proyecto económico
                                iTarea = -1;
                                iActiv = -1;
                                iFase  = -1;
                                break;
                            }
                        }

                        fDuracion    = 0;
                        sFiniPL      = ""; //¿alguno es obligatorio?
                        sFfinPL      = "";
                        sFiniV       = Fechas.primerDiaMes(DateTime.Today).ToShortDateString();
                        sFfinV       = "";
                        fPresupuesto = 0;
                        sIdTareaPL   = dr["t339_iditems"].ToString();

                        bFacturable = (bool)dr["t339_facturable"];

                        //if (sEstado != "D")
                        iOrden++;
                        //iOrden = int.Parse(aElem[8]);
                        //Si no ha cambiado la linea pero el orden actual es distinto del original hay que updatear la linea para actualizar el orden
                        switch (sTipo)
                        {
                        case "P":
                            iPT    = -1;
                            iFase  = -1;
                            iActiv = -1;
                            break;

                        case "F":
                            iFase  = -1;
                            iActiv = -1;
                            break;

                        case "A":
                            iActiv = -1;
                            if (iMargen != 40)
                            {
                                iFase = -1;
                            }
                            break;

                        case "T":
                            iTarea = -1;
                            if (iMargen == 40)
                            {
                                iFase = -1;
                            }
                            else
                            {
                                if (iMargen != 60)
                                {
                                    iFase  = -1;
                                    iActiv = -1;
                                }
                            }
                            break;

                        case "HT":
                        case "HF":
                        case "HM":
                            iHito = -1;    //int.Parse(aElem[7]);
                            break;
                        }

                        bObligaEst        = (bool)dr["obliga"];
                        bAvanceAutomatico = (bool)dr["avance"];
                        sAux = EstrProy.Insertar(tr, int.Parse(aValores[0]), nPE, nPSN, sTipo, sDesc, iPT, iFase, iActiv, iMargen, iOrden,
                                                 sFiniPL, sFfinPL, fDuracion, sFiniV, sFfinV, fPresupuesto,
                                                 bFacturable, bObligaEst, bAvanceAutomatico, "1", "", 0);

                        iPos    = sAux.IndexOf("##");
                        iAux    = int.Parse(sAux.Substring(0, iPos));
                        sAvisos = sAux.Substring(iPos + 2);

                        switch (sTipo)
                        {
                        case "P": iPT = iAux; break;

                        case "F": iFase = iAux; break;

                        case "A": iActiv = iAux; break;

                        case "T":
                            iTarea = iAux;
                            if (sIdTareaPL != "" && sIdTareaPL != "-1")
                            {
                                string[] aDatosAux = new string[] { sIdTareaPL, iAux.ToString() };
                                alTareas.Add(aDatosAux);
                                //Grabo los atributos estadísticos provenientes de la plantilla. iAux=código de tarea
                                TAREAPSP.InsertarAE(tr, int.Parse(sIdTareaPL), iAux);
                            }

                            //Hay que guardar las tareas que quedan pendientes, ya que luego hay que actualizar el estado en pantalla
                            bEstadoTarea = TAREAPSP.bFaltanValoresAE(tr, short.Parse(aValores[0]), iAux);
                            if (bEstadoTarea)
                            {
                                //actualizo el estado de la tarea
                                TAREAPSP.Modificar(tr, iTarea, sDesc, iPT, iActiv, iOrden, sFiniPL, sFfinPL, fDuracion, sFiniV,
                                                   sFfinV, (int)Session["UsuarioActual"], fPresupuesto, 2, bFacturable);
                                //sAvisos = "Se han insertado tareas que quedan en estado Pendiente ya que el C.R. tiene atributos estadísticos\nobligatorios para los que la tarea no tiene valores asignados";
                                //if (sTareasPendientes == "") sTareasPendientes = iAux.ToString();
                                //else sTareasPendientes += "//"+ iAux.ToString();
                            }
                            break;

                        case "HT":
                            iHito = iAux;
                            break;
                        }
                        if (sTipo.Substring(0, 1) == "H")
                        {
                            AsociarTareasHitos(tr, nPSN, iPT, iFase, iActiv, iTarea, iHito, iMargen);
                        }
                    }
                    dr.Close();
                    dr.Dispose();
                    #endregion

                    #region 2º Se insertan las filas de los hitos de cumplimiento discontinuo
                    dr = PlantTarea.CatalogoHitos(int.Parse(aValores[4]));
                    while (dr.Read())
                    {
                        sTipo        = "HM";
                        sDesc        = dr["t369_deshito"].ToString();
                        idItemHitoPl = (int)dr["t369_idhito"];
                        iOrden       = int.Parse(dr["t369_orden"].ToString());

                        sAux    = EstrProy.Insertar(tr, int.Parse(aValores[0]), nPE, nPSN, sTipo, sDesc, 0, 0, 0, 0, iOrden, "", "", 0, "", "", 0, false, false, false, "1", "", 0);
                        iPos    = sAux.IndexOf("##");
                        iAux    = int.Parse(sAux.Substring(0, iPos));
                        sAvisos = sAux.Substring(iPos + 2);
                        //Si es hito de cumplimiento discontinuo y se ha cargado desde plantilla hay que grabar sus tareas
                        if (sTipo == "HM")
                        {
                            if (idItemHitoPl > 0)
                            {
                                //Recojo las tareas de plantilla del código de hito en plantilla
                                sCad = HITOE_PLANT.fgListaTareasPlantilla(tr, idItemHitoPl);
                                string[] aElems2 = Regex.Split(sCad, @"##");
                                for (int j = 0; j < aElems2.Length; j++)
                                {
                                    sIdTareaPL = aElems2[j];
                                    if (sIdTareaPL != "" && sIdTareaPL != "-1")
                                    {
                                        //Identifico el código de tarea real asociado al codigo de tarea de plantilla
                                        for (int n = 0; n < alTareas.Count; n++)
                                        {
                                            if (((string[])alTareas[n])[0] == sIdTareaPL)
                                            {//Inserto la tarea del hito
                                                sCad   = ((string[])alTareas[n])[1];
                                                iTarea = int.Parse(sCad);
                                                EstrProy.InsertarTareaHito(tr, iAux, iTarea);
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }//while
                    dr.Close();
                    dr.Dispose();
                    #endregion
                }
                #endregion
            }

            Conexion.CommitTransaccion(tr);

            sResul = "OK";
        }
        catch (Exception ex)
        {
            Conexion.CerrarTransaccion(tr);
            sResul = "Error@#@" + Errores.mostrarError("Error al crear los proyectos improductivos genéricos.", ex, false);
        }
        finally
        {
            Conexion.Cerrar(oConn);
        }
        return(sResul);
    }
    private string Grabar(string sIdPlant, string sCadena, string sHitosEspeciales)
    {/*En el parametro de entrada tenemos en primer lugar el codigo de la plantilla
      * y luego una lista de elementos del tipo sEstado@#@sTipo@#@sDes@#@sCodigo@#@sOrden@#@sMargen@#@sFacturable@#@avance@#@obligaest##
      */
        string         sCad, sTipo, sDesc, sResul = "", sEstado = "N", sCadenaBorrado = "", sTipoPlant, sAux;
        int            iPos, iTarea = -1, iAux = -1, iCodigo = -1, iHito = -1, iMargen = 0;
        short          iOrden = 0, iOrdenAnt = 0;
        bool           bFacturable, bAvance, bObliga;
        SqlConnection  oConn = null;
        SqlTransaction tr    = null;

        #region Control para comprobar que la estructura no ha variado desde que se ha leido.
        SqlConnection  oConn2 = null;
        SqlTransaction tr2    = null;
        try
        {
            oConn2 = Conexion.Abrir();
            tr2    = Conexion.AbrirTransaccion(oConn2);
        }
        catch (Exception ex)
        {
            sResul = "Error@#@" + Errores.mostrarError("Error al abrir la conexión", ex);
            return(sResul);
        }

        SqlDataReader dr2 = PlantTarea.Catalogo(int.Parse(sIdPlant));
        ArrayList     aEstrOrig = (ArrayList)Session["OrdenEstructuraPlant"];
        ArrayList     aEstrActual = new ArrayList();
        string        sTipo2, sIDItem2, sOrden2;

        while (dr2.Read())
        {
            sTipo2   = dr2["Tipo"].ToString();
            sIDItem2 = dr2["t339_iditems"].ToString();
            sOrden2  = dr2["orden"].ToString();

            string[] sEstr = new string[3] {
                sOrden2, sTipo2, sIDItem2
            };
            aEstrActual.Add(sEstr);
        }
        dr2.Close();
        dr2.Dispose();

        string sMsgError = "Error@#@PSP ha detectado que durante su edición, la estructura ha variado por modificación de otro usuario.\n\nPulse \"Aceptar\" para recuperar la estructura actualizada, teniendo en cuenta que perderá los cambios realizados.\nPulsando \"Cancelar\" permanecerá en la pantalla actual sin realizar la grabación.@#@1";
        if (aEstrOrig.Count != aEstrActual.Count)
        {
            Conexion.CerrarTransaccion(tr2);
            Conexion.Cerrar(oConn2);
            return(sMsgError);
        }
        else
        {
            for (int i = 0; i < aEstrOrig.Count; i++)
            {
                if (((string[])aEstrOrig[i])[0] != ((string[])aEstrActual[i])[0] ||
                    ((string[])aEstrOrig[i])[1] != ((string[])aEstrActual[i])[1] ||
                    ((string[])aEstrOrig[i])[2] != ((string[])aEstrActual[i])[2]
                    )
                {
                    Conexion.CerrarTransaccion(tr2);
                    Conexion.Cerrar(oConn2);
                    return(sMsgError);
                }
            }
        }

        Conexion.CommitTransaccion(tr2);
        Conexion.Cerrar(oConn2);
        Session["OrdenEstructuraPlant"] = null;
        #endregion
        try
        {
            sCadenaBorrado = sIdPlant + @"//";
            //Abro transaccion
            try
            {
                oConn = Conexion.Abrir();
                tr    = Conexion.AbrirTransaccion(oConn);
            }
            catch (Exception ex)
            {
                sResul = "Error@#@" + Errores.mostrarError("Error al abrir la conexión", ex);
                return(sResul);
            }

            if (lblTipo.Text == "Proyecto económico")
            {
                sTipoPlant = "E";
            }
            else
            {
                sTipoPlant = "T";
            }
            //Obtengo una cadena solo con la lista de filas a grabar
            //estado@#@tipo@#@descripcion@#@codPT@#@sCodigo@#@sOrden@#@sMargen@#@sFacturable  @#@avance@#@obligaest
            sCad = sCadena;
            if (sCad == "")
            {//Tenemos un desglose vacío. No hacemos nada
            }
            else
            {//Con la cadena generamos una lista y la recorremos para grabar cada elemento
                string[] aTareas = Regex.Split(sCad, @"##");

                for (int i = 0; i < aTareas.Length - 1; i++)
                {
                    sCad = aTareas[i];
                    string[] aItems = Regex.Split(sCad, @"@#@");

                    sEstado = aItems[0];
                    sTipo   = aItems[1];
                    sDesc   = Utilidades.unescape(aItems[2]);
                    sAux    = aItems[3];
                    if (sAux != "")
                    {
                        iCodigo = int.Parse(sAux);
                    }
                    else
                    {
                        iCodigo = -1;
                    }
                    sAux = aItems[4];
                    if (sAux != "")
                    {
                        iOrdenAnt = short.Parse(sAux);
                    }
                    else
                    {
                        iOrdenAnt = 1;
                    }
                    sCad = aItems[5];
                    iPos = sCad.IndexOf(@"px");
                    sAux = sCad.Substring(0, iPos);
                    if (sAux != "")
                    {
                        iMargen = int.Parse(sAux);
                    }
                    else
                    {
                        iMargen = 0;
                    }
                    sCad = aItems[6];
                    if (sCad == "T")
                    {
                        bFacturable = true;
                    }
                    else
                    {
                        bFacturable = false;
                    }
                    sCad = aItems[7];
                    if (sCad == "T")
                    {
                        bAvance = true;
                    }
                    else
                    {
                        bAvance = false;
                    }
                    sCad = aItems[8];
                    if (sCad == "T")
                    {
                        bObliga = true;
                    }
                    else
                    {
                        bObliga = false;
                    }

                    //Si no ha cambiado la linea pero el orden actual es distinto del original hay que updatear la linea para actualizar el orden
                    if (iOrden != iOrdenAnt && sEstado == "N")
                    {
                        sEstado = "U";
                    }
                    if (sEstado != "D")
                    {
                        iOrden++;
                    }

                    if (sEstado == "D")
                    {
                        sCadenaBorrado += sTipo + "##" + iCodigo + @"@#@";
                    }
                    switch (sTipo)
                    {
                    case "T":
                        iTarea = iCodigo;
                        break;

                    case "H":
                        iHito = iCodigo;
                        break;
                    }
                    //Si es una plantilla de proyecto técnico no hay que grabar linea de PT
                    if ((sTipoPlant == "T") && (sTipo == "P"))
                    {
                        sEstado = "N";
                    }
                    switch (sEstado)
                    {
                    case "U":
                        ITEMSPLANTILLA.Update(tr, iCodigo, sTipo, Utilidades.unescape(sDesc), (byte)iMargen, (short)iOrden,
                                              int.Parse(sIdPlant), bFacturable, bAvance, bObliga);
                        break;

                    case "I":
                        iAux = ITEMSPLANTILLA.Insert(tr, sTipo, Utilidades.unescape(sDesc), (byte)iMargen, (short)iOrden,
                                                     int.Parse(sIdPlant), bFacturable, bAvance, bObliga);
                        break;
                    } //switch (sEstado)
                }     //for
            }
            //Elimino las filas borradas
            BorrarDesglose(tr, sCadenaBorrado, sTipoPlant);

            //Grabo los hitos especiales
            //sEstado+"##"+Utilidades.escape(sDes)+"##"+sCodigo+"##"+sOrden+"//"
            sCad = sHitosEspeciales;
            if (sCad == "")
            {//Tenemos un desglose vacío. No hacemos nada
            }
            else
            {//Con la cadena generamos una lista y la recorremos para grabar cada elemento
                string[] aTareas = Regex.Split(sCad, @"@#@");
                iOrden = 0;
                for (int i = 0; i < aTareas.Length - 1; i++)
                {
                    sCad = aTareas[i];
                    if (sCad != "")
                    {
                        string[] aElems = Regex.Split(sCad, @"##");
                        sEstado   = aElems[0];
                        sDesc     = Utilidades.unescape(aElems[1]);
                        iHito     = int.Parse(aElems[2]);
                        iOrdenAnt = short.Parse(aElems[3]);

                        if (sEstado != "D")
                        {
                            iOrden++;
                        }
                        //Si no ha cambiado la linea pero el orden actual es distinto del original hay que updatear la linea para actualizar el orden
                        if (iOrden != iOrdenAnt && sEstado == "N")
                        {
                            sEstado = "U";
                        }
                        switch (sEstado)
                        {
                        case "N":
                            break;

                        case "D":
                            HITOE_PLANT.Delete(tr, iHito);
                            break;

                        case "U":
                            HITOE_PLANT.Update(tr, iHito, sDesc, null, null, iOrden);
                            break;

                        case "I":
                            iAux = HITOE_PLANT.Insert(tr, sDesc, "", true, iOrden, int.Parse(sIdPlant));
                            break;
                        }//switch (sEstado)
                    }
                }
            }
            //Cierro transaccion
            Conexion.CommitTransaccion(tr);

            //Recargo el desglose
            ObtenerTareas(int.Parse(sIdPlant), sTipoPlant);
            ObtenerHitos(int.Parse(sIdPlant));
            //sResul = "OK@#@" + sIdPlant;
            sResul = "OK@#@" + strTablaHTMLTarea + "@#@" + strTablaHTMLHito;
        }
        catch (Exception ex)
        {
            Conexion.CerrarTransaccion(tr);
            sResul = "Error@#@" + Errores.mostrarError("Error al grabar el desglose de la plantilla", ex);
        }
        finally
        {
            Conexion.Cerrar(oConn);
        }
        return(sResul);
    }