using System.IO; using System.IO.Compression; using System.Text; using AGEHAB.RelatorioSeadIpasgo.Application.Abstractions; namespace AGEHAB.RelatorioSeadIpasgo.Infrastructure.Zip; public class IpasgoZipWriter : IIpasgoZipWriter { private static readonly Dictionary DePara = new() { ["1"] = "01", ["5026"] = "02", ["5007"] = "04", ["5050"] = "04", ["5046"] = "04", ["102"] = "06", ["104"] = "06", ["5934"] = "10", ["5"] = "13", ["200"] = "13", ["5030"] = "16", ["5101"] = "16", ["51"] = "18", ["52"] = "18", ["53"] = "18", ["41"] = "18", ["100"] = "20", ["101"] = "21", ["20"] = "22", ["110"] = "31", ["5067"] = "31", ["5009"] = "31", ["12"] = "50", ["90"] = "51", ["22"] = "53", ["23"] = "53" }; public void Escrever(string referencia, IReadOnlyList linhas, string caminhoArquivo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var remessa = MontarRemessa(linhas, cancellationToken); var nomeBase = $"REM{referencia}"; var pastaTemporaria = Path.Combine(Path.GetTempPath(), "Ipasgo", Guid.NewGuid().ToString("N")); Directory.CreateDirectory(pastaTemporaria); try { var txtPath = Path.Combine(pastaTemporaria, $"{nomeBase}.txt"); var zipInternoPath = Path.Combine(pastaTemporaria, Path.GetFileName(caminhoArquivo)); cancellationToken.ThrowIfCancellationRequested(); File.WriteAllText(txtPath, remessa, Encoding.UTF8); using (var zip = ZipFile.Open(zipInternoPath, ZipArchiveMode.Create)) zip.CreateEntryFromFile(txtPath, Path.GetFileName(txtPath), CompressionLevel.Optimal); cancellationToken.ThrowIfCancellationRequested(); using (var outerZip = ZipFile.Open(caminhoArquivo, ZipArchiveMode.Create)) outerZip.CreateEntryFromFile(zipInternoPath, Path.GetFileName(zipInternoPath), CompressionLevel.Optimal); } finally { if (Directory.Exists(pastaTemporaria)) { Directory.Delete(pastaTemporaria, true); } } } private static string MontarRemessa(IReadOnlyList linhas, CancellationToken cancellationToken) { var salarios = ObterSalarios(linhas, cancellationToken); var sb = new StringBuilder(); var sequencial = 1; foreach (var item in salarios) { cancellationToken.ThrowIfCancellationRequested(); sb.Append("10"); sb.Append("8792"); sb.Append(item.Cpf.PadLeft(11, '0')); sb.Append(new string(' ', 30)); sb.Append("0001160"); sb.Append(item.Sufixo.PadLeft(2, '0')); sb.Append("000"); sb.Append(new string(' ', 50)); sb.Append("00"); sb.Append(new string(' ', 255)); sb.Append(item.Valor.ToString("0000000000.00").Replace('.', ',')); sb.Append(sequencial.ToString().PadLeft(6, '0')); sb.AppendLine(); sequencial++; } sb.Append("99"); sb.Append(new string(' ', 380)); sb.Append(sequencial.ToString().PadLeft(6, '0')); return sb.ToString(); } private static List<(string Cpf, string Sufixo, decimal Valor)> ObterSalarios(IReadOnlyList linhas, CancellationToken cancellationToken) { var resultado = new List<(string Cpf, string Sufixo, decimal Valor)>(); foreach (var linha in linhas) { cancellationToken.ThrowIfCancellationRequested(); var dict = (IDictionary)linha; if (!dict.ContainsKey("CPF")) continue; var cpf = dict["CPF"]?.ToString(); if (string.IsNullOrWhiteSpace(cpf)) continue; foreach (var kv in dict) { if (kv.Key.StartsWith("R") || kv.Key.StartsWith("D")) { if (kv.Value is decimal valor && valor != 0) { var match = System.Text.RegularExpressions.Regex.Match(kv.Key, @"\d+"); if (match.Success) { var codigo = match.Value.TrimStart('0'); if (DePara.TryGetValue(codigo, out var sufixo)) { resultado.Add((cpf, sufixo, valor)); } } } } } } return resultado; } }