faturas_4docs/Compliance/Services/ValidationRules/TariffComponentValidationRule.cs

89 lines
3.4 KiB
C#

using System;
using System.Threading.Tasks;
using System.Text;
using Compliance.Domain.Models;
using Compliance.DTOs;
using Compliance.Infrastructure.Repositories;
namespace Compliance.Services.ValidationRules
{
public class TariffComponentValidationRule(IDistributorRepository distributorRepository) : IValidationRule
{
private readonly IDistributorRepository _distributorRepository = distributorRepository;
private const string RULE_NAME = "Tariff Component Validation";
private const string TUSD_ERROR = "TUSD amount doesn't match the expected value";
private const string TE_ERROR = "TE amount doesn't match the expected value";
private const string POWER_FACTOR_ERROR = "Power factor adjustment is incorrect";
private const decimal TOLERANCE = 0.01m;
private const decimal MIN_POWER_FACTOR = 0.92m;
public int Priority => 3; // Run after consumption validation
public async Task<ValidationResult> ValidateAsync(
BillComplianceRequest request,
DistributorInformation distributorInfo,
Client clientInfo)
{
var tariffInfo = await _distributorRepository.GetTariffInformationAsync(
request.DistributorName,
request.Month) ?? throw new InvalidOperationException("Tariff information not found");
var isValid = true;
var message = new StringBuilder();
// Validate TUSD calculation
var expectedTUSD = request.ConsumptionAmount * tariffInfo.TUSDValue;
if (Math.Abs(request.TUSDAmount - expectedTUSD) > TOLERANCE)
{
isValid = false;
message.AppendLine(TUSD_ERROR);
}
// Validate TE calculation
var expectedTE = request.ConsumptionAmount * tariffInfo.TEValue;
if (Math.Abs(request.TEAmount - expectedTE) > TOLERANCE)
{
isValid = false;
message.AppendLine(TE_ERROR);
}
// Validate power factor adjustment if applicable
if (request.PowerFactor < MIN_POWER_FACTOR)
{
var powerFactorAdjustment = CalculatePowerFactorAdjustment(
request.ConsumptionAmount,
request.PowerFactor,
tariffInfo);
if (Math.Abs(request.PowerFactorAdjustment - powerFactorAdjustment) > TOLERANCE)
{
isValid = false;
message.AppendLine(POWER_FACTOR_ERROR);
}
}
else if (request.PowerFactorAdjustment != 0)
{
isValid = false;
message.AppendLine("Power factor adjustment should be zero when power factor is above minimum");
}
return new ValidationResult
{
IsValid = isValid,
RuleName = RULE_NAME,
Message = message.ToString().TrimEnd()
};
}
private static decimal CalculatePowerFactorAdjustment(
decimal consumption,
decimal powerFactor,
TariffInformation tariffInfo)
{
if (powerFactor >= MIN_POWER_FACTOR)
return 0;
var adjustment = (MIN_POWER_FACTOR / powerFactor - 1) * 100;
return consumption * (tariffInfo.TUSDValue + tariffInfo.TEValue) * adjustment / 100;
}
}
}