private DatiFornitori770 getDatiFornitore(Fornitore fornitore, Condominio condominio, int index)
        {
            var datiFornitore = new DatiFornitori770
            {
                Cognome = (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Giuridica) ? fornitore.PersonaRiferimento.RagioneSociale : fornitore.PersonaRiferimento.Cognome,
                Nome = (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Giuridica) ? string.Empty : fornitore.PersonaRiferimento.Nome,
                CodiceFiscale = fornitore.GetCodiceFiscale(),
                ComuneNascita = (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Fisica) ? fornitore.PersonaRiferimento.ComuneNascita.Descrizione : string.Empty,
                ProvinciaNascita = (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Fisica) ? fornitore.PersonaRiferimento.ComuneNascita.ProvinciaAppartenenza.Codice : string.Empty,
                DataNascita = (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Fisica) ? fornitore.PersonaRiferimento.DataNascita.GetValueOrDefault().ToShortDateString() : string.Empty,
                Sesso = (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Fisica) ? fornitore.PersonaRiferimento.Sesso.ToString().Substring(0, 1).ToUpper() : string.Empty,
                IndirizzoCompleto = fornitore.PersonaRiferimento.IndirizzoResidenza.GetIndirizzoCompleto(),
                ComuneResidenza = fornitore.PersonaRiferimento.IndirizzoResidenza.Comune.Descrizione,
                Provincia = fornitore.PersonaRiferimento.IndirizzoResidenza.Comune.ProvinciaAppartenenza.Codice,
                CodiceFiscaleCondominio = condominio.CodiceFiscale,
                Causale = fornitore.GetTipologiaReddito(),
                ProgressivoComunicazione = index.ToString().PadLeft(8, '0')
            };

            return datiFornitore;
        }
        }

        /// <summary>
        /// RECORD DI TIPO "H":  Dati relativi alla comunicazione dati certificazioni lavoro autonomo, provvigioni e redditi diversi - CU 2015
        /// </summary>
        /// <param name="condominio">Condominio di riferimento</param>
        /// <param name="fornitore">Fornitore a cui è stata trattenuta l'imposta</param>
        /// <param name="anno"></param>
        /// <param name="datiCertificazione">Dati delle certificazioni</param>
        /// <param name="esenteRegimeMinimo">Identifica se il fornitore è esente per regime minimo</param>
        /// <param name="progressivoCertificazione"></param>
        /// <param name="progressivoModulo">Progressivo del modulo compilato</param>
        /// <param name="sw">File di scrittura</param>
        private void writeRowH(Condominio condominio, Fornitore fornitore, int anno, IList<DettaglioDatiCertificazioneDTO> datiCertificazione, bool esenteRegimeMinimo, int progressivoCertificazione, int progressivoModulo, StreamWriter sw)
        {
            try
            {
                var sb = new StringBuilder(1900);

                var datiImponibile = new List<DettaglioDatiCertificazioneDTO>();
                foreach (var dettaglioDatiCertificazioneDTO in datiCertificazione)
                {
                    if(datiImponibile.All(item => item.IdFattura != dettaglioDatiCertificazioneDTO.IdFattura))
                        datiImponibile.Add(dettaglioDatiCertificazioneDTO);
                }

                //======================================================
                // CAMPI POSIZIONALI (da carattere 1 a carattere 89)
                //======================================================
                var formatoDecimale = "#0.00";
                var cultureInfo = new CultureInfo("it-IT");

                // Tipo record
                sb.Append("H");

                // Codice fiscale del Sostituto d'imposta (Condominio)
                sb.Append(condominio.CodiceFiscale.PadRight(16, ' '));

                // Progressivo Modulo
                sb.Append(progressivoModulo.ToString(CultureInfo.InvariantCulture).PadLeft(8, '0'));

                // Codice Fiscale del percipiente (Fornitore)
                sb.Append(fornitore.GetCodiceFiscale().ToUpper().PadRight(16));

                // Progressivo Certificazione
                sb.Append(progressivoCertificazione.ToString(CultureInfo.InvariantCulture).PadLeft(5, '0'));

                // filler
                sb.Append(string.Empty.PadLeft(17));

                // Spazio a disposizione dell'utente 
                sb.Append(string.Empty.PadRight(6));

                // filler
                sb.Append(string.Empty.PadLeft(14));
                // filler
                sb.Append(string.Empty.PadLeft(1));
                // filler
                sb.Append(string.Empty.PadLeft(4));
                // filler
                sb.Append(string.Empty.PadLeft(1));

                //======================================================
                // CAMPI NON POSIZIONALI (da carattere 90)
                //======================================================

                //---------------------------------------------
                // Dati relativi al percipiente delle somme
                //---------------------------------------------
                // Causale
                sb.Append(getCampoNonPosizionale("AU001001", fornitore.GetTipologiaReddito(), AllineamentoCaratteri.Sinistro));

                // Anno
                //sb.Append(getCampoNonPosizionale("AU001002", anno.ToString(cultureInfo), AllineamentoCaratteri.Destro));

                // Ammontare lordo corrisposto
                sb.Append(getCampoNonPosizionale("AU001004", Math.Round(datiCertificazione.Sum(item => item.CompensiSoggetti + item.CompensiNonSoggetti + item.AltreSpeseNonSoggette), 2).ToString(formatoDecimale, cultureInfo), AllineamentoCaratteri.Destro));

                // Altre somme non soggette a ritenuta
                var altreSommeNonSoggetteARitenuta = Math.Round(datiCertificazione.Sum(item => item.CompensiNonSoggetti + item.AltreSpeseNonSoggette), 2);
                if (altreSommeNonSoggetteARitenuta > 0)
                {
                    sb.Append(getCampoNonPosizionale("AU001007", altreSommeNonSoggetteARitenuta.ToString(formatoDecimale, cultureInfo), AllineamentoCaratteri.Destro));

                    // Codice
                    sb.Append(getCampoNonPosizionale("AU001006", "3", AllineamentoCaratteri.Destro));
                }

                if (!esenteRegimeMinimo)
                {
                    // Imponibile
                    sb.Append(getCampoNonPosizionale("AU001008", Math.Round(datiCertificazione.Sum(item => item.CompensiSoggetti), 2).ToString(formatoDecimale, cultureInfo), AllineamentoCaratteri.Destro));

                    // Ritenute a titolo di acconto
                    sb.Append(getCampoNonPosizionale("AU001009", Math.Round(datiCertificazione.Sum(item => item.ImportoRitenuta), 2).ToString(formatoDecimale, cultureInfo), AllineamentoCaratteri.Destro));
                }

                //======================================================
                // CAMPI POSIZIONALI (da carattere 1890 a carattere 1900)
                //======================================================

                var charToEnd = 1889 - sb.ToString().Length;
                sb.Append(string.Empty.PadRight(charToEnd));

                // filler
                sb.Append(string.Empty.PadLeft(8));

                //---------------------------------------------
                // Ultimi caratteri di controllo
                //---------------------------------------------
                sb.Append("A");

                // CarriageReturn LineFeed
                sb.Append(CRLF);

                sw.Write(sb.ToString());
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato durante la creazione della sezione H per il modello Certificazione Unica - {0} - condominio:{1} - fornitore:{2}", ex, Library.Utility.GetMethodDescription(), condominio.ID, fornitore.ID);
                throw;
        private byte[] getModuloLavoratoreAutonomo(Fornitore fornitore, IList<DettaglioDatiCertificazioneDTO> datiCertificazione, bool esenteRegimeMinimo, int anno, int progressivoModulo, byte[] templateDatiLavoratoreAutonomo, Azienda azienda)
        {
            const string formatoDecimale = "#0.00";

            var datiLavoratoreAutonomo = new DatiLavoratoreAutonomoCU
            {
                Causale = fornitore.GetTipologiaReddito(),
                CodiceFiscalePercipiente = fornitore.GetCodiceFiscale(),
                //AnnoRiferimento = anno.ToString(_cultureInfo),
                AmmontareLordoCorrisposto = Math.Round(datiCertificazione.Sum(item => item.CompensiSoggetti + item.CompensiNonSoggetti + item.AltreSpeseNonSoggette), 2).ToString(formatoDecimale, _cultureInfo),
                Imponibile = esenteRegimeMinimo ? string.Empty : Math.Round(datiCertificazione.Sum(item => item.CompensiSoggetti), 2).ToString(formatoDecimale, _cultureInfo),
                Ritenuta = esenteRegimeMinimo ? string.Empty : Math.Round(datiCertificazione.Sum(item => item.ImportoRitenuta), 2).ToString(formatoDecimale, _cultureInfo),
                NumeroModulo = progressivoModulo.ToString(_cultureInfo)
            };

            var altreSommeNonSoggette = Math.Round(datiCertificazione.Sum(item => item.CompensiNonSoggetti + item.AltreSpeseNonSoggette), 2);
            if (altreSommeNonSoggette != 0)
            {
                datiLavoratoreAutonomo.AltreSommeNonSoggette = altreSommeNonSoggette.ToString(formatoDecimale, _cultureInfo);
                datiLavoratoreAutonomo.Codice = "3";
            }

            return FillForm.FillStream(datiLavoratoreAutonomo, templateDatiLavoratoreAutonomo, GestioneFiscaleResources.ModelloCULavoratoreAutonomo_FieldMapping, false, true);
        }
        /// <summary>
        /// RECORD DI TIPO "H": Dati relativi alla comunicazione dati certificazioni lavoro autonomo, provvigioni e redditi diversi del mod. 770/20XX semplificato
        /// </summary>
        /// <param name="condominio">Condominio di riferimento</param>
        /// <param name="fornitore">Fornitore a cui è stata trattenuta l'imposta</param>
        /// <param name="anno"></param>
        /// <param name="ritenute">Elenco delle trattenute per fornitore</param>
        /// <param name="progressivoModulo">Progressivo del modulo compilato</param>
        /// <param name="sw">File di scrittura</param>
        private void writeRowH(Condominio condominio, Fornitore fornitore, int anno, IEnumerable<Ritenuta> ritenute, int progressivoModulo, StreamWriter sw)
        {
            try
            {
                var sb = new StringBuilder(1900);

                //======================================================
                // CAMPI POSIZIONALI (da carattere 1 a carattere 89)
                //======================================================

                // Tipo record
                sb.Append("H");

                // Codice Fiscale del soggetto dichiarante (Condominio)
                sb.Append(condominio.CodiceFiscale.PadRight(16, ' '));

                // Progressivo Modulo
                sb.Append(progressivoModulo.ToString().PadLeft(8, '0'));

                // campo utente
                sb.Append(string.Empty.PadLeft(3));

                // Tipo operazione
                sb.Append(string.Empty.PadLeft(1));

                // Codice Fiscale del percipiente (Fornitore)
                sb.Append(fornitore.GetCodiceFiscale().PadRight(16));

                // filler
                sb.Append(string.Empty.PadLeft(8));

                // campo utente per identificativo dichiarazione
                sb.Append(string.Empty.PadRight(20));

                // Identificativo del produttore del software (codice fiscale)
                sb.Append("02818651206".PadRight(16));

                //======================================================
                // CAMPI NON POSIZIONALI (da carattere 90)
                //======================================================

                //---------------------------------------------
                // Dati relativi al percipiente delle somme
                //---------------------------------------------

                // Codice fiscale
                sb.Append(getCampoNonPosizionale("AU001001", fornitore.GetCodiceFiscale(), AllineamentoCaratteri.Sinistro));

                // Cognome o denominazione
                if (fornitore.PersonaRiferimento.TipoPersona == TipoPersonaEnum.Giuridica)
                    sb.Append(getCampoNonPosizionale("AU001002", fornitore.PersonaRiferimento.RagioneSociale, AllineamentoCaratteri.Sinistro));
                else
                {
                    // Cognome
                    sb.Append(getCampoNonPosizionale("AU001002", fornitore.PersonaRiferimento.Cognome.ToUpper(), AllineamentoCaratteri.Sinistro));

                    // Nome
                    sb.Append(getCampoNonPosizionale("AU001003", fornitore.PersonaRiferimento.Nome.ToUpper(), AllineamentoCaratteri.Sinistro));

                    // Sesso
                    if (fornitore.PersonaRiferimento.TipoPersona == TipoPersonaEnum.Fisica)
                    {
                        if(fornitore.PersonaRiferimento.Sesso != SessoEnum.Undefined)
                            sb.Append(getCampoNonPosizionale("AU001004", fornitore.PersonaRiferimento.Sesso.ToString().Substring(0, 1).ToUpper(), AllineamentoCaratteri.Sinistro));

                        // Data di nascita
                        sb.Append(getCampoNonPosizionale("AU001005", convertData(fornitore.PersonaRiferimento.DataNascita), AllineamentoCaratteri.Destro));

                        // Comune di nascita
                        sb.Append(getCampoNonPosizionale("AU001006", fornitore.PersonaRiferimento.ComuneNascita.Descrizione, AllineamentoCaratteri.Sinistro));

                        // Provincia di nascita
                        sb.Append(int.Parse(fornitore.PersonaRiferimento.ComuneNascita.Codice) <= 999201
                                      ? getCampoNonPosizionale("AU001007", fornitore.PersonaRiferimento.ComuneNascita.ProvinciaAppartenenza.Codice, AllineamentoCaratteri.Sinistro)
                                      : getCampoNonPosizionale("AU001007", "EE", AllineamentoCaratteri.Sinistro));
                    }
                }

                // Comune di residenza
                sb.Append(getCampoNonPosizionale("AU001008", fornitore.PersonaRiferimento.IndirizzoResidenza.Comune.Descrizione, AllineamentoCaratteri.Sinistro));

                // Provincia di residenza
                sb.Append(getCampoNonPosizionale("AU001009", fornitore.PersonaRiferimento.IndirizzoResidenza.Comune.ProvinciaAppartenenza.Codice, AllineamentoCaratteri.Sinistro));

                // Via e numero civico
                sb.Append(getCampoNonPosizionale("AU001012", fornitore.PersonaRiferimento.IndirizzoResidenza.GetIndirizzoCompleto(), AllineamentoCaratteri.Sinistro));

                //---------------------------------------------
                // Dati relativi alle somme erogate
                //---------------------------------------------

                var speseSoggette = _spesaService.GetSoggetteRitenutaByFornitoreCondominioAnno(fornitore, condominio, anno);
                var imponibileIva = speseSoggette.Sum(item => item.Imponibile);
                var imponibileRitenuta = speseSoggette.Sum(item => item.GetImponibileRitenuta());
                var altreSommeNonSoggette = Math.Round(imponibileIva - imponibileRitenuta, 2);

                // Causale
                sb.Append(getCampoNonPosizionale("AU001019", fornitore.GetTipologiaReddito(), AllineamentoCaratteri.Sinistro));

                // Ammontare Lordo Corrisposto (al netto di IVA)
                sb.Append(getCampoNonPosizionale("AU001022", Math.Round(imponibileIva, 2).ToString(), AllineamentoCaratteri.Destro));

                // Codice
                if (altreSommeNonSoggette > 0)
                    sb.Append(getCampoNonPosizionale("AU001024", "3", AllineamentoCaratteri.Destro));

                // Altre somme non soggette a ritenuta
                if(altreSommeNonSoggette > 0)
                    sb.Append(getCampoNonPosizionale("AU001025", altreSommeNonSoggette.ToString(), AllineamentoCaratteri.Destro));

                // Imponibile
                sb.Append(getCampoNonPosizionale("AU001026", Math.Round(imponibileIva - altreSommeNonSoggette, 2).ToString(), AllineamentoCaratteri.Destro));

                // Ritenute a titolo di acconto
                sb.Append(getCampoNonPosizionale("AU001027", Math.Round(ritenute.Sum(item => item.Importo.GetValueOrDefault()), 2).ToString(), AllineamentoCaratteri.Destro));

                //======================================================
                // CAMPI POSIZIONALI (da carattere 1890 a carattere 1900)
                //======================================================

                var charToEnd = 1889 - sb.ToString().Length;
                sb.Append(string.Empty.PadRight(charToEnd));

                // filler
                sb.Append(string.Empty.PadLeft(8));

                //---------------------------------------------
                // Ultimi caratteri di controllo
                //---------------------------------------------
                sb.Append("A");

                // CarriageReturn LineFeed
                sb.Append(CRLF);

                sw.Write(sb.ToString());
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato durante la creazione della sezione H per il modello 770 - {0} - condominio:{1} - fornitore:{2}", ex, Library.Utility.GetMethodDescription(), condominio.ID, fornitore.ID);
                throw;
            }