public ResultCreazioneFile GetModello(int idAzienda, int anno, IList<DatiCertificazioneDTO> datiCertificazione, DateTime dataDichiarazione, bool intermediarioDichiarazioneCondominio, bool aggregatoPerFornitore, bool ordinatoPerFornitore, PersonaDTO firmatarioDichiarazione, PersonaDTO intermediarioDichiarazione, TipoOperazioneFiscale tipoOperazione, long? protocolloComunicazione, int? progressivoInvio)
        {
            byte[] bytes = null;
            var message = string.Empty;

            var annoModulo = string.Empty;
            if (anno > 2009)
                annoModulo = (anno + 1).ToString(CultureInfo.InvariantCulture);

            var azienda = _daoFactory.GetAziendaDao().GetById(idAzienda, false);

            var templateFrontespizio = getTemplate("frontespizio", annoModulo);
            var templatePercipiente = getTemplate("percipiente", annoModulo);
            var templateDatiLavoratoreAutonomo = getTemplate("lavoratoreAutonomo", annoModulo);
            
            if (templateFrontespizio != null && templatePercipiente != null && templateDatiLavoratoreAutonomo != null)
            {
                try
                {
                    var pageBytes = new List<byte[]>();
                    if (ordinatoPerFornitore)
                    {
                        var dataSource = datiCertificazione.GroupBy(item => item.IdFornitore).ToList();
                        foreach (var dataSourcePerFornitore in dataSource)
                        {
                            pageBytes.AddRange(getModuloPages(dataSourcePerFornitore.ToList(), firmatarioDichiarazione, intermediarioDichiarazione, aggregatoPerFornitore, intermediarioDichiarazioneCondominio, dataDichiarazione, tipoOperazione, anno, azienda, templateFrontespizio, templatePercipiente, templateDatiLavoratoreAutonomo));
                        }
                    }
                    else
                        pageBytes.AddRange(getModuloPages(datiCertificazione, firmatarioDichiarazione, intermediarioDichiarazione, aggregatoPerFornitore, intermediarioDichiarazioneCondominio, dataDichiarazione, tipoOperazione, anno, azienda, templateFrontespizio, templatePercipiente, templateDatiLavoratoreAutonomo));


                    // =============================================================================================
                    // Merge dei moduli
                    // =============================================================================================
                    var stream = new MemoryStream();
                    var doc = new PdfMerge();

                    foreach (var pageByte in pageBytes)
                    {
                        doc.AddDocument(pageByte);
                    }
                    doc.Merge(stream, true);

                    bytes = new byte[stream.Length];
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Read(bytes, 0, bytes.Length);
                    stream.Close();

                    return new ResultCreazioneFile(bytes, message);
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("Errore inaspettato durante la creazione del file per il modello CU - {0} - anno:{1} - azienda:{2}", ex, Library.Utility.GetMethodDescription(), anno, azienda);
                    message = "Si sono verificati problemi inaspettati durante la generazione del modello CU." + Environment.NewLine + "Controllare il log per ulteriori dettagli.";
                    return new ResultCreazioneFile(bytes, message);
                } 
            }

            return new ResultCreazioneFile(null, string.Format("Il modulo per l'anno {0} non è ancora disponibile", annoModulo));
        }
        public ResultCreazioneFile GetModello770(int idCondominio, int idAzienda, int anno, int? idFornitoreModello770, DateTime dataDichiarazione, int? numeroIscrizioneCaf, bool intermediarioDichiarazioneCondominio, PersonaDTO firmatarioDichiarazione, PersonaDTO intermediarioDichiarazione)
        {
            byte[] bytes = null;
            var message = string.Empty;
            var numeroRecordE = 0;

            var annoModulo = string.Empty;
            if (anno > 2009)
                annoModulo = (anno + 1).ToString();

            var modulo = GestioneFiscaleResources.ResourceManager.GetObject("Modello770" + annoModulo + "_frontespizio");
            if (modulo != null)
            {
                try
                {
                    var condominio = _daoFactory.GetCondominioDao().GetById(idCondominio, false);

                    // =============================================================================================
                    // Ritenute da inserire nel modello 770
                    // =============================================================================================
                    var ritenute = _ritenutaService.GetByCondominioAnno(idCondominio, idAzienda, anno).OrderBy(item => item.PagamentoRiferimento.Data.GetValueOrDefault());

                    // -----------------------------------------------------------------
                    // Raggruppamento per periodo riferimento, tributo, data versamento
                    // -----------------------------------------------------------------
                    var ritenutePerMese = (from item in ritenute
                                           group item by item.GetPeriodoRiferimento(false) + "¥" + item.PagamentoRiferimento.ScadenzaRiferimento.SpesaRiferimento.FornitoreRiferimento.CodiceTributo + "¥" + item.GetDataVersamento().GetValueOrDefault().ToShortDateString() into itemPerMese
                                           select itemPerMese).ToList();

                    // -----------------------------------------------------------------
                    // Raggruppamento per fornitore
                    // -----------------------------------------------------------------
                    var ritenutePerFornitore = (from item in ritenute
                                                group item by item.PagamentoRiferimento.ScadenzaRiferimento.SpesaRiferimento.FornitoreRiferimento.ID into itemPerFornitore
                                                select itemPerFornitore).ToList();

                    // ---------------------------------------------------------------------
                    //  Fornitori regime minimo
                    // ---------------------------------------------------------------------
                    var listaPagamentiEsentiMinimo = _daoFactory.GetPagamentoDao().GetPagamentiEsentiRegimeMinimo(idAzienda, anno, idCondominio, null);
                    var regimeMinimoPerFornitore = listaPagamentiEsentiMinimo.GroupBy(item => item.ScadenzaRiferimento.SpesaRiferimento.FornitoreRiferimento.ID);

                    // =============================================================================================
                    // Creazione dei moduli
                    // =============================================================================================

                    // Importi versati in eccesso
                    var importiVersatiInEccesso = ritenute.Where(item => item.Tipo == TipoVersamentoRitenutaEnum.Eccesso).Sum(item => item.Importo.GetValueOrDefault());

                    // -----------------------------------------------------------------------------
                    // Frontespizio
                    // -----------------------------------------------------------------------------
                    string codiceFiscaleFirmatario;
                    string nomeFirmatario;
                    string cognomeFirmatario;
                    var sessoFirmatario = string.Empty;
                    DateTime? dataNascitaFirmatario = null;
                    var comuneNascitaFirmatario = string.Empty;
                    var siglaProvinciaNascitaFirmatario = string.Empty;
                    if (firmatarioDichiarazione != null)
                    {
                        nomeFirmatario = firmatarioDichiarazione.Nome;
                        cognomeFirmatario = firmatarioDichiarazione.Cognome;
                        codiceFiscaleFirmatario = firmatarioDichiarazione.CodiceFiscale;
                        var cf = new CodiceFiscale();
                        var datiNascita = cf.CalcoloInversoCF(firmatarioDichiarazione.CodiceFiscale);
                        if (datiNascita != null)
                        {
                            sessoFirmatario = datiNascita.GetValueOrDefault().Sesso;
                            dataNascitaFirmatario = datiNascita.GetValueOrDefault().DataNascita;

                            var codiceComuneNascita = datiNascita.GetValueOrDefault().CodiceComune;
                            var comune = _daoFactory.GetComuneDao().GetByCodiceCatastale(codiceComuneNascita);
                            if (comune != null)
                            {
                                comuneNascitaFirmatario = comune.Descrizione;
                                siglaProvinciaNascitaFirmatario = comune.ProvinciaAppartenenza.Codice;
                            }
                        }
                    }
                    else
                    {
                        nomeFirmatario = condominio.Azienda.Amministratore.PersonaRiferimento.Nome;
                        cognomeFirmatario = condominio.Azienda.Amministratore.PersonaRiferimento.Cognome;
                        codiceFiscaleFirmatario = condominio.Azienda.Amministratore.PersonaRiferimento.CodiceFiscale;
                        sessoFirmatario = condominio.Azienda.Amministratore.PersonaRiferimento.Sesso.ToString();
                        dataNascitaFirmatario = condominio.Azienda.Amministratore.PersonaRiferimento.DataNascita;
                        comuneNascitaFirmatario = condominio.Azienda.Amministratore.PersonaRiferimento.ComuneNascita.Descrizione;
                        siglaProvinciaNascitaFirmatario = condominio.Azienda.Amministratore.PersonaRiferimento.ComuneNascita.ProvinciaAppartenenza.Codice;
                    }


                    string codiceFiscaleIntermediario;
                    if (intermediarioDichiarazione != null)
                        codiceFiscaleIntermediario = intermediarioDichiarazione.CodiceFiscale;
                    else if (intermediarioDichiarazioneCondominio)
                        codiceFiscaleIntermediario = condominio.CodiceFiscale;
                    else 
                        codiceFiscaleIntermediario = condominio.Azienda.CodiceFiscale;

                    var datiFrontespizio = new DatiFrontespizio770
                    {
                        CodiceFiscaleCondominio = condominio.CodiceFiscale,
                        CognomeStudio = condominio.Azienda.Descrizione,
                        CapCondominio = condominio.Indirizzo.Cap,
                        CodiceComuneCondominio = condominio.Indirizzo.Comune.CodiceCatastale,
                        DenominazioneCondominio = condominio.Descrizione,
                        IndirizzoCompletoCondominio = condominio.Indirizzo.GetIndirizzoCompleto(),
                        ProvinciaCondominio = condominio.Indirizzo.Comune.ProvinciaAppartenenza.Codice,
                        ComuneCondominio = condominio.Indirizzo.Comune.Descrizione,
                        CodiceAttivitaCondominio = "970000",
                        NaturaGiuridicaCondominio = "51",
                        SituazioneCondominio = "6",
                        StatoCondominio = "1",
                        ImpegnoPresentazione = "2",
                        CapStudio = condominio.Azienda.IndirizzoSede.Cap,
                        CivicoStudio = condominio.Azienda.IndirizzoSede.Civico,
                        ComuneStudio = condominio.Azienda.IndirizzoSede.Comune.Descrizione,
                        IndirizzoStudio = condominio.Azienda.IndirizzoSede.Indirizzo,
                        TipoIndirizzoStudio = "VIA",
                        LocalitaStudio = condominio.Azienda.IndirizzoSede.Localita,
                        NomeStudio = string.Empty,
                        CodiceFiscaleStudio = condominio.Azienda.CodiceFiscale,
                        CodiceComuneStudio = condominio.Indirizzo.Comune.CodiceCatastale,

                        CodiceFiscaleAmministratore = codiceFiscaleFirmatario,
                        CognomeAmministratore = cognomeFirmatario,
                        NomeAmministratore = nomeFirmatario,
                        ComuneNascitaAmministratore = comuneNascitaFirmatario,
                        DataNascitaAmministratore = dataNascitaFirmatario.GetValueOrDefault().ToShortDateString(),
                        MaschioAmministratore = sessoFirmatario.ToUpper().StartsWith("M") ? "1" : string.Empty,
                        FemminaAmministratore = sessoFirmatario.ToUpper().StartsWith("F") ? "1" : string.Empty,
                        ProvinciaNascitaAmministratore = siglaProvinciaNascitaFirmatario,

                        CodiceFiscaleIntermediario = codiceFiscaleIntermediario,
                        ImpegnoPresentareDichiarazioneIntermediario = intermediarioDichiarazione != null || intermediarioDichiarazioneCondominio ? "1" : "2",
                        NumeroIscrizioneCaf = numeroIscrizioneCaf == null ? string.Empty : numeroIscrizioneCaf.GetValueOrDefault().ToString(),

                        CodiceCaricaAmministratore = "13",
                        ProvinciaStudio = condominio.Azienda.IndirizzoSede.Comune.ProvinciaAppartenenza.Codice,
                        DataPresentazione = dataDichiarazione.ToShortDateString(),
                        NumeroComunicazioniFornitori = idFornitoreModello770 == null ? (ritenutePerFornitore.Count() + regimeMinimoPerFornitore.Count()).ToString() : string.Empty,
                        PresenzaModelloSS = idFornitoreModello770 == null && ritenute.Any() ? "1" : string.Empty,
                        PresenzaModelloST = idFornitoreModello770 == null && ritenute.Any() ? "1" : string.Empty,
                        PresenzaModelloSV = string.Empty,
                        PresenzaModelloSX = idFornitoreModello770 == null && importiVersatiInEccesso > 0 ? "1" : string.Empty,
                        NonTrasmissioneModelloSTSVSX = !ritenute.Any() ? "2" : string.Empty,
                        PresenzaModello770Ordinario = string.Empty,

                        PresenzaModelloSSLavoratoreAutonomo = idFornitoreModello770 != null ? "1" : string.Empty,
                        PresenzaModelloSTLavoratoreAutonomo = idFornitoreModello770 != null ? "1" : string.Empty,
                        PresenzaModelloSXLavoratoreAutonomo = idFornitoreModello770 != null && importiVersatiInEccesso > 0 ? "1" : string.Empty,
                        PresenzaModelloSYLavoratoreAutonomo = string.Empty,
                        NumeroComunicazioniFornitoriLavoratoreAutonomo = idFornitoreModello770 != null ? (ritenutePerFornitore.Count() + regimeMinimoPerFornitore.Count()).ToString() : string.Empty,
                        CodiceFiscaleFornitore770 = string.Empty
                    };
                    
                    if(idFornitoreModello770 > 0)
                    {
                        var fornitoreModello770 = _daoFactory.GetFornitoreDao().Find(idFornitoreModello770.GetValueOrDefault(), false);
                        if (fornitoreModello770 != null)
                            datiFrontespizio.CodiceFiscaleFornitore770 = fornitoreModello770.GetCodiceFiscale();
                    }

                    var moduloFrontespizio = FillForm.FillStream(datiFrontespizio, (byte[])modulo, GestioneFiscaleResources.Modello770Frontespizio_FieldMapping, false, true);

                    // -----------------------------------------------------------------------------
                    // Dati Fornitori
                    // -----------------------------------------------------------------------------
                    var index = 0;
                    var moduloFornitori = new List<byte[]>(ritenutePerFornitore.Count() + regimeMinimoPerFornitore.Count());
                    foreach (var itemGroup in ritenutePerFornitore)
                    {
                        var fornitore = _daoFactory.GetFornitoreDao().GetById(itemGroup.Key, false);
                        index++;
                        var datiFornitore = getDatiFornitore(fornitore, condominio, index);

                        if (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Fisica && int.Parse(fornitore.PersonaRiferimento.ComuneNascita.Codice) > 999201)
                            datiFornitore.ProvinciaNascita = "EE";

                        // Importi
                        var speseSoggette = _spesaService.GetSoggetteRitenutaByFornitoreCondominioAnno(fornitore, condominio, anno);

                        var compensiSoggetti = speseSoggette.Sum(item => item.GetImponibileRitenutaPagata(anno));
                        var compensiNonSoggetti =  speseSoggette.Sum(item => item.AltreSpese.GetValueOrDefault());
                        var altreSpeseNonSoggette = speseSoggette.Sum(item => item.SpeseEsentiRitenuta.GetValueOrDefault());
                        var importoLordoCorrisposto = compensiSoggetti + compensiNonSoggetti + altreSpeseNonSoggette;
                        var altreSommeNonSoggette = compensiNonSoggetti + altreSpeseNonSoggette;

                        datiFornitore.CodiceAltreSommeNonSoggetteARitenuta = (altreSommeNonSoggette > 0) ? "3" : string.Empty;
                        datiFornitore.AltreSommeNonSoggetteARitenuta = (altreSommeNonSoggette > 0) ? altreSommeNonSoggette.ToString() : string.Empty;
                        datiFornitore.AmmontareLordoCorrisposto = Math.Round(importoLordoCorrisposto, 2).ToString();
                        datiFornitore.Imponibile = Math.Round(compensiSoggetti, 2).ToString();
                        datiFornitore.Ritenute = Math.Round(itemGroup.Sum(item => item.Importo.GetValueOrDefault()), 2).ToString();

                        moduloFornitori.Add(FillForm.FillStream(datiFornitore, (byte[])GestioneFiscaleResources.ResourceManager.GetObject("Modello770" + annoModulo + "_fornitore"), GestioneFiscaleResources.Modello770Fornitore_FieldMapping, false, true));
                    }

                    // Regime minimo
                    // -------------------------------
                    foreach (var itemGroup in regimeMinimoPerFornitore)
                    {
                        var fornitore = _daoFactory.GetFornitoreDao().GetById(itemGroup.Key, false);
                        index++;
                        var datiFornitore = getDatiFornitore(fornitore, condominio, index);

                        if (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Fisica && int.Parse(fornitore.PersonaRiferimento.ComuneNascita.Codice) > 999201)
                            datiFornitore.ProvinciaNascita = "EE";

                        // Importi
                        var speseSoggette = itemGroup.Select(item => item.ScadenzaRiferimento.SpesaRiferimento).ToList();

                        var compensiNonSoggetti = speseSoggette.Sum(item => item.GetImponibileRitenutaPagata(anno));
                        var altreSpeseNonSoggette = speseSoggette.Sum(item => item.SpeseEsentiRitenuta.GetValueOrDefault());
                        var importoLordoCorrisposto = compensiNonSoggetti + altreSpeseNonSoggette;
                        var altreSommeNonSoggette = compensiNonSoggetti + altreSpeseNonSoggette;

                        datiFornitore.CodiceAltreSommeNonSoggetteARitenuta = (altreSommeNonSoggette > 0) ? "3" : string.Empty;
                        datiFornitore.AltreSommeNonSoggetteARitenuta = (altreSommeNonSoggette > 0) ? altreSommeNonSoggette.ToString() : string.Empty;
                        datiFornitore.AmmontareLordoCorrisposto = Math.Round(importoLordoCorrisposto, 2).ToString();
                        datiFornitore.Imponibile = string.Empty;
                        datiFornitore.Ritenute = string.Empty;

                        moduloFornitori.Add(FillForm.FillStream(datiFornitore, (byte[])GestioneFiscaleResources.ResourceManager.GetObject("Modello770" + annoModulo + "_fornitore"), GestioneFiscaleResources.Modello770Fornitore_FieldMapping, false, true));
                    }

                    // ---------------------------------------------------------------------
                    //  Quadro ST
                    // ---------------------------------------------------------------------
                    var moduloST = new List<byte[]>();
                    var datiST = new List<DatiProspettoSTBody770>();
                    var countRow = 0;
                    foreach (var itemGroup in ritenutePerMese)
                    {
                        countRow++;
                        var keys = itemGroup.Key.Split('¥');
                        var importoInteressi = itemGroup.Sum(item => item.ImportoInteressi.GetValueOrDefault());
                        var importoSanzioni = itemGroup.Sum(item => item.ImportoSanzione.GetValueOrDefault());

                        // Nel calcolo dell'importo delle ritenute operate NON devono essere compresi gli importi versate due volte
                        // http://www.condominioweb.com/forum/f17/errore-versamenti-ritenute-con-ff24-12097/
                        var importo = itemGroup.Where(item => item.Tipo == TipoVersamentoRitenutaEnum.Normale).Sum(item => item.Importo.GetValueOrDefault());
                        var importoRitenute = Math.Round(importo, 2);

                        // Nel calcolo dell'importo delle ritenute versate DEVONO essere compresi gli importi versati in eccesso
                        importo = itemGroup.Sum(item => item.ImportoConInteressi);
                        var importoVersato = Math.Round(importo, 2);

                        var datiProspettoST = new DatiProspettoSTBody770
                        {
                            AnnoRiferimento = keys[0].Substring(2, 4),
                            MeseRiferimento = keys[0].Substring(0, 2),
                            CodiceTributo = keys[1],
                            RitenuteOperate = importoRitenute > 0 ? importoRitenute.ToString() : string.Empty,
                            Interessi = (importoInteressi > 0) ? Math.Round(importoInteressi, 2).ToString() : string.Empty,
                            Ravvedimento = (importoInteressi > 0 || importoSanzioni > 0) ? "1" : string.Empty,
                            ImportoVersato = importoVersato.ToString(),
                            DataVersamento = keys[2]
                        };
                        datiST.Add(datiProspettoST);

                        if (countRow == 12)
                        {
                            numeroRecordE++;
                            var datiSTHeader = new DatiProspettoSTHeader770
                            {
                                CodiceFiscaleCondominio = condominio.CodiceFiscale,
                                NumeroModello = numeroRecordE.ToString().PadLeft(2, '0'),
                            };
                            var precompilato = FillForm.FillStream(datiSTHeader, (byte[])GestioneFiscaleResources.ResourceManager.GetObject("Modello770" + annoModulo + "_ST"), GestioneFiscaleResources.Modello770STHeader_FieldMapping, true, true);
                            moduloST.Add(FillForm.FillStream(datiST.ToArray(), precompilato, GestioneFiscaleResources.Modello770STBody_FieldMapping, false, true));
                            countRow = 0;
                            datiST.Clear();
                        }
                    }
                    if (datiST.Count > 0)
                    {
                        numeroRecordE++;
                        var datiSTHeader = new DatiProspettoSTHeader770
                        {
                            CodiceFiscaleCondominio = condominio.CodiceFiscale,
                            NumeroModello = numeroRecordE.ToString().PadLeft(2, '0'),
                        };
                        var precompilato = FillForm.FillStream(datiSTHeader, (byte[])GestioneFiscaleResources.ResourceManager.GetObject("Modello770" + annoModulo + "_ST"), GestioneFiscaleResources.Modello770STHeader_FieldMapping, true, true);
                        moduloST.Add(FillForm.FillStream(datiST.ToArray(), precompilato, GestioneFiscaleResources.Modello770STBody_FieldMapping, false, true));
                    }

                    // ---------------------------------------------------------------------
                    //  Quadro SX - Riepilogo dei crediti e delle compensazioni
                    // ---------------------------------------------------------------------
                    byte[] moduloSX = null;
                    if (importiVersatiInEccesso > 0)
                    {
                        var datiSX = new DatiProspettoSX770
                        {
                            CodiceFiscaleCondominio = condominio.CodiceFiscale,
                            NumeroModello = "0001",
                            CreditoCompensazione = Math.Round(importiVersatiInEccesso, 2).ToString(),
                            ImportoRitenuteVersateEccesso = Math.Round(importiVersatiInEccesso, 2).ToString(),
                            RiepilogoCreditoCompensazione = Math.Round(importiVersatiInEccesso, 2).ToString()
                        };
                        moduloSX = FillForm.FillStream(datiSX, (byte[])GestioneFiscaleResources.ResourceManager.GetObject("Modello770" + annoModulo + "_SX"), GestioneFiscaleResources.Modello770SX_FieldMapping, false, true);
                    }

                    // ---------------------------------------------------------------------
                    //  Quadro SS - Dati riassuntivi
                    // ---------------------------------------------------------------------
                    byte[] moduloSS = null;
                    var importoRitenuteVersate = ritenute.Sum(item => item.Importo.GetValueOrDefault());
                    if (importoRitenuteVersate != 0)
                    {
                        var datiSS = new DatiProspettoSS770
                        {
                            CodiceFiscaleCondominio = condominio.CodiceFiscale,
                            NumeroModello = "01",
                            ImportoRitenute = Math.Round(importoRitenuteVersate, 2).ToString()
                        };
                        moduloSS = FillForm.FillStream(datiSS, (byte[])GestioneFiscaleResources.ResourceManager.GetObject("Modello770" + annoModulo + "_SS"), GestioneFiscaleResources.Modello770SS_FieldMapping, false, true);
                    }

                    // =============================================================================================
                    // Merge dei moduli
                    // =============================================================================================
                    var stream = new MemoryStream();
                    var doc = new PdfMerge();

                    // frontespizio
                    doc.AddDocument(moduloFrontespizio);

                    // fornitore
                    foreach (var item in moduloFornitori)
                        doc.AddDocument(item);

                    // quadro ST
                    foreach (var item in moduloST)
                        doc.AddDocument(item);

                    // quadro SX
                    if (moduloSX != null)
                        doc.AddDocument(moduloSX);

                    // quadro SS
                    if (moduloSS != null)
                        doc.AddDocument(moduloSS);

                    doc.Merge(stream, true);

                    bytes = new byte[stream.Length];
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Read(bytes, 0, bytes.Length);
                    stream.Close();

                    return new ResultCreazioneFile(bytes, message);
                }
                catch (Exception ex)
                {
                    
                    _log.Fatal("Errore inaspettato durante la creazione del file per il modello 770 -" + Library.Utility.GetMethodDescription() + " - condominio:" + idCondominio + " - anno:" + anno, ex);
                    message = "Si sono verificati problemi inaspettati durante la generazione del modello 770." + Environment.NewLine + "Controllare il log per ulteriori dettagli.";
                    return new ResultCreazioneFile(bytes, message);
                }
            }
            return new ResultCreazioneFile(null, "Il modulo per l'anno " + annoModulo + " non è ancora disponibile");
        }
