diff --git a/C2P_Data/reportPrinter.cs b/C2P_Data/reportPrinter.cs new file mode 100644 index 0000000..66fc10c --- /dev/null +++ b/C2P_Data/reportPrinter.cs @@ -0,0 +1,407 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Data; +using System.Drawing.Imaging; +using System.Drawing.Printing; +using System.Windows.Forms; +using Microsoft.Reporting.WinForms; +using System.Configuration; +using SteamWare; +using C2P_Data; + + +using System.Net; +using System.Web; + +/// +/// Classe che si occupa di stampare report da reportViewer via printer remota +/// +public class reportPrinter +{ + #region area codice da non modificare + + private int m_currentPageIndex; + protected int logLevel = 0; + protected bool doPdfCopy = false; + /// + /// stream del report... + /// + private IList m_streams; + /// + /// ciclo da fornire al renderizzatore dei report, per salvare 1 immagine da ogni pagina del report + /// + /// + /// + /// + /// + /// + /// + private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) + { + // creo files con nomi univoci... + string filePathName = string.Format(@"~\temp\{0}_{1:HHmmss}_{1:ffff}.{2}", name, DateTime.Now, fileNameExtension); + Stream stream = new FileStream(SteamWare.SteamwareStrings.getFilePath(filePathName), FileMode.Create); + m_streams.Add(stream); + return stream; + } + /// + /// ciclo da fornire al renderizzatore dei report, per salvare 1 pdf da ogni pagina del report + /// + /// + /// + /// + /// + /// + /// + private Stream CreateStreamPdf(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) + { + // creo Directory se non c'è + SteamWare.fileMover fm = new fileMover(string.Format(@"{0}\{1:yyyy}\{1:MM}\{1:dd}\", memLayer.ML.confReadString("PdfFolder"), DateTime.Now), ""); + fm.checkDir(); + string pdfPathName = string.Format(@"{0}\{1:yyyy}\{1:MM}\{1:dd}\{2}_{1:HHmmss}_{1:ffff}.{3}", memLayer.ML.confReadString("PdfFolder"), DateTime.Now, name, fileNameExtension); + Stream stream = new FileStream(SteamWare.SteamwareStrings.getFilePath(pdfPathName), FileMode.Create); + m_streams.Add(stream); + return stream; + } + /// + /// Handler per PrintPageEvents + /// + /// + /// + private void PrintPage(object sender, PrintPageEventArgs ev) + { + Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]); + ev.Graphics.DrawImage(pageImage, ev.PageBounds); + m_currentPageIndex++; + ev.HasMorePages = (m_currentPageIndex < m_streams.Count); + } + /// + /// funzione di stampa... + /// + private void Print(string printerName) + { + //const string printerName = "Microsoft Office Document Image Writer"; + //const string printerName = "Brother HL-2170W series"; + if (m_streams == null || m_streams.Count == 0) + return; + PrintDocument printDoc = new PrintDocument(); + printDoc.PrinterSettings.PrinterName = printerName; + if (!printDoc.PrinterSettings.IsValid) + { + logger.lg.scriviLog(String.Format("Impostazioni non valide per la stampante \"{0}\".", printerName), tipoLog.ERROR); + return; + } + printDoc.PrintPage += new PrintPageEventHandler(PrintPage); + printDoc.Print(); + } + /// + /// Export del report come EMF (Enhanced Metafile) file. + /// + /// + private void Export(LocalReport report, string deviceInfo) + { + Warning[] warnings; + m_streams = new List(); + report.Render("Image", deviceInfo, CreateStream, out warnings); + foreach (Stream stream in m_streams) stream.Position = 0; + } + /// + /// Export del report come PDF file. + /// + /// + private void ExportPDF(LocalReport report, string deviceInfo) + { + Warning[] warnings; + m_streams = new List(); + report.Render("PDF", deviceInfo, CreateStreamPdf, out warnings); + foreach (Stream stream in m_streams) stream.Position = 0; + } + /// + /// dispone l'applicazione e rilascia le risorse + /// + public void Dispose() + { + if (m_streams != null) + { + foreach (Stream stream in m_streams) + stream.Close(); + m_streams = null; + } + } + + #endregion + + #region area codice da modificare + + /// + /// carica i dati richiesti dal report dalla StoredProcedure (filtrando quindi...) + /// + /// + /// cod UDC + /// tabella dati + private DataTable caricaDati(reportRichiesto tipoReport, int ticket) + { + DataTable tab = new DataTable(); + switch (tipoReport) + { + case reportRichiesto.ReportOffers: + tab = (DataTable)DtProxy.man.taQFQ.repOffersByTicket(ticket); + break; + //case reportRichiesto.ReportSimulation: + // tab = (DataTable)DtProxy.man.taQFQ.repOffersByTicket(ticket); + // break; + case reportRichiesto.Vocabolario: + tab = (DataTable)SteamWare.selDataVoc.mgr.getVocabolarioByLemma(SteamWare.user_std.UtSn.lingua, "C2P_prt1"); + break; + default: + break; + } + return tab; + } + /// + /// Crea un report locale da file rdlc, carica i dati, esporta report come EMF file e quindi lo invia alla stampante + /// + /// report ammessi: ElencoMacchine / RichiestaIntervento + /// nome completo stampante (rispetto al server) + /// cod UDC + /// parametri "device input" + public void printReport(reportRichiesto tipoReport, string printerName, int ticket, devInfoParam deviceInfoParam) + { + LocalReport report = new LocalReport(); + string deviceInfo = ""; + switch (tipoReport) + { + case reportRichiesto.ReportOffers: + report.ReportPath = System.Web.HttpContext.Current.Server.MapPath(@".\Reports\ReportOffers.rdlc"); + // 2) caricamento tab dati + DataTable tabVoc = new DataTable(); + DataTable tabQuote = new DataTable(); + tabVoc = (DataTable)SteamWare.selDataVoc.mgr.getVocabolarioByLemma(SteamWare.user_std.UtSn.lingua, "C2P_prt1"); + tabQuote = (DataTable)DtProxy.man.taQFQ.repOffersByTicket(ticket); + // 3) inserimento dataset nel report + report.DataSources.Add(new ReportDataSource("dsVocabolario", tabVoc)); + report.DataSources.Add(new ReportDataSource("dsQuoteFull_Q_Data", tabQuote)); + + //report.DataSources.Add(new ReportDataSource("dsQuoteFull_Q_Data", caricaDati(tipoReport, ticket))); + //report.DataSources.Add(new ReportDataSource("dsVocabolario", caricaDati(reportRichiesto.Vocabolario, ticket))); + break; + //case reportRichiesto.ReportSimulation: + // report.ReportPath = @".\Reports\ReportSimulation.rdlc"; + // report.DataSources.Add(new ReportDataSource(memLayer.ML.confReadString("RepDsSimulation"), caricaDati(tipoReport, ticket))); + // break; + } + deviceInfo = deviceInfoParam.xmlParam; + doEmfPrint(printerName, report, deviceInfo); + // controllo se devo fare copia PDF... stampiamo ANCHE su pdf su una folder locale + if (doPdfCopy) + { + deviceInfoParam.OutputFormat = "PDF"; + deviceInfo = deviceInfoParam.xmlParam; + doLocalPdfPrint(report, deviceInfo); + } + } + /// + /// esegue print vero e proprio + /// + /// + /// + /// + private void doEmfPrint(string printerName, LocalReport report, string deviceInfo) + { + // export in EMF + Export(report, deviceInfo); + m_currentPageIndex = 0; + // stampo + Print(printerName); + // do dispose? + Dispose(); + } + /// + /// effettua stampa in PDF dei vari report in una cartella Anno/Mese/Giorno + /// + /// + /// + private void doLocalPdfPrint(LocalReport report, string deviceInfo) + { + // export in PDF + ExportPDF(report, deviceInfo); + m_currentPageIndex = 0; + // do dispose? + Dispose(); + } + /// + /// effettua la stampa del cartellino indicato + /// + /// + /// + /// indirizzo di rete completo stampante del tipo \\nomePc\nomeStampante, oppure "" x default + /// + public bool stampaReport(reportRichiesto tipoReport, int ticket, string printerName) + { + bool answ = false; + int idxPrintJob = 0; + // gestione coda: SE abilitata... + if (memLayer.ML.confReadBool("enableQueue")) + { + // disabilitata COMUNQUE coda (per ora) +#if false + // incomincio con gestione della coda di stampa... inserisco in tab la richiesta di stampa... + DataProxy.obj.taPJQ.insertQuery(tipoReport.ToString(), UDC, printerName); + // faccio un ciclo while... finchè non sono "in testa" alla coda delle esecuzioni aspetto... + string nextUdc = "ND"; + try + { + nextUdc = DataProxy.obj.taPJQ.getNext()[0].UDC; + } + catch + { + nextUdc = "ND"; + } + // verifico eventuali processi zombie: quelli in stato 0 con LastTry superiore a data attuale meno zombieMsTime + DataProxy.obj.taPJQ.chiudiZoombie(DateTime.Now.AddMilliseconds(-memLayer.ML.confReadInt("zombieMsTime"))); + // ora inizio a fare le mie stampe... + Random rand = new Random(); + int msWait = 200; + while (nextUdc != UDC) + { + // indico che ho fatto un tentativo di stampa aggiornando dtLastTry + DataProxy.obj.taPJQ.updateLastTry(UDC); + // aspetto... + msWait = rand.Next(memLayer.ML.confReadInt("minWait"), memLayer.ML.confReadInt("maxWait")); + System.Threading.Thread.Sleep(msWait); + // leggo prox record da coda + nextUdc = DataProxy.obj.taPJQ.getNext()[0].UDC; + } + // salvo idx job... + idxPrintJob = DataProxy.obj.taPJQ.getNext()[0].IdxPrintJob; +#endif + } + string outForm = ""; + string pagWidth = ""; + string pagHeigth = ""; + string margin = ""; + string tipo = ""; + switch (tipoReport) + { + case reportRichiesto.ReportOffers: + tipo = "Offers"; + break; + //case reportRichiesto.ReportOffers: + // tipo = "Offers"; + // break; + default: + break; + } + // carico di dati con lettura da web.config parametrica + if (printerName == "") + { + printerName = memLayer.ML.confReadString(string.Format("printer{0}", tipo)); + } + outForm = "EMF"; + pagWidth = memLayer.ML.confReadString(string.Format("PageWidth{0}", tipo)); + pagHeigth = memLayer.ML.confReadString(string.Format("PageHeight{0}", tipo)); + margin = memLayer.ML.confReadString(string.Format("Margin{0}", tipo)); + // compongo parametri stampa + devInfoParam deviceInfo = new devInfoParam(outForm, pagHeigth, pagWidth, margin, margin, margin, margin); + answ = printAndLog(ticket, printerName, answ, tipoReport, deviceInfo); + // gestione coda: SE abilitata... + if (memLayer.ML.confReadBool("enableQueue")) + { + // disabilitata COMUNQUE coda (per ora) +#if false + if (answ) + { + // registro stampato in tabella queue... + DataProxy.obj.taPJQ.updateStato(idxPrintJob, 1); + } + else + { + // registro annullato in tab queue... + DataProxy.obj.taPJQ.updateStato(idxPrintJob, -1); + } +#endif + } + return answ; + } + /// + /// effettua la vera e propria fase di stampa + /// + /// + /// + /// + /// + /// + /// + private bool printAndLog(int ticket, string printerName, bool answ, reportRichiesto report, devInfoParam deviceInfo) + { + try + { + if (logLevel > 5) logger.lg.scriviLog(String.Format("Sto per inviare un report alla stampante {0}", printerName), tipoLog.INFO); + reportPrinter.obj.printReport(report, printerName, ticket, deviceInfo); + if (logLevel > 5) logger.lg.scriviLog(String.Format("inviato comando print alla stampante {0}", printerName), tipoLog.INFO); + answ = true; + } + catch (Exception e) + { + logger.lg.scriviLog(String.Format("Errore in fase di creazione e stampa report: stampante {0}, errore riscontrato {1}", printerName, e), tipoLog.EXCEPTION); + } + return answ; + } + /// + /// oggetto protected + /// + /// + protected reportPrinter() + { + logLevel = memLayer.ML.confReadInt("_logLevel"); + doPdfCopy = memLayer.ML.confReadBool("doPdfCopy"); + } + /// + /// singleton pubblico + /// + public static reportPrinter obj = new reportPrinter(); + /// + /// effettua pulizia della cartella temp x i files più vecchi di X ore (web.config) + /// + public void pulisciDir() + { + // num max ore di età x files "vecchi" da tenere in temp area... + int maxOre = memLayer.ML.confReadInt("maxAgeTempAreaHours"); + int eliminati = 0; + // ottengo elenco files *.emf + fileMover.obj.setDirectory(@"~\temp\"); + FileInfo[] _fis = fileMover.obj.elencoFiles_FI("*.emf"); + bool fatto = false; + foreach (FileInfo _file in _fis) + { + if (_file.CreationTime < DateTime.Now.AddHours(-maxOre)) // elimino files vecchi... + { + fatto = fileMover.obj.eliminaFile(_file); + if (fatto) + { + logger.lg.scriviLog(String.Format("Eliminato file {0}", _file.Name), tipoLog.INFO); + eliminati++; + } + } + } + // salvo il log degli update + if (eliminati > 0) + { + logger.lg.scriviLog(String.Format("Eliminati {0} files temporanei da area temp", eliminati), tipoLog.INFO); + } + } + + #endregion +} +/// +/// tipologia di report ammessi alla stampa... +/// +public enum reportRichiesto +{ + ReportOffers + //, ReportSimulation + , Vocabolario +}