public void EmitirFacturas(List<DTO_EMISION_FACTURA> ListaClientesFacturar, DateTime FechaDesde,
            DateTime FechaHasta)
        {
            Init();
            ListaDetalleFactura = new List<DTO_REPORTE_DETALLEFACTURA_PRESTACION>();
            try
            {
                using (LQCEEntities context = new LQCEEntities())
                {
                    RepositorioFACTURACION _RepositorioFACTURACION = new RepositorioFACTURACION(context);
                    RepositorioCLIENTE _RepositorioCLIENTE = new RepositorioCLIENTE(context);
                    RepositorioPRESTACION _RepositorioPRESTACION = new RepositorioPRESTACION(context);

                    FACTURACION _FACTURACION = new FACTURACION();
                    _FACTURACION.FECHA_FACTURACION = DateTime.Now;
                    _FACTURACION.ACTIVO = true;
                    context.AddToFACTURACION(_FACTURACION);

                    int correlativo = 1;
                    foreach (var item in ListaClientesFacturar)
                    {
                        CLIENTE _CLIENTE = _RepositorioCLIENTE.GetByIdWithReferences(item.ID_CLIENTE);
                        if (_CLIENTE == null)
                            throw new Exception("No se encuentra información del cliente");

                        var prestaciones = _RepositorioFACTURACION.GetPrestacionesPorFacturar(FechaDesde, FechaHasta, item.ID_CLIENTE).ToList();

                        FACTURA _FACTURA = new FACTURA();
                        _FACTURA.FACTURACION = _FACTURACION;
                        _FACTURA.CORRELATIVO = correlativo;
                        _FACTURA.CLIENTE = _CLIENTE;
                        _FACTURA.NUMERO_FACTURA = null;
                        _FACTURA.RUT_LABORATORIO = _CLIENTE.TIPO_FACTURA.RUT_FACTURA;
                        _FACTURA.ACTIVO = true;
                        _FACTURA.DESCUENTO = item.DESCUENTO;
                        _FACTURA.NOMBRE_CLIENTE = _CLIENTE.NOMBRE;
                        _FACTURA.RUT_CLIENTE = _CLIENTE.RUT;
                        _FACTURA.DIRECCION = _CLIENTE.DIRECCION;
                        if (_CLIENTE.COMUNA != null)
                        {
                            _FACTURA.NOMBRE_COMUNA = _CLIENTE.COMUNA.NOMBRE;
                        }
                        _FACTURA.FONO = _CLIENTE.FONO;
                        _FACTURA.GIRO = _CLIENTE.GIRO;
                        _FACTURA.DETALLE = "Exámenes realizados del " + FechaDesde.ToString("dd MMMM yyyy") + " al " + FechaHasta.ToString("dd MMMM yyyy");
                        _FACTURA.TIPO_FACTURA = _CLIENTE.TIPO_FACTURA;

                        context.AddToFACTURA(_FACTURA);

                        int suma_total = 0;
                        foreach (var prestacion in prestaciones)
                        {
                            PRESTACION _PRESTACION = _RepositorioPRESTACION.GetById(prestacion.ID);
                            if (_PRESTACION == null)
                                throw new Exception("No se encuentra información de la prestación");

                            int total = (int)(prestacion.TOTAL * (1 - (double)item.DESCUENTO / 100.0));
                            suma_total += total;

                            FACTURA_DETALLE _FACTURA_DETALLE = new FACTURA_DETALLE();
                            _FACTURA_DETALLE.FACTURA = _FACTURA;
                            _FACTURA_DETALLE.PRESTACION = _PRESTACION;
                            _FACTURA_DETALLE.MONTO_TOTAL = total;
                            _FACTURA_DETALLE.MONTO_COBRADO = 0;
                            _FACTURA_DETALLE.ACTIVO = true;
                            context.AddToFACTURA_DETALLE(_FACTURA_DETALLE);
                        }

                        if (_CLIENTE.TIPO_FACTURA.AFECTO_IVA)
                        {
                            if (_CLIENTE.TIPO_PRESTACION.ID == (int)Enum.ENUM_TIPO_PRESTACION.Humanas)
                            {
                                _FACTURA.NETO = suma_total;
                                _FACTURA.IVA = (int)(suma_total * 0.19);
                                _FACTURA.TOTAL = (int)(suma_total * 1.19);
                            }
                            else
                            {
                                _FACTURA.NETO = (int)(suma_total / 1.19);
                                _FACTURA.IVA = suma_total - (int)(suma_total / 1.19);
                                _FACTURA.TOTAL = suma_total;
                            }
                        }
                        else
                        {
                            _FACTURA.NETO = suma_total;
                            _FACTURA.IVA = 0;
                            _FACTURA.TOTAL = suma_total;
                        }
                        //context.ApplyPropertyChanges("FACTURA", _FACTURA);
                        correlativo++;
                    }
                    context.SaveChanges();

                    try
                    {
                        var LISTA_DTO_REPORTE_FACTURA = GetReporteFacturaByID_FACTURACION(_FACTURACION.ID);

                        ListaDetalleFactura = GetReporteDetalleFacturaByID_FACTURACION(_FACTURACION.ID);

                        string deviceInfo =
                                      "<DeviceInfo>" +
                                      "  <OutputFormat>PDF</OutputFormat>" +
                                      "  <PageWidth>21cm</PageWidth>" +
                                      "  <PageHeight>29.7cm</PageHeight>" +
                                      "  <MarginTop>1cm</MarginTop>" +
                                      "  <MarginLeft>0.5cm</MarginLeft>" +
                                      "  <MarginRight>0.5cm</MarginRight>" +
                                      "  <MarginBottom>1cm</MarginBottom>" +
                                      "</DeviceInfo>";
                        Warning[] warnings;
                        m_streams_matriz = new List<Stream>();
                        m_streams_DetalleFactura = new List<Stream>();

                        string deviceInfoDireccion =
                                     "<DeviceInfo>" +
                                     "  <OutputFormat>PDF</OutputFormat>" +
                                     "  <PageWidth>11in</PageWidth>" +
                                     "  <PageHeight>1.3in</PageHeight>" +
                                     "  <MarginTop>0.5in</MarginTop>" +
                                     "  <MarginLeft>1in</MarginLeft>" +
                                     "  <MarginRight>1in</MarginRight>" +
                                     "  <MarginBottom>0.5in</MarginBottom>" +
                                     "</DeviceInfo>";
                        Warning[] warningsDireccion;
                        m_streams_Direccion = new List<Stream>();

                        // Documento 1: Un archivo con todas las facturas sin fondo para imprimir en matriz de punto
                        var tf = from f in LISTA_DTO_REPORTE_FACTURA
                                 group f by f.NOMBRE_REPORTE_FACTURA into g
                                 select g;

                        foreach (var facturas in tf)
                        {
                            Hashtable propiedades = new Hashtable();
                            propiedades.Add("Fecha de Documento", _FACTURACION.FECHA_FACTURACION);
                            propiedades.Add("Tipo de Documento", "Factura " + facturas.FirstOrDefault().NOMBRE_TIPO_FACTURA);
                            propiedades.Add("Formato", "Consolidado");

                            Hashtable propiedadesDireccion = new Hashtable();
                            propiedadesDireccion.Add("Fecha de Documento", _FACTURACION.FECHA_FACTURACION);
                            propiedadesDireccion.Add("Tipo de Documento", "Direcciones " + facturas.FirstOrDefault().NOMBRE_TIPO_FACTURA);
                            propiedadesDireccion.Add("Formato", "Consolidado");

                            ReportViewer _ReportViewer = new ReportViewer();
                            _ReportViewer.ProcessingMode = ProcessingMode.Local;
                            _ReportViewer.LocalReport.ShowDetailedSubreportMessages = true;
                            _ReportViewer.LocalReport.DataSources.Clear();
                            _ReportViewer.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", facturas));
                            _ReportViewer.LocalReport.ReportEmbeddedResource = "LQCE.Transaccion.Reporte." + facturas.Key;
                            _ReportViewer.LocalReport.Render("PDF", deviceInfo, CreateStream, out warnings);
                            foreach (Stream stream in m_streams_matriz)
                                stream.Position = 0;

                            ReportViewer _ReportViewerDireccion = new ReportViewer();
                            _ReportViewerDireccion.ProcessingMode = ProcessingMode.Local;
                            _ReportViewerDireccion.LocalReport.DataSources.Clear();
                            _ReportViewerDireccion.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", facturas));
                            _ReportViewerDireccion.LocalReport.ReportEmbeddedResource = "LQCE.Transaccion.Reporte.DireccionFactura.rdlc";
                            _ReportViewerDireccion.LocalReport.Render("PDF", deviceInfoDireccion, CreateStreamDireccion, out warningsDireccion);
                            foreach (Stream stream in m_streams_Direccion)
                                stream.Position = 0;

                            using (SPWeb spWeb = new SPSite(Settings.Default.SP_WEB).OpenWeb())
                            {
                                SPList spList = spWeb.GetList(Settings.Default.SP_LIBRERIA_FACTURAS);

                                string strNombreFactura = DateTime.Now.ToString("yyyyMMddhhmmss") + "_" + facturas.Key + ".pdf";
                                spList.RootFolder.Files.Add(spList.RootFolder.Url + "/" + strNombreFactura, m_streams_matriz[0], propiedades, true);
                                spList.Update();

                                string strNombreDirecciones = DateTime.Now.ToString("yyyyMMddhhmmss") + "_" + facturas.Key + " - Direcciones.pdf";
                                spList.RootFolder.Files.Add(spList.RootFolder.Url + "/" + strNombreDirecciones, m_streams_Direccion[0], propiedadesDireccion, true);
                                spList.Update();
                            }
                        }

                        // Documento 2: Un archivo con todos los detalles de facturas
                        List<DTO_REPORTE_DETALLEFACTURA_FACTURA> LISTA_DTO_REPORTE_DETALLEFACTURA_FACTURA =
                            (from df in ListaDetalleFactura
                             group df by df.ID_FACTURA into g
                             select new DTO_REPORTE_DETALLEFACTURA_FACTURA
                             {
                                 ID_FACTURA = g.Key,
                                 ID_CLIENTE = g.FirstOrDefault().ID_CLIENTE,
                                 NOMBRE_CLIENTE = g.FirstOrDefault().NOMBRE_CLIENTE,
                                 RUT_CLIENTE = g.FirstOrDefault().RUT_CLIENTE,
                                 DETALLE = g.FirstOrDefault().DETALLE,
                                 SUMA_PENDIENTE = g.Where(p => p.ESTADO_PENDIENTE == "INPAGO" || p.ESTADO_PREVISION == "INPAGO").Sum(p => p.MONTO_TOTAL)
                             }).ToList();

                        Hashtable propiedadesDetalle = new Hashtable();
                        propiedadesDetalle.Add("Fecha de Documento", _FACTURACION.FECHA_FACTURACION);
                        propiedadesDetalle.Add("Tipo de Documento", "Detalle de Factura");
                        propiedadesDetalle.Add("Formato", "Consolidado");

                        ReportViewer _ReportViewerDetalle = new ReportViewer();
                        _ReportViewerDetalle.ProcessingMode = ProcessingMode.Local;
                        _ReportViewerDetalle.LocalReport.ShowDetailedSubreportMessages = true;
                        _ReportViewerDetalle.LocalReport.DataSources.Clear();
                        _ReportViewerDetalle.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", LISTA_DTO_REPORTE_DETALLEFACTURA_FACTURA));
                        _ReportViewerDetalle.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(ReporteDetalleFactura_SubreportProcessingEventHandler);
                        _ReportViewerDetalle.LocalReport.ReportEmbeddedResource = "LQCE.Transaccion.Reporte.DetalleFactura.rdlc";

                        _ReportViewerDetalle.LocalReport.Render("PDF", deviceInfo, CreateStreamDetalleFactura, out warnings);
                        foreach (Stream stream in m_streams_DetalleFactura)
                            stream.Position = 0;

                        using (SPWeb spWeb = new SPSite(Settings.Default.SP_WEB).OpenWeb())
                        {
                            SPList spList = spWeb.GetList(Settings.Default.SP_LIBRERIA_FACTURAS);
                            string strNombreFactura = DateTime.Now.ToString("yyyyMMddhhmmss") + "_DetalleFactura.pdf";
                            spList.RootFolder.Files.Add(spList.RootFolder.Url + "/" + strNombreFactura, m_streams_DetalleFactura[0], propiedadesDetalle, true);
                            spList.Update();
                        }
                    }
                    catch (Exception ex)
                    {
                        // En caso de error, al generar los PDF se eliminan los registros de las facturas
                        _FACTURACION.ACTIVO = false;
                        foreach (var _FACTURA in _FACTURACION.FACTURA)
                        {
                            _FACTURA.ACTIVO = false;
                            foreach (var _FACTURA_DETALLE in _FACTURA.FACTURA_DETALLE)
                            {
                                _FACTURA_DETALLE.ACTIVO = false;
                                context.ApplyPropertyChanges("FACTURA_DETALLE", _FACTURA_DETALLE);
                            }
                            context.ApplyPropertyChanges("FACTURA", _FACTURA);
                        }
                        context.ApplyPropertyChanges("FACTURACION", _FACTURACION);
                        context.SaveChanges();
                        throw ex;
                    }
                }
            }
            catch (Exception ex)
            {
                ISException.RegisterExcepcion(ex);
                Error = ex.Message;
                throw ex;
            }
        }