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");
        }
        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));
        }
Exemplo n.º 3
0
        public byte[] EsecuzionePagamenti(PagamentoRitenuta ritenuta, bool testataPerCondominio, bool mittenteCondominio, DateTime dataVersamento)
        {
            _testata = ritenuta;
            byte[] bytes = null;

            try
            {
                // =============================================================================================
                // Compilo il modulo PDF
                // =============================================================================================
                var modulo = RitenutaModuloPDFResources.ResourceManager.GetObject("F24_" + dataVersamento.Year);
                if (modulo != null)
                {
                    var listaPagamenti = ordinaDisposizioni(new List<Pagamento>(_testata.Pagamenti));

                    // Per ogni condominio creo un modulo
                    var moduliCondomini = new List<byte[]>();
                    foreach (var condominio in listaPagamenti.Keys)
                    {
                        var iban = condominio.DatiBancariPrincipale.Iban;
                        if (!string.IsNullOrEmpty(iban) && iban.StartsWith("IT"))
                            iban = iban.Substring(2);

                        // Intestazione
                        var datiF24 = new DatiModelloF24
                        {
                            CodiceFiscaleCondominio = condominio.CodiceFiscale,
                            ComuneCondominio = condominio.Indirizzo.Comune.Descrizione,
                            IbanCondominio = iban,
                            IndirizzoCondominio = condominio.Indirizzo.Indirizzo + condominio.Indirizzo.Civico,
                            ProvinciaCondominio = condominio.Indirizzo.Comune.ProvinciaAppartenenza.Codice,
                            DataVersamento = dataVersamento.ToShortDateString()
                        };

                        if (dataVersamento.Year == 2014)
                            datiF24.IbanCondominio = datiF24.IbanCondominio.Substring(2);

                        var nomeCondominio = condominio.Descrizione;
                        if (nomeCondominio.Length > 70)
                        {
                            datiF24.NomeCondominio = nomeCondominio.Substring(0, 70);
                            datiF24.NomeCondominio2 = nomeCondominio.Substring(71);
                        }
                        else
                            datiF24.NomeCondominio = nomeCondominio;

                        // Dati Banca
                        var banca = _daoFactory.GetAbiCabDao().GetByAbiCab(condominio.DatiBancariPrincipale.Abi, condominio.DatiBancariPrincipale.Cab);
                        datiF24.NomeBancaDelega = banca.DescrizioneAbi;
                        datiF24.NomeAgenziaDelega = banca.DescrizioneCab;
                        datiF24.ProvinciaAgenziaDelega = banca.Provincia;

                        var progressivoTributo = 0;
                        var totaleDebito = 0m;
                        var totaleCredito = 0m;
                        foreach (var kvp in listaPagamenti[condominio])
                        {
                            progressivoTributo++;
                            decimal? importoADebito = (from pag in kvp.Value
                                                       where pag.RitenutaAcconto.Importo != null && pag.RitenutaAcconto.Importo > 0
                                                       select pag).Sum(pag => Math.Round(pag.RitenutaAcconto.ImportoConInteressi, 2));
                            setImporto(kvp.Key, importoADebito.GetValueOrDefault(), progressivoTributo, datiF24);

                            // Eventuali sanzioni
                            var importoSanzione = kvp.Value.Sum(pag => Math.Round(pag.RitenutaAcconto.ImportoSanzione.GetValueOrDefault(), 2));
                            if (importoSanzione > 0)
                            {
                                progressivoTributo++;
                                setImporto("8906¥" + kvp.Key.Split('¥')[1], importoSanzione, progressivoTributo, datiF24);
                            }

                            totaleDebito += importoADebito.GetValueOrDefault() + importoSanzione;
                        }

                        datiF24.TotaleImportoADebito = totaleDebito.ToString("#0.00");
                        datiF24.TotaleImporto = datiF24.TotaleImportoADebito;

                        var xmlMappingFile = RitenutaModuloPDFResources.ResourceManager.GetObject(string.Format("F24_FieldMapping_{0}", dataVersamento.Year));
                        if (xmlMappingFile == null)
                            xmlMappingFile = RitenutaModuloPDFResources.ResourceManager.GetObject("F24_FieldMapping");

                        moduliCondomini.Add(FillForm.FillStream(datiF24, (byte[])modulo, Library.Conversione.ToString(xmlMappingFile), false, true));
                    }

                    // Merge di tutte le pagine
                    if (moduliCondomini.Count > 0)
                    {
                        try
                        {
                            var pdfmerge = new PdfMerge();
                            bytes = pdfmerge.Merge(moduliCondomini, true);
                        }
                        catch (Exception ex)
                        {
                            _log.ErrorFormat("Errore nel merge dei moduli - {0} - ritenuta:{1} - azienda:{2}", ex, Library.Utility.GetMethodDescription(), ritenuta.ID, ritenuta.AziendaID);                            
                            throw;
                        }
                    }
                }


                return bytes;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato durante la creazione del file CBI delle ritenute - F24. - {0} - ritenuta:{1}", ex, Library.Utility.GetMethodDescription(), ritenuta.ID);
                _notifier.Notify("Si sono verificati problemi inaspettati durante la creazione del file CBI delle ritenute - F24." + Environment.NewLine + "Controllare il log per ulteriori dettagli.");
                return bytes;
            }

        }
