Skip to content

Commit f6aa4b7

Browse files
Merge pull request #15 from TransactionProcessing/task/#5_fileimportlog
Added Import log to processing
2 parents 6f78a3f + 811c232 commit f6aa4b7

26 files changed

Lines changed: 1188 additions & 130 deletions

File tree

FIleProcessor.Models/FileDetails.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,20 @@ public class FileDetails
5151
public Guid FileProfileId { get; set; }
5252

5353
/// <summary>
54-
/// Gets or sets the name of the original file.
54+
/// Gets or sets the file import log identifier.
5555
/// </summary>
5656
/// <value>
57-
/// The name of the original file.
57+
/// The file import log identifier.
5858
/// </value>
59-
public String OriginalFileName { get; set; }
59+
public Guid FileImportLogId { get; set; }
60+
61+
/// <summary>
62+
/// Gets or sets the file location.
63+
/// </summary>
64+
/// <value>
65+
/// The file location.
66+
/// </value>
67+
public String FileLocation { get; set; }
6068

6169
/// <summary>
6270
/// Gets or sets the file lines.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
namespace FIleProcessor.Models
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
6+
public class FileImportLog
7+
{
8+
public Guid EstateId { get; set; }
9+
public DateTime FileImportLogDateTime { get; set; }
10+
public Guid FileImportLogId { get; set; }
11+
public List<ImportLogFile> Files { get; set; }
12+
}
13+
public class ImportLogFile
14+
{
15+
/// <summary>
16+
/// Gets or sets the file identifier.
17+
/// </summary>
18+
/// <value>
19+
/// The file identifier.
20+
/// </value>
21+
public Guid FileId { get; set; }
22+
23+
/// <summary>
24+
/// Gets or sets the estate identifier.
25+
/// </summary>
26+
/// <value>
27+
/// The estate identifier.
28+
/// </value>
29+
public Guid EstateId { get; set; }
30+
31+
/// <summary>
32+
/// Gets or sets the user identifier.
33+
/// </summary>
34+
/// <value>
35+
/// The user identifier.
36+
/// </value>
37+
public Guid UserId { get; set; }
38+
39+
/// <summary>
40+
/// Gets or sets the merchant identifier.
41+
/// </summary>
42+
/// <value>
43+
/// The merchant identifier.
44+
/// </value>
45+
public Guid MerchantId { get; set; }
46+
47+
/// <summary>
48+
/// Gets or sets the file profile identifier.
49+
/// </summary>
50+
/// <value>
51+
/// The file profile identifier.
52+
/// </value>
53+
public Guid FileProfileId { get; set; }
54+
55+
/// <summary>
56+
/// Gets or sets the name of the original file.
57+
/// </summary>
58+
/// <value>
59+
/// The name of the original file.
60+
/// </value>
61+
public String OriginalFileName { get; set; }
62+
63+
/// <summary>
64+
/// Gets or sets the file path.
65+
/// </summary>
66+
/// <value>
67+
/// The file path.
68+
/// </value>
69+
public String FilePath { get; set; }
70+
}
71+
}

FileProcessor.BusinessLogic.Tests/DomainEventHandlerTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace FileProcessor.BusinessLogic.Tests
99
using System.Threading;
1010
using EventHandling;
1111
using File.DomainEvents;
12+
using FileImportLog.DomainEvents;
1213
using MediatR;
1314
using Moq;
1415
using Shouldly;
@@ -29,5 +30,17 @@ public void FileDomainEventHandler_FileLineAddedEvent_EventIsHandled()
2930
await eventHandler.Handle(fileLineAddedEvent, CancellationToken.None);
3031
});
3132
}
33+
34+
[Fact]
35+
public void FileDomainEventHandler_FileAddedToImportLogEvent_EventIsHandled()
36+
{
37+
Mock<IMediator> mediator = new Mock<IMediator>();
38+
FileDomainEventHandler eventHandler = new FileDomainEventHandler(mediator.Object);
39+
FileAddedToImportLogEvent fileAddedToImportLogEvent = TestData.FileAddedToImportLogEvent;
40+
Should.NotThrow(async () =>
41+
{
42+
await eventHandler.Handle(fileAddedToImportLogEvent, CancellationToken.None);
43+
});
44+
}
3245
}
3346
}

FileProcessor.BusinessLogic.Tests/FileRequestHandlerTests.cs

Lines changed: 219 additions & 12 deletions
Large diffs are not rendered by default.

FileProcessor.BusinessLogic.Tests/RequestTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ public void UploadFileRequest_CanBeCreated_IsCreated()
2323
uploadFileRequest.FileProfileId.ShouldBe(TestData.FileProfileId);
2424
}
2525

