using System; using System.Collections.Generic; using System.Data.OleDb; using Dapper; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using NfProcessorApp.Domain.Entities; using NfProcessorApp.Domain.Repositories; using NfProcessorApp.Handlers; using NfProcessorApp.Infrastructure; namespace NfProcessorApp.Infrastructure { /// /// Implementação de INotaFiscalRepository usando banco Access /// public class AccessRepository : ITERepository, IDatabaseUpdater { private readonly string _connectionString; private readonly ILogger _logger; public AccessRepository(IConfiguration config, ILogger logger) { ArgumentNullException.ThrowIfNull(config); ArgumentNullException.ThrowIfNull(logger); _connectionString = config.GetConnectionString("AccessDb") ?? throw new InvalidOperationException("Connection string 'AccessDb' não configurada."); _logger = logger; } public IEnumerable ObterCandidatos(string cnpjComprador, string cnpjVendedor) { const string sql = @" SELECT Mont_LO AS Mont_LO, Prec_LO AS Prec_LO, NF_c_ICMS AS NF_c_ICMS, Hora_NF AS Data FROM Dados_TE DT INNER JOIN Dados_Cadastrais DC ON DT.Cod_smart_unidade = DC.Cod_smart_unidade WHERE DC.CNPJ_comp = @CNPJ_comp AND DC.CNPJ_vend = @CNPJ_vend ORDER BY Hora_NF DESC"; try { using var conn = new OleDbConnection(_connectionString); return conn.Query(sql, new { CNPJ_comp = cnpjComprador, CNPJ_vend = cnpjVendedor }); } catch (Exception ex) { _logger.LogError(ex, "Erro obtendo candidatos com Dapper para {CNPJ_comp}/{CNPJ_vend}", cnpjComprador, cnpjVendedor); #pragma warning disable IDE0301 // Simplificar a inicialização de coleção return Array.Empty(); #pragma warning restore IDE0301 // Simplificar a inicialização de coleção } } public void MarcarComoCorreta(string cod_TE, string numeroNF, DateTime dataVerificacao, string caminhoDestino) { const string sql = @" UPDATE Dados_Cadastrais SET Numero_NF = @Numero_NF, NF_Correta = TRUE, Hora_NF = @Hora_NF, Caminho_NFs = @Caminho_NFs WHERE Cod_TE = @Cod_TE"; try { using var conn = new OleDbConnection(_connectionString); var affected = conn.Execute(sql, new { Cod_TE = cod_TE, Numero_NF = numeroNF, Hora_NF = dataVerificacao, Caminho_NFs = caminhoDestino }); _logger.LogInformation("Registros atualizados: {AffectedRows}", affected); } catch (Exception ex) { _logger.LogError(ex, "Erro ao marcar NF como correta com Dapper para Cod_TE {cod_TE}", cod_TE); } } public string ObterCaminhoDestino(string cnpjComprador) { const string sql = @" SELECT Caminho_NFs FROM Dados_Cadastrais WHERE CNPJ_CPF = @CNPJ_comp"; try { using var conn = new OleDbConnection(_connectionString); return conn.QueryFirstOrDefault(sql, new { CNPJ_comp = cnpjComprador }) ?? string.Empty; } catch (Exception ex) { _logger.LogError(ex, "Erro ao obter caminho de destino para o cliente com CNPJ {CNPJ}", cnpjComprador); return string.Empty; } } /// public void Update(NFResult result) { ArgumentNullException.ThrowIfNull(result); // Data de verificação = momento atual var dataVerificacao = DateTime.Now; // Obtém caminho de destino usando o CNPJ do vendedor var caminhoDestino = ObterCaminhoDestino(result.CNPJ_Vendedor); var candidatos = ObterCandidatos(result.CNPJ_Comprador, result.CNPJ_Vendedor); // Chama o método de marcação usando Cod_TE e NumeroNF do resultado MarcarComoCorreta( cod_TE: candidatos.First().Cod_TE.ToString(), numeroNF: result.NumeroNF, dataVerificacao: dataVerificacao, caminhoDestino: caminhoDestino ); } } }