89 lines
3.4 KiB
C#
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;
|
|
}
|
|
}
|
|
} |