26+
[Fact]
27+
public void ProcessUploadedFileRequest_CanBeCreated_IsCreated()
28+
{
29+
ProcessUploadedFileRequest processUploadedFileRequest =
30+
new ProcessUploadedFileRequest(TestData.EstateId, TestData.MerchantId, TestData.FileId, TestData.UserId, TestData.FilePath, TestData.FileProfileId);
31+
32+
processUploadedFileRequest.EstateId.ShouldBe(TestData.EstateId);
33+
processUploadedFileRequest.MerchantId.ShouldBe(TestData.MerchantId);
34+
processUploadedFileRequest.FileId.ShouldBe(TestData.FileId);
35+
processUploadedFileRequest.UserId.ShouldBe(TestData.UserId);
36+
processUploadedFileRequest.FilePath.ShouldBe(TestData.FilePath);
37+
processUploadedFileRequest.FileProfileId.ShouldBe(TestData.FileProfileId);
38+
}
39+
2640
[Fact]
2741
public void SafaricomTopupRequest_CanBeCreated_IsCreated()
2842
{

FileProcessor.BusinessLogic/EventHandling/FileDomainEventHandler.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace FileProcessor.BusinessLogic.EventHandling
88
using EstateManagement.Client;
99
using File.DomainEvents;
1010
using FileAggregate;
11+
using FileImportLog.DomainEvents;
1112
using Managers;
1213
using MediatR;
1314
using Microsoft.Extensions.Logging;
@@ -78,7 +79,25 @@ private async Task HandleSpecificDomainEvent(FileLineAddedEvent domainEvent,
7879

7980
await this.Mediator.Send(request, cancellationToken);
8081
}
81-
82+
83+
/// <summary>
84+
/// Handles the specific domain event.
85+
/// </summary>
86+
/// <param name="domainEvent">The domain event.</param>
87+
/// <param name="cancellationToken">The cancellation token.</param>
88+
private async Task HandleSpecificDomainEvent(FileAddedToImportLogEvent domainEvent,
89+
CancellationToken cancellationToken)
90+
{
91+
ProcessUploadedFileRequest request = new ProcessUploadedFileRequest(domainEvent.EstateId,
92+
domainEvent.MerchantId,
93+
domainEvent.FileId,
94+
domainEvent.UserId,
95+
domainEvent.FilePath,
96+
domainEvent.FileProfileId);
97+
98+
await this.Mediator.Send(request, cancellationToken);
99+
}
100+
82101
#endregion
83102
}
84103
}

FileProcessor.BusinessLogic/FileProcessor.BusinessLogic.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
<ItemGroup>
1919
<ProjectReference Include="..\FileProcessor.FileAggregate\FileProcessor.FileAggregate.csproj" />
20+
<ProjectReference Include="..\FileProcessor.FileImportLogAggregate\FileProcessor.FileImportLogAggregate.csproj" />
2021
</ItemGroup>
2122

2223
<ItemGroup>

