using System; using System.Threading.Tasks; using Compliance.Domain.Models; using Compliance.DTOs; using Compliance.Infrastructure.Repositories; using System.Text; namespace Compliance.Services.ValidationRules { public class TaxValidationRule(IDistributorRepository distributorRepository) : IValidationRule { private readonly IDistributorRepository _distributorRepository = distributorRepository; private const string RULE_NAME = "Tax Validation"; private const string PIS_ERROR = "PIS amount doesn't match the expected value. "; private const string COFINS_ERROR = "COFINS amount doesn't match the expected value."; private const decimal TOLERANCE = 0.01m; public int Priority => 2; public async Task ValidateAsync( BillComplianceRequest request, DistributorInformation distributorInfo, Client clientInfo) { var taxInfo = await _distributorRepository.GetTaxInformationAsync( request.DistributorName, request.Month) ?? throw new InvalidOperationException("Tax information not found"); var isValid = true; var message = new StringBuilder(); var totalBeforeTaxes = request.TUSDAmount + request.TEAmount; var expectedPIS = totalBeforeTaxes * (distributorInfo.PISPercentage / 100); var expectedCOFINS = totalBeforeTaxes * (distributorInfo.COFINSPercentage / 100); if (Math.Abs(request.PISAmount - expectedPIS) > TOLERANCE) { isValid = false; message.Append(PIS_ERROR); } if (request.COFINSAmount != expectedCOFINS) { isValid = false; message.Append(COFINS_ERROR); } return new ValidationResult { IsValid = isValid, RuleName = RULE_NAME, Message = message.ToString() }; } } }