IpasgoZipWriter.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. using System.IO;
  2. using System.IO.Compression;
  3. using System.Text;
  4. using AGEHAB.RelatorioSeadIpasgo.Application.Abstractions;
  5. namespace AGEHAB.RelatorioSeadIpasgo.Infrastructure.Zip;
  6. public class IpasgoZipWriter : IIpasgoZipWriter
  7. {
  8. private static readonly Dictionary<string, string> DePara = new()
  9. {
  10. ["1"] = "01",
  11. ["5026"] = "02",
  12. ["5007"] = "04",
  13. ["5050"] = "04",
  14. ["5046"] = "04",
  15. ["102"] = "06",
  16. ["104"] = "06",
  17. ["5934"] = "10",
  18. ["5"] = "13",
  19. ["200"] = "13",
  20. ["5030"] = "16",
  21. ["5101"] = "16",
  22. ["51"] = "18",
  23. ["52"] = "18",
  24. ["53"] = "18",
  25. ["41"] = "18",
  26. ["100"] = "20",
  27. ["101"] = "21",
  28. ["20"] = "22",
  29. ["110"] = "31",
  30. ["5067"] = "31",
  31. ["5009"] = "31",
  32. ["12"] = "50",
  33. ["90"] = "51",
  34. ["22"] = "53",
  35. ["23"] = "53"
  36. };
  37. public void Escrever(string referencia, IReadOnlyList<dynamic> linhas, string caminhoArquivo, CancellationToken cancellationToken)
  38. {
  39. cancellationToken.ThrowIfCancellationRequested();
  40. var remessa = MontarRemessa(linhas, cancellationToken);
  41. var nomeBase = $"REM{referencia}";
  42. var pastaTemporaria = Path.Combine(Path.GetTempPath(), "Ipasgo", Guid.NewGuid().ToString("N"));
  43. Directory.CreateDirectory(pastaTemporaria);
  44. try
  45. {
  46. var txtPath = Path.Combine(pastaTemporaria, $"{nomeBase}.txt");
  47. var zipInternoPath = Path.Combine(pastaTemporaria, Path.GetFileName(caminhoArquivo));
  48. cancellationToken.ThrowIfCancellationRequested();
  49. File.WriteAllText(txtPath, remessa, Encoding.UTF8);
  50. using (var zip = ZipFile.Open(zipInternoPath, ZipArchiveMode.Create))
  51. zip.CreateEntryFromFile(txtPath, Path.GetFileName(txtPath), CompressionLevel.Optimal);
  52. cancellationToken.ThrowIfCancellationRequested();
  53. using (var outerZip = ZipFile.Open(caminhoArquivo, ZipArchiveMode.Create))
  54. outerZip.CreateEntryFromFile(zipInternoPath, Path.GetFileName(zipInternoPath), CompressionLevel.Optimal);
  55. }
  56. finally
  57. {
  58. if (Directory.Exists(pastaTemporaria))
  59. {
  60. Directory.Delete(pastaTemporaria, true);
  61. }
  62. }
  63. }
  64. private static string MontarRemessa(IReadOnlyList<dynamic> linhas, CancellationToken cancellationToken)
  65. {
  66. var salarios = ObterSalarios(linhas, cancellationToken);
  67. var sb = new StringBuilder();
  68. var sequencial = 1;
  69. foreach (var item in salarios)
  70. {
  71. cancellationToken.ThrowIfCancellationRequested();
  72. sb.Append("10");
  73. sb.Append("8792");
  74. sb.Append(item.Cpf.PadLeft(11, '0'));
  75. sb.Append(new string(' ', 30));
  76. sb.Append("0001160");
  77. sb.Append(item.Sufixo.PadLeft(2, '0'));
  78. sb.Append("000");
  79. sb.Append(new string(' ', 50));
  80. sb.Append("00");
  81. sb.Append(new string(' ', 255));
  82. sb.Append(item.Valor.ToString("0000000000.00").Replace('.', ','));
  83. sb.Append(sequencial.ToString().PadLeft(6, '0'));
  84. sb.AppendLine();
  85. sequencial++;
  86. }
  87. sb.Append("99");
  88. sb.Append(new string(' ', 380));
  89. sb.Append(sequencial.ToString().PadLeft(6, '0'));
  90. return sb.ToString();
  91. }
  92. private static List<(string Cpf, string Sufixo, decimal Valor)> ObterSalarios(IReadOnlyList<dynamic> linhas, CancellationToken cancellationToken)
  93. {
  94. var resultado = new List<(string Cpf, string Sufixo, decimal Valor)>();
  95. foreach (var linha in linhas)
  96. {
  97. cancellationToken.ThrowIfCancellationRequested();
  98. var dict = (IDictionary<string, object>)linha;
  99. if (!dict.ContainsKey("CPF"))
  100. continue;
  101. var cpf = dict["CPF"]?.ToString();
  102. if (string.IsNullOrWhiteSpace(cpf))
  103. continue;
  104. foreach (var kv in dict)
  105. {
  106. if (kv.Key.StartsWith("R") || kv.Key.StartsWith("D"))
  107. {
  108. if (kv.Value is decimal valor && valor != 0)
  109. {
  110. var match = System.Text.RegularExpressions.Regex.Match(kv.Key, @"\d+");
  111. if (match.Success)
  112. {
  113. var codigo = match.Value.TrimStart('0');
  114. if (DePara.TryGetValue(codigo, out var sufixo))
  115. {
  116. resultado.Add((cpf, sufixo, valor));
  117. }
  118. }
  119. }
  120. }
  121. }
  122. }
  123. return resultado;
  124. }
  125. }