示例#3
0
        public IList<RisultatoInvioMessaggio> InvioMessaggio(int idAzienda, PersonaMessaggioDTO personaMessaggioDTO, Condominio condominio, int? idUnitaImmobiliare, int? idFornitore, int? idResponsabile, int? idIncaricatoAttivita, MotivoMessaggio motivoMessaggio, string oggetto, string testo, IList<string> destinatari, string mittente, string emailRapportino, IList<DocumentInfo> allegati, ParametriInvioLettera parametriInvioLettera)
        {
            if (destinatari.Count > 0)
            {
                if(allegati.Count == 0)
                    return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio(null, null, false, "Non è presente nessun messaggio da inviare", new DocumentInfo()) };

                _parametriInvioLettera = parametriInvioLettera;
                var results = new List<RisultatoInvioMessaggio>();
                var allegatiLista = new List<DocumentInfo>(allegati.Count + 1);
                Persona persona = null;
                if (personaMessaggioDTO != null)
                    persona = _daoFactory.GetPersonaDao().Find(personaMessaggioDTO.ID, false);

                try
                {
                    // =====================================
                    // Elaborazione documenti allegati
                    // =====================================
                    var nomiFiles = new string[allegati.Count];
                    var contenutoAllegati = new byte[allegati.Count][];

                    // -------------------------------------
                    // Allegati
                    // -------------------------------------
                    var index = 0;
                    foreach (var documento in allegati)
                    {
                        var body = documento.Body;
                        var fileExtension = documento.FileExtension;
                        var fileName = documento.FileName;

                        // Se richiesto converto l'allegato in PDF
                        if (parametriInvioLettera.FormatoDocumento == FormatoDocumentoEnum.Pdf)
                        {
                            try
                            {
                                var doc = new Document(new MemoryStream(documento.Body));
                                var pdfStream = new MemoryStream();
                                doc.Save(pdfStream, SaveFormat.Pdf);
                                body = pdfStream.ToArray();
                                fileExtension = ".pdf";
                            }
                            catch (UnsupportedFileFormatException ex)
                            {
                                _log.WarnFormat("Formato file non supportato - {0} - fileId:{1} - fileName:{2} - extension:{3}", ex, Utility.GetMethodDescription(), documento.FileId, documento.FileName, documento.FileExtension);
                            }
                            catch (Exception ex)
                            {
                                _log.ErrorFormat("Formato file non supportato - {0} - fileId:{1} - fileName:{2} - extension:{3}", ex, Utility.GetMethodDescription(), documento.FileId, documento.FileName, documento.FileExtension);
                            }
                        }

                        nomiFiles[index] = fileName + fileExtension;
                        contenutoAllegati[index] = body;

                        // Se NON creo un file singolo i singoli documenti li allego al messaggio
                        if(parametriInvioLettera.Aggregazione == AggregazioneDocumentiEnum.DocumentiSeparati)
                            allegatiLista.Add(new DocumentInfo(body, documento.FileId, fileName, fileExtension));
                        index++;
                    }

                    var nomeFile = string.Empty;

                    // =====================================
                    // Creazione dello zip
                    // =====================================
                    byte[] messaggio = null;
                    if (parametriInvioLettera.Aggregazione == AggregazioneDocumentiEnum.DocumentiSeparati)
                    {
                        // ------------------------------------------
                        //  Singolo ZIP con tutti i documenti per persona
                        // ------------------------------------------
                        var stream = new MemoryStream();
                        using (var zipFile = new ZipFile())
                        {
                            for (var i = 0; i < index; i++)
                            {
                                var zipEntry = zipFile.AddEntry(nomiFiles[i], contenutoAllegati[i]);
                            }

                            zipFile.Save(stream);
                        }
                        stream.Position = 0;

                        // ------------------------------------------
                        //  Aggiungo allo zip unico
                        // ------------------------------------------
                        if (_fileSingolo == null)
                            _fileSingolo = new ZipFile();

                        nomeFile = persona != null ? $"{(_fileSingolo.Count + 1).ToString().PadLeft(3, '0')} - {persona.ID.ToString().PadLeft(8, '0')} - {persona.DisplayName}.zip"
                            : oggetto;
                        _fileSingolo.AddEntry(nomeFile, stream);
                        messaggio = stream.ToArray();
                    }
                    else
                    {
                        if (index > 0)
                        {
                            // Se è presente più di un allegato eseguo veramente un merge, altrimenti, per evitare problemi
                            // di orientamento e dimensione del pdf finale, se ho un solo allegato prendo questo come documento finale
                            if (index > 1)
                            {
                                if (parametriInvioLettera.FormatoDocumento == FormatoDocumentoEnum.Pdf)
                                {
                                    var pdfMerge = new PdfMerge { EnablePagination = parametriInvioLettera.RinumeraPagine };
                                    IList<byte[]> documenti = new List<byte[]>(contenutoAllegati.Length);
                                    for (var i = 0; i < index; i++)
                                    {
                                        if (nomiFiles[i].EndsWith(".pdf"))
                                            documenti.Add(contenutoAllegati[i]);
                                    }
                                    messaggio = pdfMerge.Merge(documenti, true);
                                }
                                else
                                {
                                    // The document that the other documents will be appended to.
                                    var doc = new Document();
                                    // We should call this method to clear this document of any existing content.
                                    doc.RemoveAllChildren();

                                    for (var i = 0; i < index; i++)
                                    {
                                        try
                                        {
                                            // Open the document to join.
                                            var srcDoc = new Document(new MemoryStream(contenutoAllegati[i]));

                                            // Append the source document at the end of the destination document.
                                            doc.AppendDocument(srcDoc, ImportFormatMode.UseDestinationStyles);

                                            // In automation you were required to insert a new section break at this point, however in Aspose.Words we
                                            // don't need to do anything here as the appended document is imported as separate sectons already.

                                            // If this is the second document or above being appended then unlink all headers footers in this section
                                            // from the headers and footers of the previous section.
                                            if (i > 1)
                                                doc.Sections[i].HeadersFooters.LinkToPrevious(false);
                                        }
                                        catch (UnsupportedFileFormatException ex)
                                        {
                                            _log.WarnFormat("Documento con formato non riconosciuto - {0} - index:{1}", ex, Utility.GetMethodDescription(), index);
                                        }
                                    }

                                    var saveFormat = SaveFormat.Doc;
                                    if(parametriInvioLettera.FormatoDocumento == FormatoDocumentoEnum.Docx)
                                        saveFormat = SaveFormat.Docx;
                                    using (var stream = new MemoryStream())
                                    {
                                        doc.Save(stream, saveFormat);
                                        messaggio = stream.ToArray();
                                    }
                                }
                            }
                            else
                                messaggio = contenutoAllegati[0];

                            // ----------------------------------------------------------------
                            //  Aggiungo allo zip unico se richiesto un file unico per persona
                            // ----------------------------------------------------------------
                            if (parametriInvioLettera.Aggregazione == AggregazioneDocumentiEnum.DocumentoUnicoPerPersona)
                            {
                                if (_fileSingolo == null)
                                    _fileSingolo = new ZipFile();
                                nomeFile = persona != null ?
                                    $"{(_fileSingolo.Count + 1).ToString().PadLeft(3, '0')} - {persona.ID.ToString().PadLeft(8, '0')} - {persona.DisplayName}.{parametriInvioLettera.FormatoDocumento.ToString().ToLower()}"
                                    : oggetto;
                                if (string.IsNullOrEmpty(nomeFile) && nomiFiles.Length > 0 && !string.IsNullOrEmpty(nomiFiles[0]))
                                    nomeFile = nomiFiles[0];
                                if (string.IsNullOrEmpty(nomeFile))
                                    nomeFile = $"Documento.{parametriInvioLettera.FormatoDocumento.ToString().ToLower()}";
                                _fileSingolo.AddEntry(nomeFile, messaggio);
                            }
                            else
                            {
                                if (parametriInvioLettera.FormatoDocumento == FormatoDocumentoEnum.Pdf)
                                {
                                    var pdfMerge = new PdfMerge
                                    {
                                        EnablePagination = parametriInvioLettera.RinumeraPagine
                                    };
                                    if (_documentoSingolo != null)
                                        pdfMerge.AddDocument(_documentoSingolo);
                                    pdfMerge.AddDocument(messaggio);
                                    using (var stream = new MemoryStream())
                                    {
                                        pdfMerge.Merge(stream, true);
                                        _documentoSingolo = stream.ToArray();
                                    }
                                }
                                else
                                {
                                    var doc = new Document();
                                    doc.RemoveAllChildren();

                                    if (_documentoSingolo != null)
                                    {
                                        var singleDoc = new Document(new MemoryStream(_documentoSingolo));
                                        doc.AppendDocument(singleDoc, ImportFormatMode.UseDestinationStyles);
                                    }

                                    var newDoc = new Document(new MemoryStream(messaggio));
                                    doc.AppendDocument(newDoc, ImportFormatMode.UseDestinationStyles);
                                    doc.Sections[0].HeadersFooters.LinkToPrevious(false);

                                    var saveFormat = SaveFormat.Doc;
                                    if (parametriInvioLettera.FormatoDocumento == FormatoDocumentoEnum.Docx)
                                        saveFormat = SaveFormat.Docx;
                                    using (var stream = new MemoryStream())
                                    {
                                        doc.Save(stream, saveFormat);
                                        _documentoSingolo = stream.ToArray();
                                    }
                                }
                            }
                        }
                    }

                    if (messaggio != null)
                    {
                        var fileExtension = $".{parametriInvioLettera.FormatoDocumento.ToString().ToLower()}";
                        var documentMessage = _documentService.SaveDocument(messaggio, nomeFile, fileExtension, null, idAzienda);
                        if (documentMessage.Documento != null)
                        {
                            var checkSumMessaggio = documentMessage.Documento.Checksum;
                            var destinatarioMessaggio = "Tutti";
                            if (persona != null)
                                destinatarioMessaggio = persona.DisplayName;
                            var messaggioInvio = $"Messaggio preparato per l'invio: {destinatarioMessaggio}";

                            var document = new DocumentInfo();
                            var nomeDocumento = persona != null ? $"Lettera {motivoMessaggio} {DateTime.Today:d MMMM yyyy} - {persona.DisplayName}"
                                : $"Lettera {motivoMessaggio} {DateTime.Today:d MMMM yyyy}";
                            if (parametriInvioLettera.ApriFileGenerato)
                            {
                                document = new DocumentInfo(messaggio, checkSumMessaggio, nomeDocumento, fileExtension) { BodyText = oggetto };
                                allegatiLista.Add(document);
                            }

                            var resultInvio = new RisultatoInvioMessaggio(checkSumMessaggio, checkSumMessaggio, true, messaggioInvio, document);
                            var storicoMessaggio = _messaggisticaService.StoricizzaMessaggio(persona, condominio, resultInvio, motivoMessaggio, oggetto, testo, destinatari, mittente, emailRapportino, allegatiLista, TipoMessaggio.Manuale);
                            if (storicoMessaggio != null)
                                resultInvio.IdMessaggio = storicoMessaggio.ID;
                            results.Add(resultInvio);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("Errore inaspettato durante la creazione del messaggio - {0} - oggetto:{1} - destinatario:{2}", ex, Utility.GetMethodDescription(), oggetto, destinatari[0]);
                    throw;
                }

                return results;
            }

            return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio(null, null, false, "Non è definito nessun destinatario", new DocumentInfo()) };
        }