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);
        }
        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 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="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, IGrouping<int, Ritenuta> ritenute, int progressivoModulo, StreamWriter sw)
        {
            try
            {
                StringBuilder 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 == Gipasoft.Sfera.Enums.TipoPersonaEnum.Giuridica)
                    sb.Append(getCampoNonPosizionale("AU001002", Gipasoft.Library.Conversione.ToCBI(fornitore.PersonaRiferimento.RagioneSociale), AllineamentoCaratteri.Sinistro));
                else
                {
                    // Cognome
                    sb.Append(getCampoNonPosizionale("AU001002", Gipasoft.Library.Conversione.ToCBI(fornitore.PersonaRiferimento.Cognome), AllineamentoCaratteri.Sinistro));

                    // Nome
                    sb.Append(getCampoNonPosizionale("AU001003", Gipasoft.Library.Conversione.ToCBI(fornitore.PersonaRiferimento.Nome), AllineamentoCaratteri.Sinistro));

                    // Sesso
                    if (fornitore.PersonaRiferimento.TipoPersona == Gipasoft.Sfera.Enums.TipoPersonaEnum.Fisica)
                    {
                        if(fornitore.PersonaRiferimento.Sesso != Gipasoft.Sfera.Enums.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", Gipasoft.Library.Conversione.ToCBI(fornitore.PersonaRiferimento.ComuneNascita.Descrizione), AllineamentoCaratteri.Sinistro));

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

                // Comune di residenza
                sb.Append(getCampoNonPosizionale("AU001008", Gipasoft.Library.Conversione.ToCBI(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("AU001011", Gipasoft.Library.Conversione.ToCBI(fornitore.PersonaRiferimento.IndirizzoResidenza.GetIndirizzoCompleto()), AllineamentoCaratteri.Sinistro));

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

                IList<Spesa> speseSoggette = _spesaService.GetSoggetteRitenutaByFornitoreCondominioAnno(fornitore, condominio, anno);
                decimal imponibileIva = speseSoggette.Sum(item => item.Imponibile);
                decimal imponibileRitenuta = speseSoggette.Sum(item => item.GetImponibileRitenuta());
                decimal altreSommeNonSoggette = Math.Truncate(imponibileIva - imponibileRitenuta);

                // Causale
                string causale = "W";
                if (fornitore.CodiceTributo == "1040")
                    causale = "A";
                sb.Append(getCampoNonPosizionale("AU001018", causale, AllineamentoCaratteri.Sinistro));

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

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

                // Imponibile
                sb.Append(getCampoNonPosizionale("AU001024", Math.Truncate(imponibileIva - altreSommeNonSoggette).ToString(), AllineamentoCaratteri.Destro));

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

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

                int 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)
            {
                log4net.MDC.Set("user", Gipasoft.Security.Login.Instance.CurrentLogin().LoginName);
                _log.Fatal("Errore inaspettato durante la creazione della sezione B per il modelle 770 -" + Gipasoft.Library.Utility.GetMethodDescription() + " - condominio:" + condominio.ID + " - fornitore:" + fornitore.ID, ex);
                throw ex;
            }
        }
        }

        /// <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;
        /// <summary>
        /// RECORD DI TIPO "D": Dati anagrafici del percipiente - CU 2015
        /// </summary>
        /// <param name="condominio"></param>
        /// <param name="fornitore">Fornitore percipiente</param>
        /// <param name="progressivoCertificazione">Progressivo della certificazione</param>
        /// <param name="dataDichiarazione"></param>
        /// <param name="progressivoInvio">Progressivo Attribuito dal Servizio telematico alla singola C.U.</param>
        /// <param name="sw">File di scrittura</param>
        /// <param name="tipoOperazione">Identifica se si tratta di un nuovo invio oppure di una sostituzione o un annullamento di un invio precedente</param>
        /// <param name="protocolloComunicazione">Protocollo assegnato dal Servizio telematico alla singola C.U. che si intende sostituire</param>
        private void writeRowD(Condominio condominio, Fornitore fornitore, int progressivoCertificazione, DateTime dataDichiarazione, TipoOperazioneFiscale tipoOperazione, long? protocolloComunicazione, int? progressivoInvio, StreamWriter sw)
        {
            try
            {
                var cognomeFornitore = fornitore.PersonaRiferimento.RagioneSociale;
                var nomeFornitore = string.Empty;
                var sessoFornitore = string.Empty;
                var dataNascitaFornitore = string.Empty;
                if (fornitore.PersonaRiferimento.TipoPersona == TipoPersonaEnum.Fisica)
                {
                    cognomeFornitore = fornitore.PersonaRiferimento.Cognome;
                    nomeFornitore = fornitore.PersonaRiferimento.Nome;
                    sessoFornitore = fornitore.PersonaRiferimento.Sesso.GetValueOrDefault().ToString().ToUpper().Substring(0, 1);
                    dataNascitaFornitore = convertData(fornitore.PersonaRiferimento.DataNascita);
                }

                var sb = new StringBuilder(1900);

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

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

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

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

                // Codice fiscale del percipiente
                sb.Append(fornitore.GetCodiceFiscale().PadRight(16, ' '));

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

                // -------------------------------------------------------------------------------------------------------------
                // Sezione da compilare per la sostituzione di una singola certificazione già trasmessa e accolta (Campi 6 e 7)
                // -------------------------------------------------------------------------------------------------------------
                // Protocollo assegnato dal Servizio telematico alla singola C.U. che si intende sostituire - Identificativo dell'invio
                sb.Append(tipoOperazione == TipoOperazioneFiscale.Nuovo
                    ? string.Empty.PadLeft(17, '0')
                    : protocolloComunicazione.ToString().PadLeft(17, '0'));

                // Protocollo assegnato dal Servizio telematico alla singola C.U. che si intende sostituire - Progressivo Attribuito dal Servizio telematico alla singola C.U.
                sb.Append(tipoOperazione == TipoOperazioneFiscale.Nuovo
                    ? string.Empty.PadLeft(6, '0')
                    : progressivoInvio.ToString().PadLeft(6, '0'));

                // Spazio a disposizione dell'utente 
                sb.Append(string.Empty.PadLeft(14));

                // Tipo operazione: Annullamento - Sostituzione
                var tipoOperazioneAnnSost = string.Empty;
                switch (tipoOperazione)
                {
                    case TipoOperazioneFiscale.Annullamento:
                        tipoOperazioneAnnSost = "A";
                        break;
                    case TipoOperazioneFiscale.Sostituzione:
                        tipoOperazioneAnnSost = "S";
                        break;
                }
                sb.Append(tipoOperazioneAnnSost.PadLeft(1));

                // Filler
                sb.Append(string.Empty.PadLeft(4));

                // Flag conferma Singola Certificazione per i controlli di rispondenza
                sb.Append("0");

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

                //---------------------------------------------
                // Dati relativi al datore di lavoro, ente pensionistico o altro sostituto d'imposta
                //---------------------------------------------

                // Codice Fiscale
                sb.Append(getCampoNonPosizionale("DA001001", condominio.CodiceFiscale, AllineamentoCaratteri.Sinistro));

                // Cognome o denominazione 
                sb.Append(getCampoNonPosizionale("DA001002", condominio.Descrizione, AllineamentoCaratteri.Sinistro));

                // Comune di residenza 
                sb.Append(getCampoNonPosizionale("DA001004", condominio.Indirizzo.Comune.Descrizione, AllineamentoCaratteri.Sinistro));

                // Provincia di residenza 
                sb.Append(getCampoNonPosizionale("DA001005", getSiglaProvincia(condominio.Indirizzo.Comune), AllineamentoCaratteri.Sinistro));

                // Cap 
                sb.Append(getCampoNonPosizionale("DA001006", condominio.Indirizzo.Cap, AllineamentoCaratteri.Sinistro));

                // Via e numero civico  
                sb.Append(getCampoNonPosizionale("DA001007", string.Format("{0} {1}", condominio.Indirizzo.Indirizzo, condominio.Indirizzo.Civico), AllineamentoCaratteri.Sinistro));

                // Codice attività
                sb.Append(getCampoNonPosizionale("DA001010", "970000", AllineamentoCaratteri.Sinistro));

                // Codice Sede  
                var codiceSedeEntratel = "000";
                if (!string.IsNullOrEmpty(condominio.Azienda.CodiceSedeEntratel))
                    codiceSedeEntratel = condominio.Azienda.CodiceSedeEntratel;
                sb.Append(getCampoNonPosizionale("DA001011", codiceSedeEntratel, AllineamentoCaratteri.Sinistro));

                //---------------------------------------------
                // Dati relativi al dipendente, pensionato o altro percettore delle somme
                //---------------------------------------------

                // Codice Fiscale
                sb.Append(getCampoNonPosizionale("DA002001", fornitore.GetCodiceFiscale().ToUpper(), AllineamentoCaratteri.Sinistro));

                // Cognome
                sb.Append(getCampoNonPosizionale("DA002002", cognomeFornitore.ToUpper(), AllineamentoCaratteri.Sinistro));

                // Nome
                sb.Append(getCampoNonPosizionale("DA002003", nomeFornitore.ToUpper(), AllineamentoCaratteri.Sinistro));

                // Sesso 
                sb.Append(getCampoNonPosizionale("DA002004", sessoFornitore, AllineamentoCaratteri.Sinistro));

                // Data di nascita
                sb.Append(getCampoNonPosizionale("DA002005", dataNascitaFornitore, AllineamentoCaratteri.Destro));

                if (fornitore.PersonaRiferimento.ComuneNascita != null)
                {
                    // Comune (o Stato estero) di nascita
                    sb.Append(getCampoNonPosizionale("DA002006", fornitore.PersonaRiferimento.ComuneNascita.Descrizione, AllineamentoCaratteri.Sinistro));

                    // Provincia di nascita (sigla) 
                    sb.Append(getCampoNonPosizionale("DA002007", getSiglaProvincia(fornitore.PersonaRiferimento.ComuneNascita), AllineamentoCaratteri.Sinistro));
                }

                // Domicilio fiscale al 1/1/2014
                // -----------------------------

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

                // Provincia (sigla) 
                sb.Append(getCampoNonPosizionale("DA002021", getSiglaProvincia(fornitore.PersonaRiferimento.IndirizzoResidenza.Comune), AllineamentoCaratteri.Sinistro));

                // Codice comune 
                sb.Append(getCampoNonPosizionale("DA002022", fornitore.PersonaRiferimento.IndirizzoResidenza.Comune.CodiceCatastale, AllineamentoCaratteri.Sinistro));


                // Domicilio fiscale al 1/1/2015
                // -----------------------------

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

                // Provincia (sigla) 
                sb.Append(getCampoNonPosizionale("DA002024", getSiglaProvincia(fornitore.PersonaRiferimento.IndirizzoResidenza.Comune), AllineamentoCaratteri.Sinistro));

                // Codice comune 
                sb.Append(getCampoNonPosizionale("DA002025", fornitore.PersonaRiferimento.IndirizzoResidenza.Comune.CodiceCatastale, AllineamentoCaratteri.Sinistro));

                // Sezione Firma Certificazione Unica
                // -----------------------------

                // Data Firma Sostituto d'imposta
                sb.Append(getCampoNonPosizionale("DA003001", convertData(dataDichiarazione), AllineamentoCaratteri.Destro));

                // Firma 
                sb.Append(getCampoNonPosizionale("DA003002", "1".PadLeft(16), 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 D per il modello Certificazione Unica - {0} - condominio:{1}", ex, Library.Utility.GetMethodDescription(), condominio.ID);
                throw;
        /// <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;
            }
        private string checkFornitore(Fornitore fornitore)
        {
            var message = string.Empty;

            if (fornitore.PersonaRiferimento.IndirizzoResidenza == null)
                message += "Per il fornitore " + fornitore.DisplayName + " non è presente l'<b>INDIRIZZO</b>." + Environment.NewLine;
            else
            {
                if (fornitore.PersonaRiferimento.IndirizzoResidenza.Comune == null)
                    message += "Per il fornitore " + fornitore.DisplayName + " non è presente il <b>COMUNE DI RESIDENZA</b>." + Environment.NewLine;
                if (string.IsNullOrEmpty(fornitore.PersonaRiferimento.IndirizzoResidenza.Indirizzo))
                    message += "Per il fornitore " + fornitore.DisplayName + " non è presente l'<b>INDIRIZZO</b>." + Environment.NewLine;
            }

            if (string.IsNullOrEmpty(fornitore.CodiceTributo))
                message += "Per il fornitore " + fornitore.DisplayName + " non è presente il <b>CODICE TRIBUTO</b>." + Environment.NewLine;

            if (string.IsNullOrEmpty(fornitore.GetCodiceFiscale()))
                message += "Per il fornitore " + fornitore.DisplayName + " non è presente il <b>CODICE FISCALE</b>." + Environment.NewLine;

            if (fornitore.PersonaRiferimento.TipoPersona == null || fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Undefined)
                message += "Per il fornitore " + fornitore.DisplayName + " non è presente il <b>TIPO DI PERSONA (fisica o giuridica)</b>." + Environment.NewLine;
            else if (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Fisica)
            {
                if (string.IsNullOrEmpty(fornitore.PersonaRiferimento.Cognome))
                    message += "Per il fornitore " + fornitore.DisplayName + " non è presente il <b>COGNOME</b>." + Environment.NewLine;
                if (string.IsNullOrEmpty(fornitore.PersonaRiferimento.Nome))
                    message += "Per il fornitore " + fornitore.DisplayName + " non è presente il <b>NOME</b>." + Environment.NewLine;
                if (fornitore.PersonaRiferimento.Sesso.GetValueOrDefault() == SessoEnum.Undefined)
                    message += "Per il fornitore " + fornitore.DisplayName + " non è presente il <b>SESSO</b>." + Environment.NewLine;
                if (fornitore.PersonaRiferimento.ComuneNascita == null)
                    message += "Per il fornitore " + fornitore.DisplayName + " non è presente il <b>COMUNE DI NASCITA</b>." + Environment.NewLine;
                if (fornitore.PersonaRiferimento.DataNascita == null)
                    message += "Per il fornitore " + fornitore.DisplayName + " non è presente la <b>DATA DI NASCITA</b>." + Environment.NewLine;
            }
            else if (fornitore.PersonaRiferimento.TipoPersona.GetValueOrDefault() == TipoPersonaEnum.Giuridica)
            {
                if (string.IsNullOrEmpty(fornitore.PersonaRiferimento.RagioneSociale))
                    message += "Per il fornitore " + fornitore.DisplayName + " non è presente la <b>RAGIONE SOCIALE</b>." + Environment.NewLine;
                if (!string.IsNullOrEmpty(fornitore.GetCodiceFiscale()))
                {
                    System.Numerics.BigInteger num;
                    if (!System.Numerics.BigInteger.TryParse(fornitore.GetCodiceFiscale(), out num))
                        message += $"Per il fornitore {fornitore.DisplayName} il <b>CODICE FISCALE</b>. {fornitore.GetCodiceFiscale()} non è corretto per le persone giuridiche il codice fiscale deve essere <b>NUMERICO</b>.{Environment.NewLine}";
                }
            }

            return message;
        }