using System; using System.Collections.Generic; using System.Threading.Tasks; using Compliance.Domain.Models; using Compliance.DTOs; using Compliance.Infrastructure.Repositories; namespace Compliance.Services.ValidationRules { public class MeterReadingValidationRule : IValidationRule { private const string RULE_NAME = "Meter Reading Validation"; private const string READING_ERROR = "Invalid meter reading value"; private const string SEQUENCE_ERROR = "Current reading must be greater than previous reading"; private const string RESET_ERROR = "Meter reset not properly documented"; private const string ESTIMATION_ERROR = "Estimated reading without proper justification"; public int Priority => 1; // High priority as other validations depend on readings public Task ValidateAsync( BillComplianceRequest request, DistributorInformation distributorInfo, Client clientInfo) { var errors = new List(); ValidateReadingValues(request, errors); ValidateReadingSequence(request, errors); ValidateEstimatedReadings(request, errors); ValidateMeterReset(request, errors); return Task.FromResult(errors.Count == 0 ? ValidationResult.Success(RULE_NAME) : ValidationResult.Failure(RULE_NAME, errors)); } private static void ValidateReadingValues(BillComplianceRequest request, List errors) { if (request.CurrentReading < 0 || request.PreviousReading < 0) errors.Add($"{READING_ERROR}: Negative readings are not allowed"); } private static void ValidateReadingSequence(BillComplianceRequest request, List errors) { if (!request.IsMeterReset && request.CurrentReading < request.PreviousReading) errors.Add(SEQUENCE_ERROR); } private static void ValidateEstimatedReadings(BillComplianceRequest request, List errors) { if (request.IsEstimatedReading && string.IsNullOrEmpty(request.EstimationJustification)) errors.Add(ESTIMATION_ERROR); } private static void ValidateMeterReset(BillComplianceRequest request, List errors) { if (request.IsMeterReset && (string.IsNullOrEmpty(request.MeterResetJustification) || request.MeterResetDate == default)) { errors.Add(RESET_ERROR); } } } }