faturas_4docs/Compliance/Services/ValidationRules/ConsumptionValidationRule.cs

69 lines
2.7 KiB
C#

using System;
using System.Threading.Tasks;
using System.Text;
using Compliance.Domain.Models;
using Compliance.DTOs;
namespace Compliance.Services.ValidationRules
{
public class ConsumptionValidationRule : IValidationRule
{
private const string RULE_NAME = "Consumption Validation";
private const string TOTAL_ERROR = "Total amount doesn't match the sum of TUSD and TE amounts";
private const string READING_PERIOD_ERROR = "Invalid reading period";
private const string CONSUMPTION_ERROR = "Consumption amount doesn't match readings difference";
private const string PEAK_OFFPEAK_ERROR = "Total consumption doesn't match sum of peak and off-peak consumption";
private const decimal TOLERANCE = 0.01m;
private const int MAX_BILLING_DAYS = 33; // According to ANEEL Resolution
public int Priority => 2; // Run after basic validation
public async Task<ValidationResult> ValidateAsync(
BillComplianceRequest request,
DistributorInformation distributorInfo,
Client clientInfo)
{
var isValid = true;
var message = new StringBuilder();
// Validate reading period
var billingDays = (request.CurrentReadingDate - request.PreviousReadingDate).Days;
if (billingDays <= 0 || billingDays > MAX_BILLING_DAYS)
{
isValid = false;
message.AppendLine(READING_PERIOD_ERROR);
}
// Validate consumption calculation
var calculatedConsumption = request.CurrentReading - request.PreviousReading;
if (Math.Abs(calculatedConsumption - request.ConsumptionAmount) > TOLERANCE)
{
isValid = false;
message.AppendLine(CONSUMPTION_ERROR);
}
// Validate peak/off-peak total
if (Math.Abs(request.ConsumptionAmount - (request.PeakConsumption + request.OffPeakConsumption)) > TOLERANCE)
{
isValid = false;
message.AppendLine(PEAK_OFFPEAK_ERROR);
}
// Validate total amount matches sum of components
var expectedTotal = request.TUSDAmount + request.TEAmount +
request.PowerFactorAdjustment + request.PublicLightingAmount +
request.FlagAmount;
if (Math.Abs(request.TotalAmount - expectedTotal) > TOLERANCE)
{
isValid = false;
message.AppendLine(TOTAL_ERROR);
}
return await Task.FromResult(new ValidationResult
{
IsValid = isValid,
RuleName = RULE_NAME,
Message = message.ToString().TrimEnd()
});
}
}
}