private List<CertificadoDetDTO> GenerarLineas(TimeSpan horaInicio, TimeSpan horaFin, IntervaloDTO intervalo, FrecuenciaDTO frecuenciaCab, AvisosDTO aviso, List<FrecuenciaDetDTO> frecuenciaDetalles)
        {
            List<CertificadoDetDTO> lineas        = mycert;
            List<CertificadoDetDTO> preExistentes = new List<CertificadoDetDTO>();

            if (intervalo == null)
            {
                intervalo             = new IntervaloDTO();
                intervalo.CantMinutos = Convert.ToDecimal(0);
            }

            if (Validaciones(horaInicio, horaFin, intervalo, frecuenciaCab, aviso, frecuenciaDetalles) == false)
            {
                RefreshAbmGrid(gv);
                return lineas;
            }

            TimeSpan incremento = TimeSpan.FromMinutes(Convert.ToDouble(intervalo.CantMinutos));
            TimeSpan horaTemp;
            CertificadoDetDTO linea;
            List<DateTime> periodo;

            try
            {
                //Obtengo la lista de los días partiedo de fechas o nombres de dia.
                if (frecuenciaCab.SemMes == "SEMANA")
                    periodo = Certificados.GetDatesByDayNames(deAnoMes.Date.Year, deAnoMes.Date.Month, GetDiasSeleccionados());
                else
                    periodo = Certificados.GetDatesByDayNumbers(deAnoMes.Date.Year, deAnoMes.Date.Month, GetDiasSeleccionados());

                foreach (DateTime fecha in periodo)
                {
                    horaTemp = horaInicio;

                    if (aviso.Duracion == 0)
                    {
                        incremento = new TimeSpan(0);
                    }
                    else if (aviso.Duracion == null)
                    {
                        incremento = new TimeSpan(0);
                    }

                    if (horaTemp.CompareTo(horaFin) == 0)
                    {
                        horaFin = horaFin.Add(TimeSpan.FromHours(1));
                        incremento = incremento.Add(TimeSpan.FromHours(1));
                    }

                    if (incremento.Minutes == 0 && ((horaTemp.CompareTo(horaFin) == 0)))
                    {
                        horaFin = horaFin.Add(TimeSpan.FromHours(1));
                        incremento = incremento.Add(TimeSpan.FromHours(1));
                    }
                    else if (incremento.Minutes == 0 && ((horaTemp.CompareTo(horaFin) == 1)))
                    {
                        horaFin = horaFin.Add(TimeSpan.FromHours(-1));
                    }

                    //Mientras no supere la hora hasta...
                    while (horaTemp.CompareTo(horaFin) < 0)
                    {
                        DateTime fechaTmp = new DateTime(fecha.Year, fecha.Month, fecha.Day, horaTemp.Hours, horaTemp.Minutes, horaTemp.Seconds);

                        linea           = new CertificadoDetDTO();
                        linea.RecId     = lineas.Count;
                        linea.Fecha     = fechaTmp;
                        linea.Hora      = horaTemp;
                        linea.Dia       = fecha.Day;
                        linea.DiaSemana = fecha.ToString("dddd", new CultureInfo("es-ES")).ToUpper().Trim();

                        if (aviso != null)
                        {
                            linea.IdentifAviso = aviso.IdentifAviso;
                            linea.Duracion     = aviso.Duracion;
                        }
                        else
                        {
                            linea.IdentifAviso = string.Empty;
                            linea.Duracion     = null;
                        }

                        linea.Salida = spSalidasInsertar.Number;

                        if (!lineas.Exists(
                            (x) => (x.Fecha == fechaTmp && x.Hora == horaTemp && x.Salida == linea.Salida && x.IdentifAviso == linea.IdentifAviso)))
                        {
                            lineas.Add(linea);
                        }
                        else
                        {
                            preExistentes.Add(linea);
                        }

                        horaTemp = horaTemp.Add(incremento);

                        if (aviso.Duracion == null || aviso.Duracion == 0)
                        {
                            horaTemp = horaFin;
                        }
                    }
                }
            }

            catch (Exception ex)
            {
                MsgErrorLinas(ex);
            }

            if (preExistentes.Count > 0)
            {
                lblErrorLineas.Text = "No se pudieron grabar todas las lineas. No olvide GRABAR antes de continuar.";
            }

            RefreshAbmGrid(gv);

            return lineas;
        }
        protected bool Validaciones(TimeSpan horaInicio, TimeSpan horaFin, IntervaloDTO intervalo, FrecuenciaDTO frecuenciaCab, AvisosDTO aviso, List<FrecuenciaDetDTO> frecuenciaDetalles)
        {
            bool retval              = false;
            decimal CantMinutosAviso = 0;

            List<EstimadoDetDTO> lineas        = Lineas;
            List<EstimadoDetDTO> preExistentes = new List<EstimadoDetDTO>();

            //TODO: VALIDACION 1: Validar que la hora de inicio de la inserción, no sea superior a la hora fin de la pauta.
            if (Convert.ToDateTime(teHoraInicioInsertar.Text) > Convert.ToDateTime(teHoraFin.Text) || Convert.ToDateTime(teHoraInicioInsertar.Text) < Convert.ToDateTime(teHoraInicio.Text))
            {
                lblErrorLineas.Text = "Las horas ingresadas no están dentro del rango de la cabecera.";
                retval              = false;
                return retval;
            }

            //TODO: VALIDACION 2: La duración del aviso excede el intervalo seleccionado para la Pauta. NO se generaron líneas.
            if (intervalo == null)
            {
                intervalo             = new IntervaloDTO();
                intervalo.CantMinutos = Convert.ToDecimal(0);
            }

            if (Convert.ToInt32(spDuracionInsertar.Value) != 0)
            {
                CantMinutosAviso = Convert.ToDecimal(spDuracionInsertar.Value) / 60;

                if (CantMinutosAviso > intervalo.CantMinutos)
                {
                    if (spSalidasInsertar.Enabled == false)
                    {
                        lblErrorLineas.Text = "La duración del aviso excede el intervalo seleccionado para la Pauta. NO se generaron líneas.";
                        retval              = false;

                        return retval;
                    }
                }
            }

            //TODO: VALIDACION 3: Si no hay lineas preexistentes,debe devolver verdadero..
            if (lineas.Count == 0)
            {
                retval = true;
                return retval;
            }
            else
            {
                for (int i = 0; i <= lineas.Count - 1; i++)
                    preExistentes.Add(lineas[i]);

                return ValidacionDiasContraPreexistente(horaInicio, horaFin, preExistentes, frecuenciaDetalles, aviso);
            }
        }
        /// <summary>
        ///  PROPIO DE CERTIFICADO
        /// </summary>
        /// <param name="horaInicio"></param>
        /// <param name="horaFin"></param>
        /// <param name="intervalo"></param>
        /// <param name="frecuenciaCab"></param>
        /// <param name="aviso"></param>
        /// <param name="frecuenciaDetalles"></param>
        /// <returns></returns>
        protected bool Validaciones(TimeSpan horaInicio, TimeSpan horaFin, IntervaloDTO intervalo, FrecuenciaDTO frecuenciaCab, AvisosDTO aviso, List<FrecuenciaDetDTO> frecuenciaDetalles)
        {
            bool retval = false;

            decimal CantMinutosAviso = 0;

            List<CertificadoDetDTO> lineas = mycert;

            List<CertificadoDetDTO> preExistentes = new List<CertificadoDetDTO>();

            //TODO: VALIDACION 1: Validar que la hora de inicio de la inserción, no sea superior a la hora fin de la pauta.
            if (Convert.ToDateTime(teHoraInicioInsertar.Text) > Convert.ToDateTime(teHoraFin.Text) || Convert.ToDateTime(teHoraInicioInsertar.Text) < Convert.ToDateTime(teHoraInicio.Text))
            {
                lblErrorLineas.Text = "Las horas ingresadas no están dentro del rango de la cabecera.";

                retval = false;

                return retval;
            }

            //TODO: VALIDACION 2: La duración del aviso excede el intervalo seleccionado para la Pauta. NO se generaron líneas.
            if (intervalo == null)
            {
                intervalo = new IntervaloDTO();

                intervalo.CantMinutos = Convert.ToDecimal(0);
            }

            if (Convert.ToInt32(spDuracionInsertar.Value) != 0)
            {
                CantMinutosAviso = Convert.ToDecimal(spDuracionInsertar.Value) / 60;

                if (CantMinutosAviso > intervalo.CantMinutos)
                {
                    if (spSalidasInsertar.Enabled == false)
                    {
                        lblErrorLineas.Text = "La duración del aviso excede el intervalo seleccionado para la Pauta. NO se generaron líneas.";

                        retval = false;

                        return retval;
                    }
                }
            }

            //TODO: VALIDACION 3: Si no hay lineas preexistentes,debe devolver verdadero..
            if (lineas.Count == 0)
            {
                retval = true;

                return retval;
            }

            //TODO: VALIDACION 4: Para aviso con duracion cero segundos y salidas deshabilitada.... (GRAFICA, PNT, ETC)
            if (Convert.ToInt32(spDuracionInsertar.Value) == 0 && spSalidasInsertar.Enabled == false)
            {
                    lblErrorLineas.Text = "No ingrese avisos con duracion cero segundos si salida está deshabilitada.";

                    retval = false;
            }

            lineas = lineas.OrderBy(p => p.Dia).ThenBy(p => p.Hora).ToList(); //Ordena la lista por dia y luego por hora

            //TODO: VALIDACION 5: Comparo que la linea insertada no pise valores preexistentes
            for (int j = 0; j <= lineas.Count - 1; j++)
            {
                //Hora de inicio dentro del array de preexistentes
                TimeSpan ts1i = new TimeSpan(0, lineas[j].Hora.Hours, lineas[j].Hora.Minutes, 0);

                //Duracion del aviso dentro del array de preexistentes
                TimeSpan ts1d = new TimeSpan(0, 0, Convert.ToInt32(lineas[j].Duracion));

                //Hora de finalizacion del aviso dentro del array de preexistentes midiendo su duracion
                TimeSpan ts1f = ts1i.Add(ts1d);

                //Hora de inicio dentro de la linea a insertar
                TimeSpan ts2i = new TimeSpan(0, Convert.ToDateTime(teHoraInicioInsertar.Text).Hour, Convert.ToDateTime(teHoraInicioInsertar.Text).Minute, 0);

                //Duracion del aviso dentro de la linea a insertar
                TimeSpan ts2d = new TimeSpan(0, 0, Convert.ToInt32(aviso.Duracion));

                //Hora de finalizacion del aviso dentro de la linea a insertar midiendo su duracion
                TimeSpan ts2f = ts2i.Add(ts2d);

                //TODO: VALIDACION 6: Si es la misma hora de inicio del aviso preexistente, sale con error
                if (ts2i.CompareTo(ts1i) == 0)
                {
                    lblErrorLineas.Text = "El aviso se superpone con otro";

                    retval = false;

                    break;
                }

                //Verificacion contra el registro siguiente
                //Quiere decir que hay un registro previo despues del actual
                if (j < lineas.Count)
                {
                    TimeSpan tsli                   = new TimeSpan(0, lineas[j + 1].Hora.Hours, lineas[j + 1].Hora.Minutes, 0);
                    TimeSpan tsld                   = new TimeSpan(0, 0, Convert.ToInt32(lineas[j + 1].Duracion));
                    TimeSpan tslf                   = tsli.Add(tsld);
                    TimeSpan RangoInicio            = ts1i;
                    TimeSpan RangoFinal             = ts1f;
                    TimeSpan HoraInicioAvisoNuevo   = ts2i;
                    TimeSpan HoraFinAvisoNuevo      = ts2f;

                    if (HoraFinAvisoNuevo.CompareTo(tsli) == 1)
                    {
                        lblErrorLineas.Text = "El aviso se superpone con otro";

                        retval = false;

                        break;
                    }

                }

                if (ts1i.Days == ts2i.Days)
                {
                    TimeSpan RangoInicio          = ts1i;
                    TimeSpan RangoFinal           = ts1f;
                    TimeSpan HoraInicioAvisoNuevo = ts2i;
                    TimeSpan HoraFinAvisoNuevo    = ts2f;

                    if (HoraInicioAvisoNuevo.CompareTo(RangoInicio) == 1 && HoraInicioAvisoNuevo.CompareTo(RangoFinal) == 2)
                    {
                        lblErrorLineas.Text = "El aviso se superpone con otro";

                        retval = false;

                        break;
                    }

                    if (ts2i.CompareTo(ts1i) == 1)
                    {
                        //Comparo que la hora de inicio del aviso sea mayor que la hora de finalizacion del preexistente
                        if (ts1f <= ts2i && aviso.Duracion != 0)
                        {
                            retval = true;

                            break;
                        }
                        else
                        {
                            lblErrorLineas.Text = "El aviso se superpone con otro";

                            retval = false;
                        }
                    }
                }
                else
                {
                    retval = false;
                }
            }
            return retval;
        }
        private List<EstimadoDetDTO> GenerarLineas(TimeSpan horaInicio, TimeSpan horaFin, IntervaloDTO intervalo, FrecuenciaDTO frecuenciaCab, AvisosDTO aviso, List<FrecuenciaDetDTO> frecuenciaDetalles)
        {
            List<EstimadoDetDTO> lineas        = Lineas;
            List<EstimadoDetDTO> preExistentes = new List<EstimadoDetDTO>();

            if (Validaciones(horaInicio, horaFin, intervalo, frecuenciaCab, aviso, frecuenciaDetalles) == false)
            {
                RefreshAbmGrid(gv);
                return lineas;
            }

            TimeSpan incremento = TimeSpan.FromMinutes(Convert.ToDouble(intervalo.CantMinutos));
            TimeSpan horaTemp;
            EstimadoDetDTO linea;
            List<DateTime> periodo;

            int year = Convert.ToInt32(Estimado.Cabecera.AnoMes.ToString().Substring(0,4));
            int month = Convert.ToInt32(Estimado.Cabecera.AnoMes.ToString().Substring(4,2));

            try
            {
                //Obtengo la lista de los días partiedo de fechas o nombres de dia.
                if (frecuenciaCab.SemMes == "SEMANA")
                    periodo = Ordenados.GetDatesByDayNames(year, month, GetDiasSeleccionados());
                else
                    periodo = Ordenados.GetDatesByDayNumbers(year, month, GetDiasSeleccionados());

                foreach (DateTime fecha in periodo)
                {
                    horaTemp = horaInicio;

                    //Mientras no supere la hora hasta...
                    while (horaTemp.CompareTo(horaFin) < 0)
                    {
                        DateTime fechaTmp = new DateTime(fecha.Year, fecha.Month, fecha.Day, horaTemp.Hours, horaTemp.Minutes, horaTemp.Seconds);

                        linea               = new EstimadoDetDTO();

                        linea.RecId         = lineas.Count;
                        linea.Fecha         = fechaTmp;
                        linea.Hora          = horaTemp;
                        linea.Dia           = fecha.Day;
                        linea.DiaSemana     = fecha.ToString("dddd", new CultureInfo("es-ES")).ToUpper().Trim();
                        linea.IdentifAviso  = aviso != null ? aviso.IdentifAviso : string.Empty;
                        linea.Duracion      = aviso != null ? aviso.Duracion : null;
                        linea.Salida        = spSalidasInsertar.Value != null ? spSalidasInsertar.Number : 0;

                        lineas.Add(linea);

                        if (!lineas.Exists(
                            (x) => (x.Fecha == fechaTmp && x.Hora == horaTemp)))
                        {
                            lineas.Add(linea);
                        }
                        else
                        {
                            preExistentes.Add(linea);
                        }

                        horaTemp = horaTemp.Add(incremento);
                    }
                }
            }
            catch (Exception ex)
            {
                MsgErrorLinas(ex);
            }

            if (preExistentes.Count > 0)
                lblErrorLineas.Text = "No se pudieron grabar todas las lineas";

            return lineas;
        }