diff --git a/ComplianceNFs.Core/Application/ApplicationInterfaces.cs b/ComplianceNFs.Core/Application/ApplicationInterfaces.cs index 066cd33..380c7a1 100644 --- a/ComplianceNFs.Core/Application/ApplicationInterfaces.cs +++ b/ComplianceNFs.Core/Application/ApplicationInterfaces.cs @@ -32,7 +32,7 @@ namespace ComplianceNFs.Core.Application // Handles archiving of files public interface IArchivingService { - Task ArchiveAsync(EnergyInvoice invoice, byte[] rawFile); + Task ArchiveAsync(EnergyInvoice invoice); } // For streaming invoice status updates (for Monitor) diff --git a/ComplianceNFs.Core/Application/Services/ApplicationServices.cs b/ComplianceNFs.Core/Application/Services/ApplicationServices.cs index 1b1c15a..7860686 100644 --- a/ComplianceNFs.Core/Application/Services/ApplicationServices.cs +++ b/ComplianceNFs.Core/Application/Services/ApplicationServices.cs @@ -92,24 +92,15 @@ namespace ComplianceNFs.Core.Application.Services } // Handles matching logic for invoices - public class MatchingService : IMatchingService + public class MatchingService(IAccessDbRepository accessDbRepository, ILogger logger) : IMatchingService { - private readonly IAccessDbRepository _accessDbRepository; - private readonly ILogger _logger; - - public MatchingService(IAccessDbRepository accessDbRepository, ILogger logger) - { - _accessDbRepository = accessDbRepository; - _logger = logger; - } - public Task MatchAsync(EnergyInvoice invoice) { try { - _logger.LogInformation("Matching invoice {InvoiceId}", invoice.InvoiceId); + logger.LogInformation("Matching invoice {InvoiceId}", invoice.InvoiceId); // Example: Primary match logic (simplified) - var records = _accessDbRepository.GetByCnpj(invoice.CnpjComp ?? throw new ArgumentNullException("CnpjComp is required")); + var records = accessDbRepository.GetByCnpj(invoice.CnpjComp ?? throw new ArgumentNullException(null, nameof(invoice.CnpjComp))); if (records == null || records.ToList().Count == 0) { invoice.Status = InvoiceStatus.NotFound; @@ -164,7 +155,7 @@ namespace ComplianceNFs.Core.Application.Services } catch (Exception ex) { - _logger.LogError(ex, "Error matching invoice {InvoiceId}", invoice.InvoiceId); + logger.LogError(ex, "Error matching invoice {InvoiceId}", invoice.InvoiceId); throw; } return Task.CompletedTask; @@ -211,9 +202,10 @@ namespace ComplianceNFs.Core.Application.Services { private readonly IFileArchiver _fileArchiver = fileArchiver; - public Task ArchiveAsync(EnergyInvoice invoice, byte[] rawFile) + public Task ArchiveAsync(EnergyInvoice invoice) { - return _fileArchiver.ArchiveAsync(invoice, rawFile); + _fileArchiver.ArchiveAsync(invoice); + return Task.CompletedTask; } } } diff --git a/ComplianceNFs.Core/Ports/DomainInterfaces.cs b/ComplianceNFs.Core/Ports/DomainInterfaces.cs index 6c8fedd..6b482eb 100644 --- a/ComplianceNFs.Core/Ports/DomainInterfaces.cs +++ b/ComplianceNFs.Core/Ports/DomainInterfaces.cs @@ -38,6 +38,6 @@ namespace ComplianceNFs.Core.Ports public interface IFileArchiver { - Task ArchiveAsync(Entities.EnergyInvoice invoice, byte[] rawFile); + void ArchiveAsync(Entities.EnergyInvoice invoice); } } diff --git a/ComplianceNFs.Infrastructure.Tests/AccessDbRepositoryTests.cs b/ComplianceNFs.Infrastructure.Tests/AccessDbRepositoryTests.cs index b21e4bd..ba36d93 100644 --- a/ComplianceNFs.Infrastructure.Tests/AccessDbRepositoryTests.cs +++ b/ComplianceNFs.Infrastructure.Tests/AccessDbRepositoryTests.cs @@ -14,7 +14,7 @@ namespace ComplianceNFs.Infrastructure.Tests { // Arrange var expected = new List { - new BuyingRecord { CodTE = 180310221018240701, CnpjComp = "06272575007403", CnpjVend = "13777004000122", MontLO = 24.72m, PrecLO = 147.29m } + new() { CodTE = 180310221018240701, CnpjComp = "06272575007403", CnpjVend = "13777004000122", MontLO = 24.72m, PrecLO = 147.29m } }; var mockRepo = new Mock(); mockRepo.Setup(r => r.GetByCnpj("06272575007403")).Returns(expected); diff --git a/ComplianceNFs.Infrastructure.Tests/ArchivingServiceTests.cs b/ComplianceNFs.Infrastructure.Tests/ArchivingServiceTests.cs index 539c8d3..a3de458 100644 --- a/ComplianceNFs.Infrastructure.Tests/ArchivingServiceTests.cs +++ b/ComplianceNFs.Infrastructure.Tests/ArchivingServiceTests.cs @@ -29,10 +29,10 @@ namespace ComplianceNFs.Infrastructure.Tests var fileBytes = new byte[] { 1, 2, 3 }; // Act - await service.ArchiveAsync(invoice, fileBytes); + await service.ArchiveAsync(invoice); // Assert - mockArchiver.Verify(a => a.ArchiveAsync(invoice, fileBytes), Times.Once); + mockArchiver.Verify(a => a.ArchiveAsync(invoice), Times.Once); } } } diff --git a/ComplianceNFs.Infrastructure.Tests/MailListenerTests.cs b/ComplianceNFs.Infrastructure.Tests/MailListenerTests.cs index c348047..8e5ae23 100644 --- a/ComplianceNFs.Infrastructure.Tests/MailListenerTests.cs +++ b/ComplianceNFs.Infrastructure.Tests/MailListenerTests.cs @@ -46,9 +46,8 @@ namespace ComplianceNFs.Infrastructure.Tests } // Expose protected method for test - private class TestableMailListener : MailListener + private class TestableMailListener(IConfiguration config, ILogger logger) : MailListener(config, logger) { - public TestableMailListener(IConfiguration config, ILogger logger) : base(config, logger) { } public new void RaiseNewMailReceivedForTest(MailMessage mail) => base.RaiseNewMailReceivedForTest(mail); } } diff --git a/ComplianceNFs.Infrastructure.Tests/MonitorViewModelTests.cs b/ComplianceNFs.Infrastructure.Tests/MonitorViewModelTests.cs index 8b4b5f5..c8f1efe 100644 --- a/ComplianceNFs.Infrastructure.Tests/MonitorViewModelTests.cs +++ b/ComplianceNFs.Infrastructure.Tests/MonitorViewModelTests.cs @@ -25,7 +25,7 @@ namespace ComplianceNFs.Infrastructure.Tests Filename = "file.xml", Status = InvoiceStatus.Validated }; - mockStream.Setup(s => s.GetRecent(It.IsAny())).Returns(new[] { testInvoice }); + mockStream.Setup(s => s.GetRecent(It.IsAny())).Returns([testInvoice]); var viewModel = new MonitorViewModel(mockStream.Object); // Assert @@ -38,7 +38,7 @@ namespace ComplianceNFs.Infrastructure.Tests { // Arrange var mockStream = new Mock(); - mockStream.Setup(s => s.GetRecent(It.IsAny())).Returns(Array.Empty()); + mockStream.Setup(s => s.GetRecent(It.IsAny())).Returns([]); var viewModel = new MonitorViewModel(mockStream.Object); var newInvoice = new EnergyInvoice { diff --git a/ComplianceNFs.Infrastructure.Tests/ServiceLogicTests.cs b/ComplianceNFs.Infrastructure.Tests/ServiceLogicTests.cs index d993159..e07aaab 100644 --- a/ComplianceNFs.Infrastructure.Tests/ServiceLogicTests.cs +++ b/ComplianceNFs.Infrastructure.Tests/ServiceLogicTests.cs @@ -55,8 +55,8 @@ namespace ComplianceNFs.Infrastructure.Tests var mockLogger = new Mock>(); var invoice = new EnergyInvoice { CnpjComp = "123", CnpjVend = "456", MontNF = 300, PrecNF = 600, MailId = "m", ConversationId = "c", SupplierEmail = "s", ReceivedDate = DateTime.Now, InvoiceId = 1, Filename = "f.xml" }; var records = new List { - new BuyingRecord { CnpjComp = "123", CnpjVend = "456", MontLO = 100, PrecLO = 200, CodTE = 1 }, - new BuyingRecord { CnpjComp = "123", CnpjVend = "456", MontLO = 200, PrecLO = 400, CodTE = 2 } + new() { CnpjComp = "123", CnpjVend = "456", MontLO = 100, PrecLO = 200, CodTE = 1 }, + new() { CnpjComp = "123", CnpjVend = "456", MontLO = 200, PrecLO = 400, CodTE = 2 } }; mockRepo.Setup(r => r.GetByCnpj("123")).Returns(records); var service = new MatchingService(mockRepo.Object, mockLogger.Object); @@ -87,8 +87,8 @@ namespace ComplianceNFs.Infrastructure.Tests Filename = "f.xml" }; var records = new List { - new BuyingRecord { CnpjComp = "123", CnpjVend = "456", MontLO = 100, PrecLO = 200, CodTE = 1 }, - new BuyingRecord { CnpjComp = "123", CnpjVend = "456", MontLO = 200, PrecLO = 400, CodTE = 2 } + new() { CnpjComp = "123", CnpjVend = "456", MontLO = 100, PrecLO = 200, CodTE = 1 }, + new() { CnpjComp = "123", CnpjVend = "456", MontLO = 200, PrecLO = 400, CodTE = 2 } }; mockRepo.Setup(r => r.GetByCnpj("123")).Returns(records); var service = new MatchingService(mockRepo.Object, mockLogger.Object); diff --git a/ComplianceNFs.Infrastructure.Tests/UnitTest1.cs b/ComplianceNFs.Infrastructure.Tests/UnitTest1.cs index ee1610c..5da3626 100644 --- a/ComplianceNFs.Infrastructure.Tests/UnitTest1.cs +++ b/ComplianceNFs.Infrastructure.Tests/UnitTest1.cs @@ -34,7 +34,7 @@ namespace ComplianceNFs.Infrastructure.Tests }; var data = new byte[] { 1, 2, 3, 4 }; - await archiver.ArchiveAsync(invoice, data); + archiver.ArchiveAsync(invoice); var expectedFolder = Path.Combine(_testBasePath, "Validated"); var expectedFile = Path.Combine(expectedFolder, "testfile.txt"); @@ -59,11 +59,10 @@ namespace ComplianceNFs.Infrastructure.Tests ReceivedDate = DateTime.Now, InvoiceId = 1 }; - var data1 = new byte[] { 1, 2, 3 }; var data2 = new byte[] { 9, 8, 7 }; - await archiver.ArchiveAsync(invoice, data1); - await archiver.ArchiveAsync(invoice, data2); + archiver.ArchiveAsync(invoice); + archiver.ArchiveAsync(invoice); var expectedFile = Path.Combine(_testBasePath, "Validated", "testfile.txt"); var fileData = await File.ReadAllBytesAsync(expectedFile); @@ -74,6 +73,7 @@ namespace ComplianceNFs.Infrastructure.Tests { if (Directory.Exists(_testBasePath)) Directory.Delete(_testBasePath, true); + GC.SuppressFinalize(this); } } diff --git a/ComplianceNFs.Infrastructure/Archiving/FileArchiver.cs b/ComplianceNFs.Infrastructure/Archiving/FileArchiver.cs index 415323f..eab3d49 100644 --- a/ComplianceNFs.Infrastructure/Archiving/FileArchiver.cs +++ b/ComplianceNFs.Infrastructure/Archiving/FileArchiver.cs @@ -12,8 +12,9 @@ namespace ComplianceNFs.Infrastructure.Archiving { private readonly string _basePath = basePath; - public async Task ArchiveAsync(EnergyInvoice invoice, byte[] rawFile) + public void ArchiveAsync(EnergyInvoice invoice) { + var sourceFile = Path.Combine(_basePath, invoice.Filename); // Create subfolder for invoice.Status var statusFolder = Path.Combine(_basePath, invoice.Status.ToString()); if (!Directory.Exists(statusFolder)) @@ -23,7 +24,7 @@ namespace ComplianceNFs.Infrastructure.Archiving // Build file path var filePath = Path.Combine(statusFolder, invoice.Filename); // Write file (overwrite if exists) - await File.WriteAllBytesAsync(filePath, rawFile); + File.Move(sourceFile, filePath); } } } diff --git a/ComplianceNFs.Infrastructure/Repositories/AttachmentRepository.cs b/ComplianceNFs.Infrastructure/Repositories/AttachmentRepository.cs index d17760c..bafd747 100644 --- a/ComplianceNFs.Infrastructure/Repositories/AttachmentRepository.cs +++ b/ComplianceNFs.Infrastructure/Repositories/AttachmentRepository.cs @@ -10,22 +10,13 @@ using Microsoft.Extensions.Logging; namespace ComplianceNFs.Infrastructure.Repositories { // Placeholder: fill in actual SQL and mapping logic - public class AttachmentRepository : IAttachmentRepository + public class AttachmentRepository(string connectionString, ILogger logger) : IAttachmentRepository { - private readonly string _connectionString; - private readonly ILogger _logger; - - public AttachmentRepository(string connectionString, ILogger logger) - { - _connectionString = connectionString; - _logger = logger; - } - public async Task SaveRawAsync(EnergyInvoice invoice) { try { - using var conn = new NpgsqlConnection(_connectionString); + using var conn = new NpgsqlConnection(connectionString); await conn.OpenAsync(); var cmd = conn.CreateCommand(); cmd.CommandText = @"INSERT INTO attachments ( @@ -55,11 +46,11 @@ namespace ComplianceNFs.Infrastructure.Repositories cmd.Parameters.AddWithValue("@discrepancy", (object?)invoice.DiscrepancyNotes ?? DBNull.Value); cmd.Parameters.AddWithValue("@metadata", Newtonsoft.Json.JsonConvert.SerializeObject(invoice)); await cmd.ExecuteNonQueryAsync(); - _logger.LogInformation("Saved raw invoice {InvoiceId} to attachments table.", invoice.InvoiceId); + logger.LogInformation("Saved raw invoice {InvoiceId} to attachments table.", invoice.InvoiceId); } catch (Exception ex) { - _logger.LogError(ex, "Error saving raw invoice {InvoiceId} to attachments table.", invoice.InvoiceId); + logger.LogError(ex, "Error saving raw invoice {InvoiceId} to attachments table.", invoice.InvoiceId); throw; } } @@ -68,7 +59,7 @@ namespace ComplianceNFs.Infrastructure.Repositories { try { - using var conn = new NpgsqlConnection(_connectionString); + using var conn = new NpgsqlConnection(connectionString); await conn.OpenAsync(); var cmd = conn.CreateCommand(); cmd.CommandText = @"UPDATE attachments SET matched_cod_te = @matched_cod_te, status = @status, discrepancy = @discrepancy WHERE invoice_id = @invoice_id"; @@ -77,11 +68,11 @@ namespace ComplianceNFs.Infrastructure.Repositories cmd.Parameters.AddWithValue("@discrepancy", (object?)notes ?? DBNull.Value); cmd.Parameters.AddWithValue("@invoice_id", invoiceId); await cmd.ExecuteNonQueryAsync(); - _logger.LogInformation("Updated match for invoice {InvoiceId}.", invoiceId); + logger.LogInformation("Updated match for invoice {InvoiceId}.", invoiceId); } catch (Exception ex) { - _logger.LogError(ex, "Error updating match for invoice {InvoiceId}.", invoiceId); + logger.LogError(ex, "Error updating match for invoice {InvoiceId}.", invoiceId); throw; } } diff --git a/ComplianceNFs.Monitor/MainWindow.xaml.cs b/ComplianceNFs.Monitor/MainWindow.xaml.cs index fc84358..c843c6e 100644 --- a/ComplianceNFs.Monitor/MainWindow.xaml.cs +++ b/ComplianceNFs.Monitor/MainWindow.xaml.cs @@ -32,6 +32,6 @@ namespace ComplianceNFs.Monitor public class DummyStatusStream : IInvoiceStatusStream { public event Action? StatusUpdated { add { } remove { } } - public IEnumerable GetRecent(int count = 100) => Array.Empty(); + public IEnumerable GetRecent(int count = 100) => []; } } \ No newline at end of file diff --git a/ComplianceNFs.Service/Worker.cs b/ComplianceNFs.Service/Worker.cs index 7c8ec5e..128d02e 100644 --- a/ComplianceNFs.Service/Worker.cs +++ b/ComplianceNFs.Service/Worker.cs @@ -44,7 +44,7 @@ public class Worker(ILogger logger, } // 4. Archive // (Assume raw file is available or can be loaded if needed) - // await _archivingService.ArchiveAsync(invoice, rawFile); + await _archivingService.ArchiveAsync(invoice); _logger.LogInformation("Invoice {NumeroNF} processed with status: {Status}", invoice.NumeroNF, invoice.Status); } catch (Exception ex)