69 lines
2.7 KiB
C#
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()
|
|
});
|
|
}
|
|
}
|
|
} |