diff --git a/source/OutgoingMessages.Domain/DocumentWriters/RSM012/MeteredDateForMeasurementPointCimXmlDocumentWriter.cs b/source/OutgoingMessages.Domain/DocumentWriters/RSM012/MeteredDateForMeasurementPointCimXmlDocumentWriter.cs index 248dce52b..bef824038 100644 --- a/source/OutgoingMessages.Domain/DocumentWriters/RSM012/MeteredDateForMeasurementPointCimXmlDocumentWriter.cs +++ b/source/OutgoingMessages.Domain/DocumentWriters/RSM012/MeteredDateForMeasurementPointCimXmlDocumentWriter.cs @@ -12,29 +12,78 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Energinet.DataHub.EDI.BuildingBlocks.Domain.Models; -using Energinet.DataHub.EDI.OutgoingMessages.Domain.Models.MarketDocuments; -using Energinet.DataHub.EDI.OutgoingMessages.Domain.Models.OutgoingMessages; +using System.Globalization; +using System.Xml; +using System.Xml.Linq; +using Energinet.DataHub.EDI.OutgoingMessages.Domain.DocumentWriters.Formats; +using Energinet.DataHub.EDI.OutgoingMessages.Domain.DocumentWriters.Formats.CIM.Xml; namespace Energinet.DataHub.EDI.OutgoingMessages.Domain.DocumentWriters.RSM012; -public class MeteredDateForMeasurementPointCimXmlDocumentWriter : IDocumentWriter +public class MeteredDateForMeasurementPointCimXmlDocumentWriter( + IMessageRecordParser parser) + : CimXmlDocumentWriter( + new DocumentDetails( + "NotifyValidatedMeasureData_MarketDocument", + "urn:ediel.org:measure:notifyvalidatedmeasuredata:0:1 urn-ediel-org-measure-notifyvalidatedmeasuredata-0-1.xsd", + "urn:ediel.org:measure:notifyvalidatedmeasuredata:0:1", + "cim", + "E66"), + parser) { - public bool HandlesFormat(DocumentFormat format) + protected override async Task WriteMarketActivityRecordsAsync( + IReadOnlyCollection marketActivityPayloads, + XmlWriter writer) { - return format == DocumentFormat.Xml; - } + ArgumentNullException.ThrowIfNull(marketActivityPayloads); + ArgumentNullException.ThrowIfNull(writer); + XNamespace @namespace = "urn:ediel.org:measure:notifyvalidatedmeasuredata:0:1"; + foreach (var wholesaleCalculationSeries in ParseFrom( + marketActivityPayloads)) + { + var seriesElement = new XElement( + @namespace + "Series", + new XElement(@namespace + "mRID", wholesaleCalculationSeries.TransactionId), + new XElement( + @namespace + "originalTransactionIDReference_Series.mRID", + wholesaleCalculationSeries.OriginalTransactionIdReferenceId), + new XElement( + @namespace + "marketEvaluationPoint.mRID", + new XAttribute("codingScheme", "A10"), + wholesaleCalculationSeries.MarketEvaluationPointNumber), + new XElement(@namespace + "marketEvaluationPoint.type", wholesaleCalculationSeries.MarketEvaluationPointType), + new XElement(@namespace + "registration_DateAndOrTime.dateTime", wholesaleCalculationSeries.RegistrationDateTime), + new XElement(@namespace + "product", wholesaleCalculationSeries.Product), + new XElement(@namespace + "quantity_Measure_Unit.name", wholesaleCalculationSeries.QuantityMeasureUnit), + new XElement( + @namespace + "Period", + new XElement(@namespace + "resolution", wholesaleCalculationSeries.Resolution), + new XElement( + @namespace + "timeInterval", + new XElement(@namespace + "start", wholesaleCalculationSeries.StartedDateTime), + new XElement(@namespace + "end", wholesaleCalculationSeries.EndedDateTime)), + wholesaleCalculationSeries.Points.Select(x => CreatePointElement(x, @namespace)))); - public bool HandlesType(DocumentType documentType) - { - return documentType == DocumentType.NotifyValidatedMeasureData; + await seriesElement.WriteToAsync(writer, CancellationToken.None).ConfigureAwait(false); + } } - public Task WriteAsync( - OutgoingMessageHeader header, - IReadOnlyCollection marketActivityRecords, - CancellationToken cancellationToken) + private XElement CreatePointElement(PointActivityRecord point, XNamespace @namespace) { - throw new NotImplementedException(); + var pointElement = new XElement( + @namespace + "Point", + new XElement(@namespace + "position", point.Position.ToString(NumberFormatInfo.InvariantInfo))); + + if (point.Quantity != null) + { + pointElement.Add(new XElement(@namespace + "quantity", point.Quantity?.ToString(NumberFormatInfo.InvariantInfo))); + } + + if (point.Quality != null) + { + pointElement.Add(new XElement(@namespace + "quality", point.Quality?.ToString(NumberFormatInfo.InvariantInfo))); + } + + return pointElement; } } diff --git a/source/Tests/Domain/OutgoingMessages/Queueing/OutgoingMessageTests.cs b/source/Tests/Domain/OutgoingMessages/Queueing/OutgoingMessageTests.cs index 605d2f364..5a607f7e4 100644 --- a/source/Tests/Domain/OutgoingMessages/Queueing/OutgoingMessageTests.cs +++ b/source/Tests/Domain/OutgoingMessages/Queueing/OutgoingMessageTests.cs @@ -55,7 +55,7 @@ public class OutgoingMessageTests new RejectRequestWholesaleSettlementCimXmlDocumentWriter(new MessageRecordParser(new Serializer())), new MeteredDateForMeasurementPointCimJsonDocumentWriter(new MessageRecordParser(new Serializer()), _serviceProvider.GetRequiredService()), - new MeteredDateForMeasurementPointCimXmlDocumentWriter(), + new MeteredDateForMeasurementPointCimXmlDocumentWriter(new MessageRecordParser(new Serializer())), ]; /// @@ -90,6 +90,7 @@ public async Task Ensure_we_can_write_all_enqueued_messages(DocumentType documen GetHeader(), new List { serializedContent }, CancellationToken.None); + // Assert await act.Should().NotThrowAsync(); } diff --git a/source/Tests/Infrastructure/OutgoingMessages/RSM012/AssertMeteredDateForMeasurementPointJsonDocument.cs b/source/Tests/Infrastructure/OutgoingMessages/RSM012/AssertMeteredDateForMeasurementPointJsonDocument.cs index 682a9711a..cb57cd7cb 100644 --- a/source/Tests/Infrastructure/OutgoingMessages/RSM012/AssertMeteredDateForMeasurementPointJsonDocument.cs +++ b/source/Tests/Infrastructure/OutgoingMessages/RSM012/AssertMeteredDateForMeasurementPointJsonDocument.cs @@ -30,8 +30,9 @@ public class AssertMeteredDateForMeasurementPointJsonDocument : IAssertMeteredDa public AssertMeteredDateForMeasurementPointJsonDocument(Stream documentStream) { _document = JsonDocument.Parse(documentStream); - var temp = _document.RootElement.GetRawText(); _root = _document.RootElement.GetProperty("NotifyValidatedMeasureData_MarketDocument"); + + Assert.Equal("E66", _root.GetProperty("type").GetProperty("value").ToString()); } public IAssertMeteredDateForMeasurementPointDocumentDocument HasMessageId(string expectedMessageId) diff --git a/source/Tests/Infrastructure/OutgoingMessages/RSM012/AssertMeteredDateForMeasurementPointXmlDocument.cs b/source/Tests/Infrastructure/OutgoingMessages/RSM012/AssertMeteredDateForMeasurementPointXmlDocument.cs new file mode 100644 index 000000000..eb2f320a9 --- /dev/null +++ b/source/Tests/Infrastructure/OutgoingMessages/RSM012/AssertMeteredDateForMeasurementPointXmlDocument.cs @@ -0,0 +1,186 @@ +// Copyright 2020 Energinet DataHub A/S +// +// Licensed under the Apache License, Version 2.0 (the "License2"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Energinet.DataHub.EDI.BuildingBlocks.Domain.Models; +using Energinet.DataHub.EDI.OutgoingMessages.Domain.DocumentWriters.RSM012; +using Energinet.DataHub.EDI.Tests.Infrastructure.OutgoingMessages.Asserts; +using FluentAssertions; + +namespace Energinet.DataHub.EDI.Tests.Infrastructure.OutgoingMessages.RSM012; + +public class AssertMeteredDateForMeasurementPointXmlDocument : IAssertMeteredDateForMeasurementPointDocumentDocument +{ + private readonly AssertXmlDocument _documentAsserter; + + public AssertMeteredDateForMeasurementPointXmlDocument(AssertXmlDocument documentAsserter) + { + _documentAsserter = documentAsserter; + _documentAsserter.HasValue("type", "E66"); + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasMessageId(string expectedMessageId) + { + _documentAsserter.ElementExists("mRID"); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasBusinessReason(string expectedBusinessReasonCode) + { + _documentAsserter.HasValue("process.processType", expectedBusinessReasonCode); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasSenderId(string expectedSenderId, string expectedSchemeCode) + { + _documentAsserter.HasValue("sender_MarketParticipant.mRID", expectedSenderId); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasSenderRole(string expectedSenderRole) + { + _documentAsserter.HasValue("sender_MarketParticipant.marketRole.type", expectedSenderRole); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasReceiverId( + string expectedReceiverId, + string expectedSchemeCode) + { + _documentAsserter.HasValue("receiver_MarketParticipant.mRID", expectedReceiverId); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasReceiverRole(string expectedReceiverRole) + { + _documentAsserter.HasValue("receiver_MarketParticipant.marketRole.type", expectedReceiverRole); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasTimestamp(string expectedTimestamp) + { + _documentAsserter.HasValue("createdDateTime", expectedTimestamp); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasTransactionId(TransactionId expectedTransactionId) + { + _documentAsserter.HasValue("Series[1]/mRID", expectedTransactionId.Value); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasMeteringPointNumber( + string expectedMeteringPointNumber, + string expectedSchemeCode) + { + _documentAsserter.HasValue("Series[1]/marketEvaluationPoint.mRID", expectedMeteringPointNumber); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasMeteringPointType(string expectedMeteringPointType) + { + _documentAsserter.HasValue("Series[1]/marketEvaluationPoint.type", expectedMeteringPointType); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasOriginalTransactionIdReferenceId( + string? expectedOriginalTransactionIdReferenceId) + { + if (expectedOriginalTransactionIdReferenceId == null) + { + _documentAsserter.IsNotPresent("Series[1]/originalTransactionIDReference_Series.mRID"); + } + else + { + _documentAsserter.HasValue( + "Series[1]/originalTransactionIDReference_Series.mRID", + expectedOriginalTransactionIdReferenceId); + } + + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasProduct(string expectedProduct) + { + _documentAsserter.HasValue("Series[1]/product", expectedProduct); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasQuantityMeasureUnit(string expectedQuantityMeasureUnit) + { + _documentAsserter.HasValue("Series[1]/quantity_Measure_Unit.name", expectedQuantityMeasureUnit); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasRegistrationDateTime(string expectedRegistrationDateTime) + { + _documentAsserter.HasValue("Series[1]/registration_DateAndOrTime.dateTime", expectedRegistrationDateTime); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasResolution(string expectedResolution) + { + _documentAsserter.HasValue("Series[1]/Period/resolution", expectedResolution); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasStartedDateTime(string expectedStartedDateTime) + { + _documentAsserter + .HasValue("Series[1]/Period/timeInterval/start", expectedStartedDateTime); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasEndedDateTime(string expectedEndedDateTime) + { + _documentAsserter + .HasValue("Series[1]/Period/timeInterval/end", expectedEndedDateTime); + return this; + } + + public IAssertMeteredDateForMeasurementPointDocumentDocument HasPoints(IReadOnlyList expectedPoints) + { + var pointsInDocument = _documentAsserter + .GetElements("Series[1]/Period/Point")!; + + pointsInDocument.Should().HaveSameCount(expectedPoints); + + for (var i = 0; i < expectedPoints.Count; i++) + { + var expectedPoint = expectedPoints[i]; + + _documentAsserter + .HasValue($"Series[1]/Period/Point[{i + 1}]/position", expectedPoint.Position.ToString()); + + if (expectedPoint.Quantity != null) + { + _documentAsserter + .HasValue($"Series[1]/Period/Point[{i + 1}]/quantity", expectedPoint.Quantity!.ToString()!); + } + + if (expectedPoint.Quality != null) + { + _documentAsserter + .HasValue($"Series[1]/Period/Point[{i + 1}]/quality", expectedPoint.Quality); + } + } + + return this; + } + + public async Task DocumentIsValidAsync() + { + await _documentAsserter.HasValidStructureAsync(DocumentType.NotifyValidatedMeasureData).ConfigureAwait(false); + return this; + } +} diff --git a/source/Tests/Infrastructure/OutgoingMessages/RSM012/MeteredDateForMeasurementPointDocumentWriterTests.cs b/source/Tests/Infrastructure/OutgoingMessages/RSM012/MeteredDateForMeasurementPointDocumentWriterTests.cs index 12b14cbcb..28785874c 100644 --- a/source/Tests/Infrastructure/OutgoingMessages/RSM012/MeteredDateForMeasurementPointDocumentWriterTests.cs +++ b/source/Tests/Infrastructure/OutgoingMessages/RSM012/MeteredDateForMeasurementPointDocumentWriterTests.cs @@ -22,20 +22,22 @@ using Energinet.DataHub.EDI.OutgoingMessages.Domain.Models.OutgoingMessages; using Energinet.DataHub.EDI.Tests.Factories; using Energinet.DataHub.EDI.Tests.Fixtures; +using Energinet.DataHub.EDI.Tests.Infrastructure.OutgoingMessages.Asserts; using FluentAssertions.Execution; using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Energinet.DataHub.EDI.Tests.Infrastructure.OutgoingMessages.RSM012; -public class MeteredDateForMeasurementPointDocumentWriterTests() +public class MeteredDateForMeasurementPointDocumentWriterTests(DocumentValidationFixture documentValidation) : IClassFixture { private readonly MessageRecordParser _parser = new(new Serializer()); private readonly MeteredDateForMeasurementPointBuilder _meteredDateForMeasurementPointBuilder = new(); + private readonly DocumentValidationFixture _documentValidation = documentValidation; [Theory] - //[InlineData(nameof(DocumentFormat.Xml))] + [InlineData(nameof(DocumentFormat.Xml))] [InlineData(nameof(DocumentFormat.Json))] public async Task Can_create_notifyWholesaleServices_document(string documentFormat) { @@ -79,10 +81,10 @@ private Task WriteDocument( { var records = _parser.From(meteredDateForMeasurementPointMarketActivityRecord); - // if (documentFormat == DocumentFormat.Xml) - // { - // return new MeteredDateForMeasurementPointCimXmlDocumentWriter(_parser).WriteAsync(header, new[] { records }); - // } + if (documentFormat == DocumentFormat.Xml) + { + return new MeteredDateForMeasurementPointCimXmlDocumentWriter(_parser).WriteAsync(header, new[] { records }); + } var serviceProvider = new ServiceCollection().AddJavaScriptEncoder().BuildServiceProvider(); return new MeteredDateForMeasurementPointCimJsonDocumentWriter( @@ -95,10 +97,12 @@ private IAssertMeteredDateForMeasurementPointDocumentDocument AssertDocument( MarketDocumentStream document, DocumentFormat documentFormat) { - // if (documentFormat == DocumentFormat.Xml) - // { - // return new AssertMeteredDateForMeasurementPointXmlDocument(document.Stream); - // } + if (documentFormat == DocumentFormat.Xml) + { + var assertXmlDocument = AssertXmlDocument.Document(document.Stream, "cim", _documentValidation.Validator); + return new AssertMeteredDateForMeasurementPointXmlDocument(assertXmlDocument); + } + return new AssertMeteredDateForMeasurementPointJsonDocument(document.Stream); } }