Untitled
unknown
plain_text
a year ago
16 kB
12
Indexable
using KMD.Elements.MDP.ConnectionPoints.Application.Dtos.MeteringPoints;
using KMD.Elements.MDP.ConnectionPoints.Application.MeteringPointProcesses.ChangeFormulaProcess.Mappers;
using KMD.Elements.MDP.ConnectionPoints.Application.MeteringPointProcesses.Exceptions;
using KMD.Elements.MDP.ConnectionPoints.Application.Services.ExternalCommunication.ConnectionPoints;
using KMD.Elements.MDP.ConnectionPoints.Application.Services.ExternalCommunication.MeterFrames;
using KMD.Elements.MDP.ConnectionPoints.Application.Services.ExternalCommunication.MeteringPoints;
using KMD.Elements.MDP.ConnectionPoints.Application.Services.ExternalCommunication.MeteringPointsV2;
using KMD.Elements.MDP.ConnectionPoints.Contracts.ChangeFormulaProcessCommand;
using KMD.Elements.MDP.ConnectionPoints.Core.Constants.MeteringPoints;
using KMD.Elements.MDP.ConnectionPoints.Core.Exceptions;
using KMD.Elements.MDP.ConnectionPoints.Models.Models.MeteringPointIds;
using KMD.Elements.MDP.ConnectionPoints.Models.Models.MeteringPointProcesses.ValueObjects;
using SupplyType = KMD.Elements.MDP.ConnectionPoints.Models.Models.Common.Enums.SupplyType;
namespace KMD.Elements.MDP.ConnectionPoints.Application.MeteringPointProcesses.ChangeFormulaProcess.Commands.StartChangeFormulaProcess;
public class ChangeFormulaProcessCommandFactory(
IMeterFramesService meterFramesService,
IConnectionPointsService connectionPointsService,
IMeteringPointsV2Service meteringPointsService,
IMeteringPointsService electricityMeteringPointsService)
: IChangeFormulaProcessCommandFactory
{
private ChangeFormulaPayloadBuilder _payloadBuilder = null!;
private string? _oldSubtypeOfMeteringPoint = null;
public async Task<StartChangeFormulaProcess> CreateAsync(
ChangeFormulaProcessCommandPayload payload,
DateTime timestamp,
CancellationToken cancellationToken)
{
_payloadBuilder = new ChangeFormulaPayloadBuilder(
payload.MeteringPointVersionId,
payload.ValidFrom,
payload.ProcessId ?? Guid.NewGuid(),
payload.StartedBy,
payload.OnBehalfOf,
DateTime.UtcNow,
ChangeFormulaParentProcessMapper.Map(payload.ParentProcess));
var meteringPointId = MeteringPointIdGenerator.ExtractMeteringPointId(payload.MeteringPointVersionId);
//if (meteringPointId.SupplyType == SupplyType.Electricity)
//{
// throw new NotSupportedException($"SupplyType {meteringPointId.SupplyType} is not supported");
//}
await BuildUpdatePayload(meteringPointId.Id, meteringPointId.SupplyType, payload, cancellationToken);
var formulaPayload = await GetFormulaPayload(payload.MeteringPointVersionId, meteringPointId.SupplyType, cancellationToken);
await BuildFormulaPayload(payload, formulaPayload, meteringPointId.SupplyType, cancellationToken);
return _payloadBuilder.Build();
}
private async Task BuildUpdatePayload(
string meteringPointId,
SupplyType supplyType,
ChangeFormulaProcessCommandPayload payload,
CancellationToken cancellationToken)
{
switch (supplyType)
{
case SupplyType.Water:
await BuildUpdatePayloadForWater(meteringPointId, payload, cancellationToken);
break;
case SupplyType.Heating:
await BuildUpdatePayloadForHeating(meteringPointId, payload, cancellationToken);
break;
case SupplyType.Electricity:
await BuildUpdatePayloadForElectricity(meteringPointId, payload, cancellationToken);
break;
}
}
private async Task BuildFormulaPayload(
ChangeFormulaProcessCommandPayload payload,
FormulaVersionDto? oldFormula,
SupplyType supplyType,
CancellationToken cancellationToken)
{
if (oldFormula is null)
{
_payloadBuilder.WithFormula(payload.Formula);
return;
}
if (!payload.Formula.IsSimpleFormula && !HasVirtualFormulaChanged(payload, oldFormula))
{
return;
}
if (payload.Formula.IsSimpleFormula && payload.Formula.MeterFrameId == oldFormula.MeterFrameId && payload.Formula.RegisterRequirementId == oldFormula.RegisterRequirementId)
{
return;
}
if (payload.Formula.MeterFrameId != oldFormula.MeterFrameId)
{
var meter = await BuildMeterPayload(payload, cancellationToken) ?? GetDefaultMeterData(supplyType);
_payloadBuilder.WithMeterPayload(meter);
}
else if (payload.Formula.RegisterRequirementId != oldFormula.RegisterRequirementId)
{
var meter = await BuildMeterPayload(payload, cancellationToken) ?? GetDefaultMeterData(supplyType);
_payloadBuilder.WithMeterInUpdatePayload(meter);
}
_payloadBuilder.WithFormula(payload.Formula);
}
private static bool HasVirtualFormulaChanged(
ChangeFormulaProcessCommandPayload payload,
FormulaVersionDto oldFormula)
{
if (payload.Formula.FormulaExpression != oldFormula.Formula)
{
return true;
}
if (payload.Formula.FormulaParameters == null && oldFormula.FormulaParameters == null)
{
return false;
}
if (payload.Formula.FormulaParameters == null || oldFormula.FormulaParameters == null)
{
return true;
}
if (payload.Formula.FormulaParameters.Count != oldFormula.FormulaParameters.Count)
{
return true;
}
var newFormulaParameters = payload.Formula.FormulaParameters.OrderBy(x => x.Name).ToList();
var oldFormulaParameters = oldFormula.FormulaParameters.OrderBy(x => x.Name).ToList();
return newFormulaParameters.Where((x, y) => AreFormulaParametersDifferent(x, oldFormulaParameters[y])).Any();
}
private static bool AreFormulaParametersDifferent(FormulaParameter newFormula, FormulaParameterDto oldFormula)
=> newFormula.Name != oldFormula.Name ||
newFormula.FormulaParameterType.ToString() != oldFormula.FormulaParameterType.ToString() ||
newFormula.Description != oldFormula.Description ||
newFormula.MeteringPointTypeCode != oldFormula.MeteringPointTypeCode;
private async Task<MeterUpdatePayload?> BuildMeterPayload(ChangeFormulaProcessCommandPayload payload, CancellationToken cancellationToken)
{
var meterFrameId = payload.Formula.MeterFrameId!.Value;
var registerRequirementId = payload.Formula.RegisterRequirementId!.Value;
var meterInformation = await meterFramesService.GetMeterInformationByMeterFrameRegisterRequirementAsync(
meterFrameId,
registerRequirementId,
cancellationToken);
if (string.IsNullOrEmpty(payload.SubTypeOfMeteringPoint)!)
{
if (payload.SubTypeOfMeteringPoint != _oldSubtypeOfMeteringPoint)
{
var functionCode = GetFunctionCode(_oldSubtypeOfMeteringPoint, payload.SubTypeOfMeteringPoint);
return new MeterUpdatePayload()
{
ConversionFactor = meterInformation!.ConversionFactor,
NumberOfDigits = meterInformation.NumberOfDigits,
UnitType = meterInformation.UnitType,
MeterNumber = meterInformation.MeterNumber,
MeterReadingType = meterInformation.MeterReadingType,
Function = functionCode,
SubtypeOfMeteringPoint = payload.SubTypeOfMeteringPoint
};
}
return null;
}
if (meterInformation is null)
{
return null;
}
return new MeterUpdatePayload()
{
ConversionFactor = meterInformation!.ConversionFactor,
NumberOfDigits = meterInformation.NumberOfDigits,
UnitType = meterInformation.UnitType,
MeterNumber = meterInformation.MeterNumber,
MeterReadingType = meterInformation.MeterReadingType
};
}
private string? GetFunctionCode(string? oldSubtypeOfMeteringPoint, string? newSubTypeOfMeteringPoint)
{
if ((oldSubtypeOfMeteringPoint == SubTypesOfMeteringPoint.D02_Virtual || oldSubtypeOfMeteringPoint == SubTypesOfMeteringPoint.D03_Calculated) &&
newSubTypeOfMeteringPoint == SubTypesOfMeteringPoint.D01_Physical)
{
return "2";
}
if ((newSubTypeOfMeteringPoint == SubTypesOfMeteringPoint.D02_Virtual || newSubTypeOfMeteringPoint == SubTypesOfMeteringPoint.D03_Calculated) &&
oldSubtypeOfMeteringPoint == SubTypesOfMeteringPoint.D01_Physical)
{
return "3";
}
return null;
}
private static MeterUpdatePayload GetDefaultMeterData(SupplyType supplyType)
=> new()
{
ConversionFactor = 1,
NumberOfDigits = "1",
UnitType = supplyType is SupplyType.Water ? "M3" : "MWH",
MeterNumber = "FIKTIV",
MeterReadingType = "D01"
};
private async Task BuildUpdatePayloadForWater(
string meteringPointId,
ChangeFormulaProcessCommandPayload payload,
CancellationToken cancellationToken)
{
var meteringPointVersion = await meteringPointsService.GetWaterMeteringPointVersionAsync(meteringPointId, cancellationToken);
if (meteringPointVersion == null)
{
throw new MeteringPointNotFoundException($"Metering point with id {meteringPointId} not found in Metering Points domain.");
}
if (meteringPointVersion.ConnectionPointId is null)
{
throw new MeteringPointProcessValidationException("Connection point id is missing on metering point.");
}
var connectionPointNumber = await GetConnectionPointNumber(meteringPointVersion.ConnectionPointId.Value, cancellationToken);
if (connectionPointNumber is null)
{
throw new MeteringPointProcessValidationException("Connection point number is missing on metering point.");
}
_payloadBuilder.WithUnitType(payload.UnitType, meteringPointVersion.ProductUnitType)
.WithMeterReadingOccurrence(payload.MeterReadingOccurrence, meteringPointVersion.MeterReadingOccurrence)
.WithConnectionPointId(meteringPointVersion.ConnectionPointId!.Value)
.WithNoMeterAndMeterSize(meteringPointVersion.NoMeter, meteringPointVersion.MeterSize)
.WithConnectionPointNumber(connectionPointNumber)
.WithTypeOfMeteringPoint(meteringPointVersion.TypeOfMeteringPoint!);
}
private async Task BuildUpdatePayloadForHeating(
string meteringPointId,
ChangeFormulaProcessCommandPayload payload,
CancellationToken cancellationToken)
{
var meteringPointVersion = await meteringPointsService.GetHeatingMeteringPointVersionAsync(meteringPointId, cancellationToken);
if (meteringPointVersion == null)
{
throw new MeteringPointNotFoundException($"Metering point with id {meteringPointId} not found in Metering Points domain.");
}
if (meteringPointVersion.ConnectionPointId is null)
{
throw new MeteringPointProcessValidationException("Connection point id is missing on metering point.");
}
var connectionPointNumber = await GetConnectionPointNumber(meteringPointVersion.ConnectionPointId!.Value, cancellationToken);
if (connectionPointNumber is null)
{
throw new MeteringPointProcessValidationException("Connection point number is missing on metering point.");
}
_payloadBuilder.WithUnitType(payload.UnitType, meteringPointVersion.ProductUnitType)
.WithMeterReadingOccurrence(payload.MeterReadingOccurrence, meteringPointVersion.MeterReadingOccurrence)
.WithConnectionPointId(meteringPointVersion.ConnectionPointId!.Value)
.WithConnectionPointNumber(connectionPointNumber)
.WithTypeOfMeteringPoint(meteringPointVersion.TypeOfMeteringPoint!);
}
private async Task BuildUpdatePayloadForElectricity(
string meteringPointId,
ChangeFormulaProcessCommandPayload payload,
CancellationToken cancellationToken)
{
var meteringPointVersion = await electricityMeteringPointsService.GetMeteringPointVersionByIdAsync(meteringPointId, cancellationToken);
if (meteringPointVersion == null)
{
throw new MeteringPointNotFoundException($"Metering point with id {meteringPointId} not found in Metering Points domain.");
}
_oldSubtypeOfMeteringPoint = meteringPointVersion.SubTypeOfMeteringPoint;
if (!ShouldCreateBrs006(meteringPointVersion.SubTypeOfMeteringPoint, payload.SubTypeOfMeteringPoint))
{
return;
}
if (meteringPointVersion.ConnectionPointId is null)
{
throw new MeteringPointProcessValidationException("Connection point id is missing on metering point.");
}
var connectionPointNumber = await GetConnectionPointNumber(meteringPointVersion.ConnectionPointId!.Value, cancellationToken);
if (connectionPointNumber is null)
{
throw new MeteringPointProcessValidationException("Connection point number is missing on metering point.");
}
_payloadBuilder.WithUnitType(payload.UnitType, meteringPointVersion.ProductUnitType)
.WithMeterReadingOccurrence(payload.MeterReadingOccurrence, meteringPointVersion.MeterReadingOccurrence)
.WithConnectionPointId(meteringPointVersion.ConnectionPointId!.Value)
.WithConnectionPointNumber(connectionPointNumber)
.WithTypeOfMeteringPoint(meteringPointVersion.TypeOfMeteringPoint!);
}
private bool ShouldCreateBrs006(string? oldSubtypeOfMeteringPoint, string? newSubTypeOfMeteringPoint)
{
if (oldSubtypeOfMeteringPoint == SubTypesOfMeteringPoint.D02_Virtual && newSubTypeOfMeteringPoint == SubTypesOfMeteringPoint.D03_Calculated)
{
return true;
}
if (oldSubtypeOfMeteringPoint == SubTypesOfMeteringPoint.D03_Calculated && newSubTypeOfMeteringPoint == SubTypesOfMeteringPoint.D02_Virtual)
{
return true;
}
return false;
}
private async Task<FormulaVersionDto?> GetFormulaPayload(
string meteringPointVersionId,
SupplyType supplyType,
CancellationToken cancellationToken)
{
switch (supplyType)
{
case SupplyType.Heating:
{
var dto = await meteringPointsService.GetHeatingFormulaVersionAsync(meteringPointVersionId, cancellationToken);
return dto;
}
case SupplyType.Water:
{
var dto = await meteringPointsService.GetWaterFormulaVersionAsync(meteringPointVersionId, cancellationToken);
return dto;
}
case SupplyType.Electricity:
default:
throw new ArgumentOutOfRangeException(nameof(supplyType), supplyType, null);
}
}
private async Task<string?> GetConnectionPointNumber(
Guid connectionPointId,
CancellationToken cancellationToken)
{
var connectionPoint = await connectionPointsService.GetConnectionPointAsync(connectionPointId, cancellationToken);
return connectionPoint?.ConnectionPointNumber;
}
}
Editor is loading...
Leave a Comment