From 43ca5854aa1b63fc6d0717cdc868e3e461a7da5b Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Wed, 4 Nov 2026 10:25:08 +0000 Subject: [PATCH 1/2] preserve utc timestamps --- Directory.Packages.props | 20 +++++++++---------- FIleProcessor.Models/FileDetails.cs | 2 +- FIleProcessor.Models/FileImportLog.cs | 2 +- FIleProcessor.Models/ImportLogFile.cs | 2 +- .../TransactionDispatchAttempt.cs | 2 +- .../FileProcessingManagerTests.cs | 8 ++++---- .../FileProcessorDomainServiceTests.cs | 1 + .../Common/FileLineProcessingDiagnostics.cs | 1 + FileProcessor.BusinessLogic/Common/Helpers.cs | 4 ++-- .../Requests/FileCommands.cs | 4 ++-- .../Services/FileProcessorDomainService.cs | 9 ++++++--- .../Requests/UploadFileRequest.cs | 2 +- .../Responses/FileImportLog.cs | 4 ++-- .../Responses/FileImportLogFile.cs | 2 +- .../Responses/TransactionDispatchAttempt.cs | 2 +- .../FileAggregateDomainEvents.cs.cs | 8 ++++---- FileProcessor.FileAggregate/FileAggregate.cs | 10 +++++----- .../FileImportLogAggregateDomainEvents.cs | 4 ++-- .../FileImportLogAggregate.cs | 12 +++++------ .../FileProcessorSteps.cs | 4 ++-- .../Features/FileProfile.feature.cs | 9 --------- FileProcessor.Testing/TestData.cs | 7 +++++-- FileProcessor/Common/ModelFactory.cs | 3 ++- FileProcessor/Handlers/FileHandlers.cs | 4 ++-- 24 files changed, 62 insertions(+), 64 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index b598d65..d2f3047 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,14 +6,14 @@ - - + + - - + + @@ -37,7 +37,7 @@ - + @@ -45,14 +45,14 @@ - - + + - - - + + + diff --git a/FIleProcessor.Models/FileDetails.cs b/FIleProcessor.Models/FileDetails.cs index 6586170..e81d0f1 100644 --- a/FIleProcessor.Models/FileDetails.cs +++ b/FIleProcessor.Models/FileDetails.cs @@ -66,7 +66,7 @@ public class FileDetails public Guid FileProfileVersionId { get; set; } - public DateTime FileReceivedDateTime { get; set; } + public DateTimeOffset FileReceivedDateTime { get; set; } /// /// Gets or sets the merchant identifier. diff --git a/FIleProcessor.Models/FileImportLog.cs b/FIleProcessor.Models/FileImportLog.cs index c5c4d5c..ce5fb3f 100644 --- a/FIleProcessor.Models/FileImportLog.cs +++ b/FIleProcessor.Models/FileImportLog.cs @@ -24,7 +24,7 @@ public class FileImportLog /// /// The file import log date time. /// - public DateTime FileImportLogDateTime { get; set; } + public DateTimeOffset FileImportLogDateTime { get; set; } /// /// Gets or sets the file import log identifier. diff --git a/FIleProcessor.Models/ImportLogFile.cs b/FIleProcessor.Models/ImportLogFile.cs index 91920f2..1a322e2 100644 --- a/FIleProcessor.Models/ImportLogFile.cs +++ b/FIleProcessor.Models/ImportLogFile.cs @@ -62,7 +62,7 @@ public class ImportLogFile /// /// The uploaded date time. /// - public DateTime UploadedDateTime { get; set; } + public DateTimeOffset UploadedDateTime { get; set; } /// /// Gets or sets the user identifier. diff --git a/FIleProcessor.Models/TransactionDispatchAttempt.cs b/FIleProcessor.Models/TransactionDispatchAttempt.cs index 8ea4541..56844b5 100644 --- a/FIleProcessor.Models/TransactionDispatchAttempt.cs +++ b/FIleProcessor.Models/TransactionDispatchAttempt.cs @@ -8,6 +8,6 @@ public class TransactionDispatchAttempt public String FailureType { get; set; } - public DateTime AttemptedAt { get; set; } + public DateTimeOffset AttemptedAt { get; set; } } } diff --git a/FileProcessor.BusinessLogic.Tests/FileProcessingManagerTests.cs b/FileProcessor.BusinessLogic.Tests/FileProcessingManagerTests.cs index 7215bd2..e788162 100644 --- a/FileProcessor.BusinessLogic.Tests/FileProcessingManagerTests.cs +++ b/FileProcessor.BusinessLogic.Tests/FileProcessingManagerTests.cs @@ -102,7 +102,7 @@ public async Task FileProcessingManager_GetFileImportLogs_NoMerchantId_ImportLog this.Context.Merchants.Add(new Merchant { MerchantId = TestData.MerchantId, Name = TestData.MerchantName }); await this.Context.SaveChangesAsync(); - Result getFileImportLogsResult = await this.Manager.GetFileImportLogs(TestData.EstateId, DateOnly.FromDateTime(TestData.ImportLogStartDate), DateOnly.FromDateTime(TestData.ImportLogEndDate), null, 1, 50, false, CancellationToken.None); + Result getFileImportLogsResult = await this.Manager.GetFileImportLogs(TestData.EstateId, DateOnly.FromDateTime(TestData.ImportLogStartDate.DateTime), DateOnly.FromDateTime(TestData.ImportLogEndDate.DateTime), null, 1, 50, false, CancellationToken.None); getFileImportLogsResult.IsSuccess.ShouldBeTrue(); List importLogs = getFileImportLogsResult.Data.FileImportLogs; this.VerifyImportLogs(TestData.FileImportLogs,importLogs); @@ -120,7 +120,7 @@ public async Task FileProcessingManager_GetFileImportLogs_WithMerchantId_ImportL this.Context.Merchants.Add(new Merchant { MerchantId = TestData.MerchantId, Name = TestData.MerchantName }); await this.Context.SaveChangesAsync(); - Result importLogsResult = await this.Manager.GetFileImportLogs(TestData.EstateId, DateOnly.FromDateTime(TestData.ImportLogStartDate), DateOnly.FromDateTime(TestData.ImportLogEndDate), TestData.MerchantId, 1, 50, false, CancellationToken.None); + Result importLogsResult = await this.Manager.GetFileImportLogs(TestData.EstateId, DateOnly.FromDateTime(TestData.ImportLogStartDate.DateTime), DateOnly.FromDateTime(TestData.ImportLogEndDate.DateTime), TestData.MerchantId, 1, 50, false, CancellationToken.None); this.VerifyImportLogs(TestData.FileImportLogs, importLogsResult.Data.FileImportLogs, TestData.MerchantId); importLogsResult.Data.FileImportLogs.SelectMany(log => log.Files).ShouldAllBe(file => file.FileProfileVersionId == TestData.FileProfileVersionId); @@ -171,8 +171,8 @@ public async Task FileProcessingManager_GetFileImportLogs_DateOnlyRangeIsInclusi Result result = await this.Manager.GetFileImportLogs( TestData.EstateId, - DateOnly.FromDateTime(TestData.ImportLogStartDate), - DateOnly.FromDateTime(TestData.ImportLogEndDate), + DateOnly.FromDateTime(TestData.ImportLogStartDate.DateTime), + DateOnly.FromDateTime(TestData.ImportLogEndDate.DateTime), null, 1, 1, diff --git a/FileProcessor.BusinessLogic.Tests/FileProcessorDomainServiceTests.cs b/FileProcessor.BusinessLogic.Tests/FileProcessorDomainServiceTests.cs index 5535ee5..da3ee65 100644 --- a/FileProcessor.BusinessLogic.Tests/FileProcessorDomainServiceTests.cs +++ b/FileProcessor.BusinessLogic.Tests/FileProcessorDomainServiceTests.cs @@ -1,5 +1,6 @@ using System.Text; using SimpleResults; +using TransactionProcessor.DataTransferObjects.Requests.Transaction; using TransactionProcessor.DataTransferObjects.Responses.Contract; using TransactionProcessor.DataTransferObjects.Responses.Operator; diff --git a/FileProcessor.BusinessLogic/Common/FileLineProcessingDiagnostics.cs b/FileProcessor.BusinessLogic/Common/FileLineProcessingDiagnostics.cs index 0cba6d4..b4cec94 100644 --- a/FileProcessor.BusinessLogic/Common/FileLineProcessingDiagnostics.cs +++ b/FileProcessor.BusinessLogic/Common/FileLineProcessingDiagnostics.cs @@ -6,6 +6,7 @@ using Shared.Logger; using SimpleResults; using TransactionProcessor.DataTransferObjects; +using TransactionProcessor.DataTransferObjects.Responses.Transaction; namespace FileProcessor.BusinessLogic.Common; diff --git a/FileProcessor.BusinessLogic/Common/Helpers.cs b/FileProcessor.BusinessLogic/Common/Helpers.cs index 3dfd616..d15a96d 100644 --- a/FileProcessor.BusinessLogic/Common/Helpers.cs +++ b/FileProcessor.BusinessLogic/Common/Helpers.cs @@ -5,10 +5,10 @@ public static class Helpers { - public static Guid CalculateFileImportLogAggregateId(DateTime importLogDateTime, + public static Guid CalculateFileImportLogAggregateId(DateTimeOffset importLogDateTime, Guid estateId) { - Guid aggregateId = GuidCalculator.Combine(estateId, importLogDateTime.ToGuid()); + Guid aggregateId = GuidCalculator.Combine(estateId, importLogDateTime.DateTime.ToGuid()); return aggregateId; } } diff --git a/FileProcessor.BusinessLogic/Requests/FileCommands.cs b/FileProcessor.BusinessLogic/Requests/FileCommands.cs index 38841b0..224a7f2 100644 --- a/FileProcessor.BusinessLogic/Requests/FileCommands.cs +++ b/FileProcessor.BusinessLogic/Requests/FileCommands.cs @@ -17,7 +17,7 @@ public record ProcessUploadedFileCommand(Guid EstateId, Guid UserId, String FilePath, Guid FileProfileId, - DateTime FileUploadedDateTime, + DateTimeOffset FileUploadedDateTime, Guid FileProfileVersionId = default) : IRequest; public record UploadFileCommand(Guid FileId, @@ -26,7 +26,7 @@ public record UploadFileCommand(Guid FileId, Guid UserId, String FilePath, Guid FileProfileId, - DateTime FileUploadedDateTime, + DateTimeOffset FileUploadedDateTime, String OriginalFileName = null) : IRequest; public record ReplayFileLineCommand(Guid FileId, diff --git a/FileProcessor.BusinessLogic/Services/FileProcessorDomainService.cs b/FileProcessor.BusinessLogic/Services/FileProcessorDomainService.cs index 95bbf6c..78aa844 100644 --- a/FileProcessor.BusinessLogic/Services/FileProcessorDomainService.cs +++ b/FileProcessor.BusinessLogic/Services/FileProcessorDomainService.cs @@ -1,6 +1,8 @@ using SecurityService.DataTransferObjects; using Shared.EventStore.Helpers; +using TransactionProcessor.DataTransferObjects.Requests.Transaction; using TransactionProcessor.DataTransferObjects.Responses.Merchant; +using TransactionProcessor.DataTransferObjects.Responses.Transaction; namespace FileProcessor.BusinessLogic.Services; @@ -160,7 +162,7 @@ private async Task ApplyFileImportLogUpdates(Func UploadFile(FileCommands.UploadFileCommand command, CancellationToken cancellationToken) { - DateTime importLogDateTime = command.FileUploadedDateTime; + DateTimeOffset importLogDateTime = command.FileUploadedDateTime; Result validateResult = this.ValidateRequest(command); if (validateResult.IsFailed) @@ -179,7 +181,7 @@ public async Task UploadFile(FileCommands.UploadFileCommand command, } private async Task RegisterUploadedFile(FileCommands.UploadFileCommand command, - DateTime importLogDateTime, + DateTimeOffset importLogDateTime, FileImportLogAggregate fileImportLogAggregate, CancellationToken cancellationToken) { @@ -268,7 +270,7 @@ private Result RegisterDuplicateImportLogFile(FileCommands.UploadFileCommand com private async Task RegisterNewImportLogFile(FileCommands.UploadFileCommand command, String originalName, - DateTime importLogDateTime, + DateTimeOffset importLogDateTime, FileImportLogAggregate fileImportLogAggregate, CancellationToken cancellationToken) { @@ -692,6 +694,7 @@ private async Task> SendSaleTransaction(FileDeta EstateId = fileDetails.EstateId, MerchantId = fileDetails.MerchantId, TransactionDateTime = fileDetails.FileReceivedDateTime, + HostDateTime = DateTimeOffset.UtcNow, TransactionNumber = transactionNumber.ToString(CultureInfo.InvariantCulture), TransactionType = "Sale", ContractId = detailsForTransaction.Data.ContractId, diff --git a/FileProcessor.DataTransferObjects/Requests/UploadFileRequest.cs b/FileProcessor.DataTransferObjects/Requests/UploadFileRequest.cs index 3611d92..aa74c83 100644 --- a/FileProcessor.DataTransferObjects/Requests/UploadFileRequest.cs +++ b/FileProcessor.DataTransferObjects/Requests/UploadFileRequest.cs @@ -29,6 +29,6 @@ public class UploadFileRequest /// Gets or sets the time the file was uploaded. If omitted or set to the minimum date value, the server uses the current local time. [Description("The time the file was uploaded. If omitted or set to the minimum date value, the server uses the current local time.")] - public DateTime UploadDateTime { get; set; } + public DateTimeOffset UploadDateTime { get; set; } } } diff --git a/FileProcessor.DataTransferObjects/Responses/FileImportLog.cs b/FileProcessor.DataTransferObjects/Responses/FileImportLog.cs index f3521ad..bd0f713 100644 --- a/FileProcessor.DataTransferObjects/Responses/FileImportLog.cs +++ b/FileProcessor.DataTransferObjects/Responses/FileImportLog.cs @@ -14,11 +14,11 @@ public class FileImportLog /// Gets or sets the import log timestamp. [Description("The import log timestamp.")] - public DateTime ImportLogDateTime { get; set; } + public DateTimeOffset ImportLogDateTime { get; set; } /// Gets or sets the calendar date of the import log. [Description("The calendar date of the import log.")] - public DateTime ImportLogDate { get; set; } + public DateOnly ImportLogDate { get; set; } /// Gets or sets the time of day of the import log. [Description("The time of day of the import log.")] diff --git a/FileProcessor.DataTransferObjects/Responses/FileImportLogFile.cs b/FileProcessor.DataTransferObjects/Responses/FileImportLogFile.cs index 17425e7..8aff515 100644 --- a/FileProcessor.DataTransferObjects/Responses/FileImportLogFile.cs +++ b/FileProcessor.DataTransferObjects/Responses/FileImportLogFile.cs @@ -28,7 +28,7 @@ public class FileImportLogFile /// Gets or sets when the file was uploaded. [Description("When the file was uploaded.")] - public DateTime FileUploadedDateTime { get; set; } + public DateTimeOffset FileUploadedDateTime { get; set; } /// Gets or sets the identifier of the associated merchant. [Description("The identifier of the associated merchant.")] diff --git a/FileProcessor.DataTransferObjects/Responses/TransactionDispatchAttempt.cs b/FileProcessor.DataTransferObjects/Responses/TransactionDispatchAttempt.cs index 5f8d6ca..51a88ed 100644 --- a/FileProcessor.DataTransferObjects/Responses/TransactionDispatchAttempt.cs +++ b/FileProcessor.DataTransferObjects/Responses/TransactionDispatchAttempt.cs @@ -17,6 +17,6 @@ public class TransactionDispatchAttempt /// Gets or sets when the dispatch attempt occurred. [Description("When the dispatch attempt occurred.")] - public DateTime AttemptedAt { get; set; } + public DateTimeOffset AttemptedAt { get; set; } } } diff --git a/FileProcessor.File.DomainEvents/FileAggregateDomainEvents.cs.cs b/FileProcessor.File.DomainEvents/FileAggregateDomainEvents.cs.cs index 038cf67..1986735 100644 --- a/FileProcessor.File.DomainEvents/FileAggregateDomainEvents.cs.cs +++ b/FileProcessor.File.DomainEvents/FileAggregateDomainEvents.cs.cs @@ -7,11 +7,11 @@ public record FileLineAddedEvent(Guid FileId, Guid EstateId, Guid MerchantId, In public record DuplicateFileLineAddedEvent(Guid FileId, Guid EstateId, Guid MerchantId, Int32 LineNumber, String FileLine) : DomainEvent(FileId, Guid.NewGuid()); - public record FileProcessingCompletedEvent(Guid FileId, Guid EstateId, Guid MerchantId, DateTime ProcessingCompletedDateTime) : DomainEvent(FileId, Guid.NewGuid()); + public record FileProcessingCompletedEvent(Guid FileId, Guid EstateId, Guid MerchantId, DateTimeOffset ProcessingCompletedDateTime) : DomainEvent(FileId, Guid.NewGuid()); public record FileLineProcessingFailedEvent(Guid FileId, Guid EstateId, Guid MerchantId, Int32 LineNumber, Guid TransactionId, String ResponseCode, String ResponseMessage) : DomainEvent(FileId, Guid.NewGuid()); - public record FileLineTransactionDispatchFailedEvent(Guid FileId, Guid EstateId, Guid MerchantId, Int32 LineNumber, Int32 TransactionNumber, String FailureType, DateTime AttemptedAt) : DomainEvent(FileId, Guid.NewGuid()); + public record FileLineTransactionDispatchFailedEvent(Guid FileId, Guid EstateId, Guid MerchantId, Int32 LineNumber, Int32 TransactionNumber, String FailureType, DateTimeOffset AttemptedAt) : DomainEvent(FileId, Guid.NewGuid()); public record FileLineProcessingRejectedEvent(Guid FileId, Guid EstateId, Guid MerchantId, Int32 LineNumber, String Reason) : DomainEvent(FileId, Guid.NewGuid()); @@ -26,7 +26,7 @@ public record FileCreatedEvent(Guid FileId, Guid UserId, Guid FileProfileId, String FileLocation, - DateTime FileReceivedDateTime, + DateTimeOffset FileReceivedDateTime, Guid OperatorId, Guid FileProfileVersionId = default) : DomainEvent(FileId, Guid.NewGuid()); @@ -40,5 +40,5 @@ public record FileRejectedEvent(Guid FileId, String RejectionReason, Int32 ObservedDetailRecordCount, Int32 MaximumDetailRecordCount, - DateTime RejectedDateTime) : DomainEvent(FileId, Guid.NewGuid()); + DateTimeOffset RejectedDateTime) : DomainEvent(FileId, Guid.NewGuid()); } diff --git a/FileProcessor.FileAggregate/FileAggregate.cs b/FileProcessor.FileAggregate/FileAggregate.cs index 89d620c..2e80a4a 100644 --- a/FileProcessor.FileAggregate/FileAggregate.cs +++ b/FileProcessor.FileAggregate/FileAggregate.cs @@ -142,7 +142,7 @@ public static void PlayEvent(this FileAggregate aggregate, FileProcessingComplet aggregate.IsCompleted = true; } - public record CreateFileRequest(Guid fileImportLogId, Guid estateId, Guid merchantId, Guid userId, Guid fileProfileId, String fileLocation, DateTime fileReceivedDateTime, Guid operatorId, Guid fileProfileVersionId = default); + public record CreateFileRequest(Guid fileImportLogId, Guid estateId, Guid merchantId, Guid userId, Guid fileProfileId, String fileLocation, DateTimeOffset fileReceivedDateTime, Guid operatorId, Guid fileProfileVersionId = default); public static Result CreateFile(this FileAggregate aggregate, CreateFileRequest createFileRequest) { @@ -189,7 +189,7 @@ public static Result RejectFile(this FileAggregate aggregate, Int32 maximumDetailRecordCount, String rejectionCode, String rejectionReason, - DateTime rejectedDateTime) + DateTimeOffset rejectedDateTime) { if (aggregate.IsCreated == false) return Result.Invalid($"File Id {aggregate.AggregateId} has not been uploaded yet"); @@ -352,7 +352,7 @@ private static void CompletedChecks(this FileAggregate aggregate) if (aggregate.FileLines.Any(f => f.ProcessingResult == ProcessingResult.NotProcessed) == false) { // All lines have been processed, write out a completed event - FileProcessingCompletedEvent fileProcessingCompletedEvent = new FileProcessingCompletedEvent(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, DateTime.Now); + FileProcessingCompletedEvent fileProcessingCompletedEvent = new FileProcessingCompletedEvent(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, DateTimeOffset.UtcNow); aggregate.ApplyAndAppend(fileProcessingCompletedEvent); } @@ -372,7 +372,7 @@ public record FileAggregate : Aggregate internal Guid FileImportLogId; - internal DateTime FileReceivedDateTime; + internal DateTimeOffset FileReceivedDateTime; internal Guid UserId; @@ -390,7 +390,7 @@ public record FileAggregate : Aggregate internal Int32 MaximumDetailRecordCount; - internal DateTime RejectedDateTime; + internal DateTimeOffset RejectedDateTime; /// /// Initializes a new instance of the class. diff --git a/FileProcessor.FileImportLog.DomainEvents/FileImportLogAggregateDomainEvents.cs b/FileProcessor.FileImportLog.DomainEvents/FileImportLogAggregateDomainEvents.cs index efa2078..8f68df5 100644 --- a/FileProcessor.FileImportLog.DomainEvents/FileImportLogAggregateDomainEvents.cs +++ b/FileProcessor.FileImportLog.DomainEvents/FileImportLogAggregateDomainEvents.cs @@ -4,6 +4,6 @@ namespace FileProcessor.FileImportLog.DomainEvents { using Shared.DomainDrivenDesign.EventSourcing; - public record ImportLogCreatedEvent(Guid FileImportLogId, Guid EstateId, DateTime ImportLogDateTime) : DomainEvent(FileImportLogId, Guid.NewGuid()); - public record FileAddedToImportLogEvent(Guid FileImportLogId, Guid FileId, Guid EstateId, Guid MerchantId, Guid UserId, Guid FileProfileId, String OriginalFileName, String FilePath, DateTime FileUploadedDateTime, Guid FileProfileVersionId = default) : DomainEvent(FileImportLogId, Guid.NewGuid()); + public record ImportLogCreatedEvent(Guid FileImportLogId, Guid EstateId, DateTimeOffset ImportLogDateTime) : DomainEvent(FileImportLogId, Guid.NewGuid()); + public record FileAddedToImportLogEvent(Guid FileImportLogId, Guid FileId, Guid EstateId, Guid MerchantId, Guid UserId, Guid FileProfileId, String OriginalFileName, String FilePath, DateTimeOffset FileUploadedDateTime, Guid FileProfileVersionId = default) : DomainEvent(FileImportLogId, Guid.NewGuid()); } diff --git a/FileProcessor.FileImportLogAggregate/FileImportLogAggregate.cs b/FileProcessor.FileImportLogAggregate/FileImportLogAggregate.cs index 78af93f..f2c45de 100644 --- a/FileProcessor.FileImportLogAggregate/FileImportLogAggregate.cs +++ b/FileProcessor.FileImportLogAggregate/FileImportLogAggregate.cs @@ -9,13 +9,11 @@ namespace FileProcessor.FileImportLogAggregate using System.Linq; using FileImportLog.DomainEvents; using FileProcessor.Models; - using Microsoft.AspNetCore.Mvc.Rendering; using Shared.DomainDrivenDesign.EventSourcing; using Shared.EventStore.Aggregate; - using Shared.General; - + public static class FileImportLogAggregateExtensions{ - public static Result CreateImportLog(this FileImportLogAggregate aggregate, Guid estateId, DateTime importLogDateTime) + public static Result CreateImportLog(this FileImportLogAggregate aggregate, Guid estateId, DateTimeOffset importLogDateTime) { // Silently handle a duplicate create if (aggregate.IsCreated) @@ -34,7 +32,7 @@ public static Result AddImportedFile(this FileImportLogAggregate aggregate, Guid fileProfileId, String originalFileName, String filePath, - DateTime fileUploadedDateTime) + DateTimeOffset fileUploadedDateTime) { return aggregate.AddImportedFile(new AddImportedFileRequest(fileId, merchantId, @@ -129,7 +127,7 @@ public record AddImportedFileRequest(Guid FileId, Guid FileProfileId, String OriginalFileName, String FilePath, - DateTime FileUploadedDateTime, + DateTimeOffset FileUploadedDateTime, Guid FileProfileVersionId = default); @@ -167,7 +165,7 @@ public static FileImportLogAggregate Create(Guid aggregateId) public Guid EstateId { get; internal set; } - public DateTime ImportLogDateTime { get; internal set; } + public DateTimeOffset ImportLogDateTime { get; internal set; } internal List Files; diff --git a/FileProcessor.IntegrationTesting.Helpers/FileProcessorSteps.cs b/FileProcessor.IntegrationTesting.Helpers/FileProcessorSteps.cs index be6bbef..3176471 100644 --- a/FileProcessor.IntegrationTesting.Helpers/FileProcessorSteps.cs +++ b/FileProcessor.IntegrationTesting.Helpers/FileProcessorSteps.cs @@ -154,7 +154,7 @@ await Retry.For(async () => { foreach ((DateTime, Int32) expectedImportLog in expectedImportLogs) { // Find the import log now - FileImportLog? importLog = importLogList.FileImportLogs.SingleOrDefault(fil => fil.ImportLogDate == expectedImportLog.Item1.Date && fil.FileCount == expectedImportLog.Item2); + FileImportLog? importLog = importLogList.FileImportLogs.SingleOrDefault(fil => fil.ImportLogDate == DateOnly.FromDateTime(expectedImportLog.Item1.Date) && fil.FileCount == expectedImportLog.Item2); importLog.ShouldNotBeNull(); } }); @@ -221,7 +221,7 @@ public async Task WhenIGetTheImportLogForEstateTheDateOnTheImportLogIs(String ac getFileImportLogsResult.IsSuccess.ShouldBeTrue(); FileImportLogList? importLogs = getFileImportLogsResult.Data; - FileImportLog i = importLogs.FileImportLogs.SingleOrDefault(x => x.ImportLogDate == expectedDate.Date); + FileImportLog i = importLogs.FileImportLogs.SingleOrDefault(x => x.ImportLogDate == DateOnly.FromDateTime(expectedDate.Date)); i.ShouldNotBeNull(); } diff --git a/FileProcessor.IntegrationTests/Features/FileProfile.feature.cs b/FileProcessor.IntegrationTests/Features/FileProfile.feature.cs index 9463186..c1d7bc3 100644 --- a/FileProcessor.IntegrationTests/Features/FileProfile.feature.cs +++ b/FileProcessor.IntegrationTests/Features/FileProfile.feature.cs @@ -390,15 +390,6 @@ await testRunner.GivenAsync("I have a token to access the estate management and "Operator", "1", "UnsupportedFileFormatHandler"}); - table10.AddRow(new string[] { - "Invalid Profile", - "55555555-5555-5555-5555-555555555555", - "Invalid Profile", - "/home/txnproc/bulkfiles/invalid", - "Profile A", - "Operator", - "1", - "UnsupportedFileFormatHandler"}); #line 48 await testRunner.WhenAsync("I try to create the following invalid file profiles", ((string)(null)), table10, "When "); #line hidden diff --git a/FileProcessor.Testing/TestData.cs b/FileProcessor.Testing/TestData.cs index 00a6f42..024364c 100644 --- a/FileProcessor.Testing/TestData.cs +++ b/FileProcessor.Testing/TestData.cs @@ -4,6 +4,7 @@ using TransactionProcessor.DataTransferObjects.Responses.Merchant; using TransactionProcessor.DataTransferObjects.Responses.Operator; using FileProcessor.FileProfileAggregate; +using TransactionProcessor.DataTransferObjects.Responses.Transaction; namespace FileProcessor.Testing { @@ -578,8 +579,10 @@ public static List GetMerchantContractsResponseNoNullValueProd public static String VoucherFileFormatHandler = FileProfileConfiguration.VoucherFileFormatHandler; - public static DateTime ImportLogStartDate = new DateTime(2021,7,1); - public static DateTime ImportLogEndDate = new DateTime(2021,7,2); + public static DateTimeOffset ImportLogStartDate = + new DateTimeOffset(2021, 7, 1, 0, 0, 0, TimeSpan.Zero); + public static DateTimeOffset ImportLogEndDate = + new DateTimeOffset(2021, 7, 2, 0, 0, 0, TimeSpan.Zero); public static String RejectionReason = "Invalid Line Format"; public static string UserEmailAddress = "securityuser@testemail.com"; diff --git a/FileProcessor/Common/ModelFactory.cs b/FileProcessor/Common/ModelFactory.cs index 327ee7d..963b161 100644 --- a/FileProcessor/Common/ModelFactory.cs +++ b/FileProcessor/Common/ModelFactory.cs @@ -1,4 +1,5 @@ using FileProcessor.Models; +using System; namespace FileProcessor.Common { @@ -75,7 +76,7 @@ public static FileImportLogResponse ConvertFrom(Models.FileImportLog fileImportL { FileCount = fileImportLog.Files.Count(), FileImportLogId = fileImportLog.FileImportLogId, - ImportLogDate = fileImportLog.FileImportLogDateTime.Date, + ImportLogDate = DateOnly.FromDateTime(fileImportLog.FileImportLogDateTime.Date), ImportLogDateTime = fileImportLog.FileImportLogDateTime, ImportLogTime = fileImportLog.FileImportLogDateTime.TimeOfDay, Files = new List() diff --git a/FileProcessor/Handlers/FileHandlers.cs b/FileProcessor/Handlers/FileHandlers.cs index 1d995a8..93408c2 100644 --- a/FileProcessor/Handlers/FileHandlers.cs +++ b/FileProcessor/Handlers/FileHandlers.cs @@ -45,8 +45,8 @@ public static async Task UploadFile(IMediator mediator, await upload.File.CopyToAsync(stream, cancellationToken); } - if (request.UploadDateTime == DateTime.MinValue) - request.UploadDateTime = DateTime.Now; + if (request.UploadDateTime == DateTimeOffset.MinValue) + request.UploadDateTime = DateTimeOffset.UtcNow; FileCommands.UploadFileCommand command = new(request.FileId, request.EstateId, From 0981cb0cffbe31e133c4462c33b1479a5d9f7d29 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Wed, 4 Nov 2026 10:35:43 +0000 Subject: [PATCH 2/2] fix pr comments --- .../Services/FileProcessorDomainService.cs | 2 +- FileProcessor.Client/FileProcessorClient.cs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/FileProcessor.BusinessLogic/Services/FileProcessorDomainService.cs b/FileProcessor.BusinessLogic/Services/FileProcessorDomainService.cs index 78aa844..ed975e4 100644 --- a/FileProcessor.BusinessLogic/Services/FileProcessorDomainService.cs +++ b/FileProcessor.BusinessLogic/Services/FileProcessorDomainService.cs @@ -169,7 +169,7 @@ public async Task UploadFile(FileCommands.UploadFileCommand command, return validateResult; // The import log is created only after validation and duplicate checks succeed. - Guid importLogId = Helpers.CalculateFileImportLogAggregateId(importLogDateTime.Date, command.EstateId); + Guid importLogId = Helpers.CalculateFileImportLogAggregateId(importLogDateTime, command.EstateId); Result result = await ApplyFileImportLogUpdates( fileImportLogAggregate => this.RegisterUploadedFile(command, importLogDateTime, fileImportLogAggregate, cancellationToken), diff --git a/FileProcessor.Client/FileProcessorClient.cs b/FileProcessor.Client/FileProcessorClient.cs index 49b3cbe..43f2efc 100644 --- a/FileProcessor.Client/FileProcessorClient.cs +++ b/FileProcessor.Client/FileProcessorClient.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Security.Cryptography; using Shared.Results; +using System.Globalization; namespace FileProcessor.Client { using System; @@ -244,8 +245,9 @@ public async Task> UploadFile(String accessToken, formFields.Add(("MerchantId", uploadFileRequest.MerchantId.ToString())); formFields.Add(("FileProfileId", uploadFileRequest.FileProfileId.ToString())); formFields.Add(("UserId", uploadFileRequest.UserId.ToString())); - formFields.Add(("UploadDateTime", uploadFileRequest.UploadDateTime.ToString("yyyy-MM-dd HH:mm:ss"))); - + formFields.Add(("UploadDateTime", + uploadFileRequest.UploadDateTime.ToString("O", CultureInfo.InvariantCulture))); + Guid fileId = CreateGuidFromFileData(fileData); formFields.Add(("FileId", fileId.ToString()));