/// <summary> /// Escrever campos p/ qualquer arquivo do projeto SPED (Contábil, Fiscal, Pis/Cofins) /// </summary> /// <param name="source">Objeto com os dados a serem tratados e gerados na linha do arquivo.</param> /// <param name="competenciaDeclaracao">Mês a que se referem as informações no arquivo(exceto informações extemporâneas).</param> /// <param name="tryTrim">Remove a quebra de linha no final de cada registro.</param> /// <returns>Linha de arquivo SPED escrita e formatada.</returns> public static string EscreverCampos(this object source, DateTime?competenciaDeclaracao = null, bool tryTrim = false) { var type = ObtemTipo(source); var registroAtual = ObtemRegistroAtual(type); var spedRegistroAttr = ObtemAtributoAtual(type); var dataObrigatoriedadeInicial = spedRegistroAttr?.ObrigatoriedadeInicial.ToDateTimeNullable(); var dataObrigatoriedadeFinal = spedRegistroAttr?.ObrigatoriedadeFinal.ToDateTimeNullable(); if (!competenciaDeclaracao.HasValue) { competenciaDeclaracao = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); } else { competenciaDeclaracao = new DateTime(competenciaDeclaracao.Value.Year, competenciaDeclaracao.Value.Month, 1); } var deveGerarCamposDoRegistro = VerificaObrigatoriedadeRegistro(new Tuple <DateTime?, DateTime?, DateTime>(dataObrigatoriedadeInicial, dataObrigatoriedadeFinal, competenciaDeclaracao.Value)); var listaComPropriedadesOrdenadas = ObtemListaComPropriedadesOrdenadas(type); var sb = new StringBuilder(); if (deveGerarCamposDoRegistro) { foreach (var property in listaComPropriedadesOrdenadas) { sb.Append("|"); foreach ( var spedCampoAttr in from Attribute attr in property.GetCustomAttributes(true) select attr as SpedCamposAttribute ) { if (spedCampoAttr == null) { throw new Exception( $"O campo {property.Name} no registro {registroAtual} não possui atributo SPED definido!"); } var propertyValue = RegistroBaseSped.GetPropValue(source, property.Name); var propertyValueToStringSafe = propertyValue.ToStringSafe().Trim(); var isRequired = spedCampoAttr.IsObrigatorio; var campoEscrito = propertyValueToStringSafe.EscreverCampo( new Tuple < InformationType, InformationType, bool, int, int>( ObtemTipoDoAtributo(spedCampoAttr), ObtemTipoDaPropriedade(property), isRequired, spedCampoAttr.Tamanho, spedCampoAttr.QtdCasas )); if (campoEscrito == Constants.StructuralError) { throw new Exception( $"O campo {spedCampoAttr.Ordem} - {spedCampoAttr.Campo} no Registro {registroAtual} é obrigatório e não foi informado!"); } sb.Append(campoEscrito); } } sb.Append("|"); sb.Append(Environment.NewLine); } return(tryTrim ? sb.ToString().Trim() : sb.ToString()); }
/// <summary> /// Escrever campos p/ qualquer arquivo do projeto SPED (Contábil, Fiscal, Pis/Cofins) /// </summary> /// <param name="source">Objeto com os dados a serem tratados e gerados na linha do arquivo.</param> /// <param name="competenciaDeclaracao">Mês a que se referem as informações no arquivo(exceto informações extemporâneas).</param> /// <param name="errosEncontrados">Lista com erros encontrados no processo de escrita.</param> /// <param name="tryTrim">Remove a quebra de linha no final de cada registro.</param> /// <returns>Linha de arquivo SPED escrita e formatada.</returns> public static string EscreverCampos(this object source, out string errosEncontrados, DateTime?competenciaDeclaracao = null, bool tryTrim = false) { errosEncontrados = string.Empty; var type = ObtemTipo(source); var registroAtual = ObtemRegistroAtual(type); var spedRegistroAttr = ObtemAtributoAtual(type); var dataObrigatoriedadeInicial = spedRegistroAttr != null?spedRegistroAttr.ObrigatoriedadeInicial.ToDateTimeNullable() : null; var dataObrigatoriedadeFinal = spedRegistroAttr != null?spedRegistroAttr.ObrigatoriedadeFinal.ToDateTimeNullable() : null; if (!competenciaDeclaracao.HasValue) { competenciaDeclaracao = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); } else { competenciaDeclaracao = new DateTime(competenciaDeclaracao.Value.Year, competenciaDeclaracao.Value.Month, 1); } var deveGerarCamposDoRegistro = VerificaObrigatoriedadeRegistro(new Tuple <DateTime?, DateTime?, DateTime>(dataObrigatoriedadeInicial, dataObrigatoriedadeFinal, competenciaDeclaracao.Value)); var listaComPropriedadesOrdenadas = ObtemListaComPropriedadesOrdenadas(type); var sb = new StringBuilder(); if (deveGerarCamposDoRegistro) { foreach (var property in listaComPropriedadesOrdenadas) { if (SomenteParaLeitura(property)) { continue; } sb.Append("|"); foreach ( var spedCampoAttr in from Attribute attr in property.GetCustomAttributes(true) select attr as SpedCamposAttribute ) { if (spedCampoAttr == null) { errosEncontrados += string.Format("O campo {0} no registro {1} não possui atributo SPED definido!\n", property.Name, registroAtual); } var propertyValue = RegistroBaseSped.GetPropValue(source, property.Name); var propertyValueToStringSafe = propertyValue.ToStringSafe().Trim(); var isRequired = spedCampoAttr.IsObrigatorio; var resultadoCampoEscrito = propertyValueToStringSafe.EscreverCampo( new Tuple < InformationType, InformationType, bool, int, int>( ObtemTipoDoAtributo(spedCampoAttr), ObtemTipoDaPropriedade(property), isRequired, spedCampoAttr.Tamanho, spedCampoAttr.QtdCasas )); if (resultadoCampoEscrito == Constants.StructuralError) { errosEncontrados += string.Format("O campo {0} - {1} no Registro {2} é obrigatório e não foi informado!\n", spedCampoAttr.Ordem, spedCampoAttr.Campo, registroAtual); } else { sb.Append(resultadoCampoEscrito); } } } sb.Append("|"); sb.Append(Environment.NewLine); } if (errosEncontrados.Length > 0) { errosEncontrados = string.Format("Registro {0} - Contém os seguintes erros: \n{1}", source.GetType().FullName, errosEncontrados); } return(tryTrim ? sb.ToString().Trim() : sb.ToString()); }
/// <summary> /// Escrever campos p/ qualquer arquivo do projeto SPED (Contábil, Fiscal, Pis/Cofins) /// </summary> /// <param name="source"></param> /// <param name="competenciaDeclaracao"></param> /// <returns></returns> public static string EscreverCampos(this object source, DateTime competenciaDeclaracao) { var type = source.GetType(); if (type == null) { throw new Exception("Falha ao identificar tipo do objeto!"); } // Extrai o nome do registro atual. Ex.: RegistroA001 -> Resultado: A001 var registroAtual = type.Name.Substring(type.Name.Length - 4); var spedRegistroAttr = (SpedRegistrosAttribute) Attribute.GetCustomAttribute(type, typeof(SpedRegistrosAttribute)); var deveGerarCamposDoRegistro = true; var dataObrigatoriedadeInicial = spedRegistroAttr?.ObrigatoriedadeInicial.ToDateTimeNullable(); var dataObrigatoriedadeFinal = spedRegistroAttr?.ObrigatoriedadeFinal.ToDateTimeNullable(); /* * Verifica obrigatoriedade de escrita do registro. Ex.: M225/M625 -> Obrigatório a partir de 01/10/2015 */ if (dataObrigatoriedadeInicial.HasValue && (dataObrigatoriedadeInicial.Value > competenciaDeclaracao)) { deveGerarCamposDoRegistro = false; } if (dataObrigatoriedadeFinal.HasValue && (dataObrigatoriedadeFinal.Value < competenciaDeclaracao.ObterProximoMesPrimeiroDia().AddDays(-1))) { deveGerarCamposDoRegistro = false; } /* * http://stackoverflow.com/questions/22306689/get-properties-of-class-by-order-using-reflection */ var listaComPropriedadesOrdenadas = type.GetProperties().OrderBy(p => p.GetCustomAttributes(typeof(SpedCamposAttribute), true) .Cast <SpedCamposAttribute>() .Select(a => a.Ordem) .FirstOrDefault()) .ToList(); var sb = new StringBuilder(); if (deveGerarCamposDoRegistro) { foreach (var property in listaComPropriedadesOrdenadas) { sb.Append("|"); foreach ( var spedCampoAttr in from Attribute attr in property.GetCustomAttributes(true) select attr as SpedCamposAttribute ) { if (spedCampoAttr == null) { throw new Exception( $"O campo {property.Name} no registro {registroAtual} não possui atributo SPED definido!"); } var isLiteralEnum = spedCampoAttr.Tipo == "LE"; // Literal Enum var propertyValue = RegistroBaseSped.GetPropValue(source, property.Name, isLiteralEnum); var propertyValueToStringSafe = propertyValue.ToStringSafe().Trim(); /* * INDICADORES PARA FORMATAÇÃO DOS CAMPOS NOS REGISTROS */ var isRequired = spedCampoAttr.IsObrigatorio; var isDecimal = property.PropertyType == typeof(decimal); var isNullableDecimal = property.PropertyType == typeof(decimal?); var isDateTime = property.PropertyType == typeof(DateTime); var isNullableDateTime = property.PropertyType == typeof(DateTime?); var hasValue = !string.IsNullOrEmpty(propertyValueToStringSafe) || !string.IsNullOrWhiteSpace(propertyValueToStringSafe); var propertyLength = hasValue ? propertyValueToStringSafe.Length : 0; // Verificação necessária p/ ajustes no tamanho de campos como CSTs e Indicadores. Ex.: CST PIS '1' -> Deve estar no arquivo como '01'. var isCodeOrNumberAndHasLength = (spedCampoAttr.Tipo == "C" || spedCampoAttr.Tipo == "N") && (spedCampoAttr.Tamanho > 0 && spedCampoAttr.Tamanho <= 4); var isHour = spedCampoAttr.Tipo == "H"; var onlyMonthAndYear = spedCampoAttr.Tipo == "MA"; if (isRequired && !hasValue) { throw new Exception( $"O campo {spedCampoAttr.Ordem} - {spedCampoAttr.Campo} no Registro {registroAtual} é obrigatório e não foi informado!"); } const decimal vZero = 0M; if (isRequired && isDecimal && (propertyValueToStringSafe == string.Empty || propertyValueToStringSafe.ToDecimal() == 0)) { sb.Append(vZero.ToString("N" + spedCampoAttr.QtdCasas)); } else { if (isDecimal && hasValue) { var vDecimal = Convert.ToDecimal(propertyValue).ToString("N" + spedCampoAttr.QtdCasas); sb.Append(vDecimal.ToStringSafe().Replace(".", "")); } else if (isNullableDecimal && hasValue) { var vDecimal = Convert.ToDecimal(propertyValue).ToString("N" + spedCampoAttr.QtdCasas); sb.Append(vDecimal.ToStringSafe().Replace(".", "")); } else if (isDateTime && hasValue) { sb.Append(Convert.ToDateTime(propertyValue).Date.ToString("ddMMyyyy")); } else if (isNullableDateTime && hasValue) { sb.Append(Convert.ToDateTime(propertyValue).Date.ToString("ddMMyyyy")); } else if ((isDateTime && hasValue) && isHour) { sb.Append(Convert.ToDateTime(propertyValue).Date.ToString("hhmmss")); } else if ((isDateTime && hasValue) && onlyMonthAndYear) { sb.Append(Convert.ToDateTime(propertyValue).Date.ToString("MMyyyy")); } else if ((isCodeOrNumberAndHasLength && hasValue) || (isLiteralEnum && hasValue)) { sb.Append(propertyValue.ToString().PadLeft(spedCampoAttr.Tamanho, '0')); } else { if (propertyLength > 0 && (propertyLength > spedCampoAttr.Tamanho)) { sb.Append(propertyValueToStringSafe.Substring(0, spedCampoAttr.Tamanho)); } else { sb.Append(propertyValueToStringSafe); } } } } } sb.Append("|"); sb.Append(Environment.NewLine); } return(sb.ToString()); }