Exemplo n.º 4
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)
            {
                var logDocuments = true;
                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
                {
                    // =====================================
                    // Creo le pagine della Lettera
                    // =====================================
                    var nomiFiles = new string[allegati.Count];
                    var contenutoAllegati = new byte[allegati.Count][];

                    // -------------------------------------
                    // Allegati
                    // -------------------------------------
                    var index = 0;
                    foreach (var documento in allegati)
                    {
                        nomiFiles[index] = documento.FileName + documento.FileExtension;
                        contenutoAllegati[index] = _converter.ConvertToPdf(documento).ToArray();
                        allegatiLista.Add(documento);
                        index++;
                    }

                    // =====================================
                    // Invio Messaggio
                    // =====================================

                    // -------------------------------------
                    // Invio
                    // -------------------------------------
                    var credenziali = _configurationService.GetLoginInfo(idAzienda);

                    if (credenziali != null && !string.IsNullOrEmpty(credenziali.Value.Utente) && !string.IsNullOrEmpty(credenziali.Value.Password))
                    {
                        var userService = new it.emessage.users.Users();
                        var success = false;
                        try
                        {
                            var resultUsers = userService.Login(credenziali.Value.Utente, credenziali.Value.Password, null);
                            success = resultUsers.success;
                        }
                        catch (Exception ex)
                        {
                            _log.WarnFormat("Errore durante il controllo delle credenziali - {0} - username:{1} - password:{2}", ex, Library.Utility.GetMethodDescription(), credenziali.Value.Utente, credenziali.Value.Password);
                        }
                        if (success)
                        {
                            var tipoIndirizzo = TipoIndirizzo.Recapito;
                            if (personaMessaggioDTO != null)
                                tipoIndirizzo = personaMessaggioDTO.TipoIndirizzo;
                            var identificazioneMittente = _configurationService.GetIdentificazioneMittente(idAzienda, TipoMessaggio.Fax, tipoIndirizzo);

                            // Controllo identificazione mittente
                            if (string.IsNullOrEmpty(identificazioneMittente.Indirizzo))
                                return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, "La lettera non può essere inviata perchè non è presente l'INDIRIZZO POSTALE del mittente" + Environment.NewLine + "Inserire l'informazione mancante nella anagrafica dello studio e riprovare.", new DocumentInfo()) };
                            if (string.IsNullOrEmpty(identificazioneMittente.Cap))
                                return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, "La lettera non può essere inviata perchè non è presente il CAP del mittente" + Environment.NewLine + "Inserire l'informazione mancante nella anagrafica dello studio e riprovare.", new DocumentInfo()) };
                            if (string.IsNullOrEmpty(identificazioneMittente.Comune))
                                return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, "La lettera non può essere inviata perchè non è presente il COMUNE del mittente" + Environment.NewLine + "Inserire l'informazione mancante nella anagrafica dello studio e riprovare.", new DocumentInfo()) };
                            if (string.IsNullOrEmpty(identificazioneMittente.Provincia))
                                return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, "La lettera non può essere inviata perchè non è presente la PROVINCIA del mittente" + Environment.NewLine + "Inserire l'informazione mancante nella anagrafica dello studio e riprovare.", new DocumentInfo()) };
                            if (string.IsNullOrEmpty(identificazioneMittente.Stato))
                                return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, "La lettera non può essere inviata perchè non è presente lo STATO del mittente" + Environment.NewLine + "Inserire l'informazione mancante nella anagrafica dello studio e riprovare.", new DocumentInfo()) };

                            // Controllo destinatari
                            foreach (var dest in destinatari)
                            {
                                var destinatarioAry = dest.Split('¥');
                                var recipient = new Contact
                                {
                                    Company = destinatarioAry[0],
                                    FirstName = destinatarioAry[1],
                                    LastName = destinatarioAry[2],
                                    Address = destinatarioAry[3],
                                    City = destinatarioAry[4],
                                    State = destinatarioAry[5],
                                    ZipCode = destinatarioAry[6],
                                    Country = destinatarioAry[7]
                                };

                                if (string.IsNullOrEmpty(recipient.Address))
                                    return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, string.Format("La lettera non può essere inviata perchè non è presente l'INDIRIZZO POSTALE di '{0} {1} {2}' {3} Inserire l'informazione mancante nella anagrafica del destinatario e riprovare.", recipient.Company, recipient.FirstName, recipient.LastName, Environment.NewLine), new DocumentInfo()) };
                                if (string.IsNullOrEmpty(recipient.ZipCode))
                                    return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, string.Format("La lettera non può essere inviata perchè non è presente il CAP di '{0} {1} {2}' {3} Inserire l'informazione mancante nella anagrafica del destinatario e riprovare.", recipient.Company, recipient.FirstName, recipient.LastName, Environment.NewLine), new DocumentInfo()) };
                                if (string.IsNullOrEmpty(recipient.City))
                                    return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, string.Format("La lettera non può essere inviata perchè non è presente il COMUNE di '{0} {1} {2}' {3} Inserire l'informazione mancante nella anagrafica del destinatario e riprovare.", recipient.Company, recipient.FirstName, recipient.LastName, Environment.NewLine), new DocumentInfo()) };
                                if (string.IsNullOrEmpty(recipient.State))
                                    return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, string.Format("La lettera non può essere inviata perchè non è presente la PROVINCIA di '{0} {1} {2}' {3} Inserire l'informazione mancante nella anagrafica del destinatario e riprovare.", recipient.Company, recipient.FirstName, recipient.LastName, Environment.NewLine), new DocumentInfo()) };
                                if (string.IsNullOrEmpty(recipient.Country))
                                    return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", null, false, string.Format("La lettera non può essere inviata perchè non è presente lo STATO di '{0} {1} {2}' {3} Inserire l'informazione mancante nella anagrafica del destinatario e riprovare.", recipient.Company, recipient.FirstName, recipient.LastName, Environment.NewLine), new DocumentInfo()) };
                            }

                            if (!string.IsNullOrEmpty(identificazioneMittente.Email))
                            {
                                if (!string.IsNullOrEmpty(emailRapportino))
                                    emailRapportino += ",";
                                emailRapportino += identificazioneMittente.Email;
                            }

                            // Mittente
                            if (string.IsNullOrEmpty(mittente))
                                mittente = identificazioneMittente.Nome;

                            if (ConfigurationManager.AppSettings["IsTest"] != null && bool.Parse(ConfigurationManager.AppSettings["IsTest"]))
                                destinatari = new List<string> { "Giorgio Parmeggiani¥Giorgio¥Parmeggiani¥via Larga 36¥Bologna¥BO¥40138¥ITALIA" };

                            var sender = new Contact
                            {
                                Address = identificazioneMittente.Indirizzo,
                                City = identificazioneMittente.Comune,
                                Company = identificazioneMittente.RagioneSociale,
                                State = identificazioneMittente.Provincia,
                                FirstName = identificazioneMittente.Nome,
                                LastName = identificazioneMittente.Cognome,
                                ZipCode = identificazioneMittente.Cap,
                                Country = identificazioneMittente.Stato
                            };

                            var recipients = new Contact[destinatari.Count];
                            var indexRecipients = 0;
                            foreach (var dest in destinatari)
                            {
                                var destinatarioAry = dest.Split('¥');
                                var recipient = new Contact
                                {
                                    Company = destinatarioAry[0],
                                    FirstName = destinatarioAry[1],
                                    LastName = destinatarioAry[2],
                                    Address = destinatarioAry[3],
                                    City = destinatarioAry[4],
                                    State = destinatarioAry[5],
                                    ZipCode = destinatarioAry[6],
                                    Country = destinatarioAry[7]
                                };
                                recipients[indexRecipients] = recipient;
                                indexRecipients++;
                            }

                            // Parametri spedizione
                            var parameters = new OptionalParameters[4];
                            parameters[0] = new OptionalParameters { ParameterName = "NotificationEmail", ParameterValue = emailRapportino };
                            parameters[1] = new OptionalParameters { ParameterName = "ColourPrint", ParameterValue = parametriInvioLettera.Colore.ToString() };
                            parameters[2] = new OptionalParameters { ParameterName = "OnlyFrontPrint", ParameterValue = (!parametriInvioLettera.FronteRetro).ToString() };
                            parameters[3] = new OptionalParameters { ParameterName = "CreateFirstPage", ParameterValue = parametriInvioLettera.PaginaIniziale.ToString() };

                            var service = new Letter { Timeout = 999999999 };

                            eMessageResultSendLetter resultSend;
                            try
                            {
                                var directoryName = string.Empty;
                                if (logDocuments)
                                {
                                    directoryName = $"{AppDomain.CurrentDomain.BaseDirectory}temp/{Guid.NewGuid()}";
                                    if (!Directory.Exists(directoryName))
                                        Directory.CreateDirectory(directoryName);

                                    for (var i = 0; i < contenutoAllegati.Length; i++)
                                    {
                                        var nomeFile = $"{directoryName}/{i.ToString().PadLeft(3, '0')}_{nomiFiles[i]}";
                                        using (var file = new FileStream(nomeFile, FileMode.Create, FileAccess.Write))
                                        {
                                            file.Write(contenutoAllegati[i], 0, contenutoAllegati[i].Length);
                                        }
                                    }
                                }

                                var pdfMerge = new PdfMerge();
                                var fileUnico = pdfMerge.Merge(contenutoAllegati, false);
                                var contentToSend = new byte[1][];
                                contentToSend[0] = fileUnico;

                                var nomiFilesToSend = new string[1];
                                nomiFilesToSend[0] = motivoMessaggio.ToString();
                                if (!string.IsNullOrEmpty(oggetto))
                                    nomiFilesToSend[0] += $"_{oggetto.ToFileName()}";
                                if (string.IsNullOrEmpty(nomiFilesToSend[0]))
                                    nomiFilesToSend[0] = "document";
                                nomiFilesToSend[0] += ".pdf";

                                if (logDocuments)
                                {
                                    var nomeFileUnico = $"{directoryName}/{nomiFilesToSend[0]}";
                                    using (var file = new FileStream(nomeFileUnico, FileMode.Create, FileAccess.Write))
                                    {
                                        file.Write(fileUnico, 0, fileUnico.Length);
                                    }
                                }

                                if (ConfigurationManager.AppSettings["IsTest"] != null && bool.Parse(ConfigurationManager.AppSettings["IsTest"]))
                                    resultSend = null;
                                else
                                    resultSend = service.Send(credenziali.Value.Utente, credenziali.Value.Password, sender, recipients, parametriInvioLettera.Tipo, contentToSend, nomiFilesToSend, parameters);
                            }
                            catch (System.Web.Services.Protocols.SoapException ex)
                            {
                                return new[]{ new RisultatoInvioMessaggio(null, null, false, ex.Message, new DocumentInfo()) };
                            }
                            catch (Exception ex)
                            {
                                _log.ErrorFormat("Errore inaspettato nell'invio della lettera - {0}", ex, Library.Utility.GetMethodDescription());
                                throw;
                            }

                            if (resultSend != null)
                            {
                                foreach (var eMessageSpeditionResult in resultSend.SpeditionResult)
                                {
                                    string messaggioInvio;
                                    if (eMessageSpeditionResult.success)
                                    {
                                        messaggioInvio = string.Format("Lettera accodata per l'invio: {0}", eMessageSpeditionResult.jobCode);
                                        _log.InfoFormat("Invio lettera RIUSCITO - {0} - messageCode: {1} - messaggio: {2} - jobcode: {3} - destinatario: {4}", Library.Utility.GetMethodDescription(), eMessageSpeditionResult.messageCode, eMessageSpeditionResult.errorDescription, eMessageSpeditionResult.jobCode, destinatari.Aggregate(string.Empty, (current, dest) => current + (dest + ";")));
                                    }
                                    else
                                    {
                                        messaggioInvio = "Invio della lettera non riuscito:" + Environment.NewLine + eMessageSpeditionResult.errorDescription;
                                        _log.WarnFormat("Invio lettera FALLITO - {0} - messageCode: {1} - messaggio: {2} - jobcode: {3} - destinatario: {4}", Library.Utility.GetMethodDescription(), eMessageSpeditionResult.messageCode, eMessageSpeditionResult.errorDescription, eMessageSpeditionResult.jobCode, destinatari.Aggregate(string.Empty, (current, dest) => current + (dest + ";")));
                                    }

                                    var resultInvio = new RisultatoInvioMessaggio(eMessageSpeditionResult.jobCode, eMessageSpeditionResult.messageCode, eMessageSpeditionResult.success, messaggioInvio, new DocumentInfo());
                                    var storicoMessaggio = _messaggisticaService.StoricizzaMessaggio(persona, condominio, resultInvio, motivoMessaggio, oggetto, testo, destinatari, mittente, emailRapportino, allegatiLista, TipoMessaggio.Lettera);
                                    if (storicoMessaggio != null)
                                        resultInvio.IdMessaggio = storicoMessaggio.ID;
                                    results.Add(resultInvio);
                                }                                
                            }
                        }
                        else
                        {
                            _log.WarnFormat("Credenziali non valide - {0} - username:{1} - password:{2} - azienda:{3}", Library.Utility.GetMethodDescription(), credenziali.Value.Utente, credenziali.Value.Password, idAzienda);
                        }
                    }
                    else
                    {
                        _log.ErrorFormat("Errore inaspettato durante l'invio della lettera. NON sono presenti le credenziali per l'invio della lettera - {0} - oggetto:{1} - destinatario:{2} - azienda:{3}", Library.Utility.GetMethodDescription(), oggetto, destinatari[0], idAzienda);
                        var message = string.Format("KO - Non sono definite le credenziali per l'invio della lettera.{0}Inserire le credenziali corrette nel pannello Messaggistica dell'anagrafica dello studio", Environment.NewLine);
                        return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", string.Empty, false, message, new DocumentInfo()) };
                    }
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("Errore inaspettato durante l'invio della lettera - {0} - oggetto:{1} - destinatario:{2} - azienda:{3}", ex, Library.Utility.GetMethodDescription(), oggetto, destinatari[0], Security.Login.Instance.CurrentLogin().Azienda);
                    throw;
                }

                return results;
            }

            return new List<RisultatoInvioMessaggio> { new RisultatoInvioMessaggio("KO", string.Empty, false, "Non è definito nessun destinatario", new DocumentInfo()) };
        }
Exemplo n.º 5
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()) };
        }