FileProcessor.BusinessLogic/RequestHandlers/FileRequestHandler.cs

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace FileProcessor.BusinessLogic.RequestHandlers
1515
using EventHandling;
1616
using FileAggregate;
1717
using FileFormatHandlers;
18+
using FileImportLogAggregate;
1819
using FIleProcessor.Models;
1920
using Managers;
2021
using Newtonsoft.Json;
@@ -32,10 +33,11 @@ namespace FileProcessor.BusinessLogic.RequestHandlers
3233
/// <summary>
3334
///
3435
/// </summary>
35-
/// <seealso cref="MediatR.IRequestHandler{FileProcessor.BusinessLogic.Requests.UploadFileRequest}" />
36-
/// <seealso cref="MediatR.IRequestHandler{FileProcessor.BusinessLogic.Requests.SafaricomTopupRequest}" />
37-
/// <seealso cref="MediatR.IRequestHandler{FileProcessor.BusinessLogic.Requests.ProcessTransactionForFileLineRequest}" />
36+
/// <seealso cref="UploadFileRequest" />
37+
/// <seealso cref="SafaricomTopupRequest" />
38+
/// <seealso cref="ProcessTransactionForFileLineRequest" />
3839
public class FileRequestHandler : IRequestHandler<UploadFileRequest>,
40+
IRequestHandler<ProcessUploadedFileRequest>,
3941
IRequestHandler<SafaricomTopupRequest>,
4042
IRequestHandler<ProcessTransactionForFileLineRequest>
4143
{
@@ -44,6 +46,8 @@ public class FileRequestHandler : IRequestHandler<UploadFileRequest>,
4446
/// </summary>
4547
private readonly IFileProcessorManager FileProcessorManager;
4648

49+
private readonly IAggregateRepository<FileImportLogAggregate, DomainEventRecord.DomainEvent> FileImportLogAggregateRepository;
50+
4751
/// <summary>
4852
/// The file aggregate repository
4953
/// </summary>
@@ -85,6 +89,7 @@ public class FileRequestHandler : IRequestHandler<UploadFileRequest>,
8589
/// <param name="fileFormatHandlerResolver">The file format handler resolver.</param>
8690
/// <param name="fileSystem">The file system.</param>
8791
public FileRequestHandler(IFileProcessorManager fileProcessorManager,
92+
IAggregateRepository<FileImportLogAggregate, DomainEventRecord.DomainEvent> fileImportLogAggregateRepository,
8893
IAggregateRepository<FileAggregate, DomainEventRecord.DomainEvent> fileAggregateRepository,
8994
ITransactionProcessorClient transactionProcessorClient,
9095
IEstateClient estateClient,
@@ -93,6 +98,7 @@ public FileRequestHandler(IFileProcessorManager fileProcessorManager,
9398
IFileSystem fileSystem)
9499
{
95100
this.FileProcessorManager = fileProcessorManager;
101+
this.FileImportLogAggregateRepository = fileImportLogAggregateRepository;
96102
this.FileAggregateRepository = fileAggregateRepository;
97103
this.TransactionProcessorClient = transactionProcessorClient;
98104
this.EstateClient = estateClient;
@@ -115,8 +121,21 @@ public FileRequestHandler(IFileProcessorManager fileProcessorManager,
115121
public async Task<Unit> Handle(UploadFileRequest request,
116122
CancellationToken cancellationToken)
117123
{
118-
// TODO: Should the file id be generated from the file uploaded to protect against duplicate files???
119-
// Find the file profile
124+
DateTime importLogDateTime = DateTime.Now;
125+
126+
// This will now create the import log and add an event for the file being uploaded
127+
Guid importLogId = this.CreateGuidFromDateTime(importLogDateTime.Date);
128+
129+
// Get the import log
130+
FileImportLogAggregate fileImportLogAggregate = await this.FileImportLogAggregateRepository.GetLatestVersion(importLogId, cancellationToken);
131+
132+
if (fileImportLogAggregate.IsCreated == false)
133+
{
134+
// First file of the day so create
135+
fileImportLogAggregate.CreateImportLog(request.EstateId, importLogDateTime);
136+
}
137+
138+
// Move the file
120139
FileProfile fileProfile = await this.FileProcessorManager.GetFileProfile(request.FileProfileId, cancellationToken);
121140

122141
if (fileProfile == null)
@@ -137,14 +156,35 @@ public async Task<Unit> Handle(UploadFileRequest request,
137156
throw new DirectoryNotFoundException($"Directory {fileProfile.ListeningDirectory} not found");
138157
}
139158

140-
file.MoveTo($"{fileProfile.ListeningDirectory}\\{request.EstateId:N}-{request.FileId:N}", overwrite:true);
159+
String fileDestination = $"{fileProfile.ListeningDirectory}\\{request.EstateId:N}-{request.FileId:N}";
160+
file.MoveTo(fileDestination, overwrite:true);;
161+
162+
// Update Import log aggregate
163+
fileImportLogAggregate.AddImportedFile(request.FileId, request.MerchantId, request.UserId, request.FileProfileId, originalName, fileDestination);
164+
165+
// Save changes
166+
await this.FileImportLogAggregateRepository.SaveChanges(fileImportLogAggregate, cancellationToken);
141167

142-
// Write file to import log
143-
// TODO:
168+
return new Unit();
169+
}
144170

171+
private Guid CreateGuidFromDateTime(DateTime dateTime)
172+
{
173+
var bytes = BitConverter.GetBytes(dateTime.Ticks);
174+
175+
Array.Resize(ref bytes, 16);
176+
177+
var guid = new Guid(bytes);
178+
179+
return guid;
180+
}
181+
182+
public async Task<Unit> Handle(ProcessUploadedFileRequest request, CancellationToken cancellationToken)
183+
{
184+
// TODO: Should the file id be generated from the file uploaded to protect against duplicate files???
145185
FileAggregate fileAggregate = await this.FileAggregateRepository.GetLatestVersion(request.FileId, cancellationToken);
146186

147-
fileAggregate.UploadFile(request.EstateId, request.MerchantId, request.UserId, request.FileProfileId, originalName);
187+
fileAggregate.CreateFile(request.FileImportLogId, request.EstateId, request.MerchantId, request.UserId, request.FileProfileId, request.FilePath);
148188

149189
await this.FileAggregateRepository.SaveChanges(fileAggregate, cancellationToken);
150190

@@ -169,6 +209,11 @@ public async Task<Unit> Handle(UploadFileRequest request,
169209
public async Task<Unit> Handle(SafaricomTopupRequest request,
170210
CancellationToken cancellationToken)
171211
{
212+
FileAggregate fileAggregate = await this.FileAggregateRepository.GetLatestVersion(request.FileId, cancellationToken);
213+
214+
if (fileAggregate.IsCreated == false)
215+
return new Unit();
216+
172217
IFileInfo file = this.FileSystem.FileInfo.FromFileName(request.FileName);
173218

174219
if (file.Exists == false)
@@ -217,8 +262,6 @@ public async Task<Unit> Handle(SafaricomTopupRequest request,
217262

218263
if (String.IsNullOrEmpty(fileContent) == false)
219264
{
220-
FileAggregate fileAggregate = await this.FileAggregateRepository.GetLatestVersion(request.FileId, cancellationToken);
221-
222265
String[] fileLines = fileContent.Split(Environment.NewLine);
223266

224267
foreach (String fileLine in fileLines)

0 commit comments

Comments
 (0)