Skip to content

Commit

Permalink
Bugfixes and minor refactor of movement builder (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
tstesyn authored Jan 6, 2025
1 parent cc4cf83 commit f77b026
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,32 @@ public class EnsureAuditEntryIsAddedForMovementUpdatesTests(ITestOutputHelper ou
: ScenarioGeneratorBaseTest<NoAuditLogForMovementUpdate>(output)
{
[Fact]
public void ShouldHaveUpdatedAuditEntry()
public void ShouldHaveCorrectDocumentReferenceFromUpdatedClearanceRequest()
{
// Assert
var movement = Client.AsJsonApiClient()
.Get("api/movements")
.GetResourceObjects<Movement>()
.Single();

movement.AuditEntries
.Count(a => a is { CreatedBy: "Cds", Status: "Updated" })

movement.Items
.Where(x => x.Documents != null)
.SelectMany(x => x.Documents!)
.Count(x => x.DocumentReference == "GBCHD2024.001239999999")
.Should().Be(1);
}

[Fact(Skip = "The document ref isn't being updated.")]
// [Fact]
public void ShouldHaveCorrectDocumentReferenceFromUpdatedClearanceRequest()
[Fact]
public void ShouldHaveUpdatedAuditEntry()
{
// Assert
var movement = Client.AsJsonApiClient()
.Get("api/movements")
.GetResourceObjects<Movement>()
.Single();

movement.Items.First().Documents!.First().DocumentReference.Should().Be("GBCHD2024.001239999999");
movement.AuditEntries
.Count(a => a is { CreatedBy: "Cds", Status: "Updated" })
.Should().Be(1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ namespace Btms.Backend.IntegrationTests.PreprocessingTests;
public class EnsureDuplicateItemsAreNotCreatedTests(ITestOutputHelper output)
: ScenarioGeneratorBaseTest<DuplicateMovementItems_CDMS_211>(output)
{

[Fact(Skip = "We're ending up with 2 items on the clearance request here.")]
// [Fact]
[Fact]
public void ShouldNotCreateDuplicateItems()
{
// Arrange
Expand All @@ -25,7 +23,6 @@ public void ShouldNotCreateDuplicateItems()
d is { Message: AlvsClearanceRequest })
.Message;


// Act
var jsonClientResponse = Client.AsJsonApiClient().GetById(movementMessage!.Header!.EntryReference!, "api/movements");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public async Task WhenNotificationNotExists_ThenShouldBeCreated()
// ARRANGE
var clearanceRequest = CreateAlvsClearanceRequest();
var dbContext = new MemoryMongoDbContext();
var preProcessor = new MovementPreProcessor(dbContext, NullLogger<MovementPreProcessor>.Instance, new MovementBuilder(NullLogger<MovementBuilder>.Instance));
var preProcessor = new MovementPreProcessor(dbContext, NullLogger<MovementPreProcessor>.Instance, new MovementBuilderFactory(NullLogger<MovementBuilder>.Instance));


// ACT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ private static List<Movement> GenerateMovements(bool hasChecks)

var config = ScenarioFactory.CreateScenarioConfig(generator, 1, 1);

var movementBuilder = new MovementBuilder(NullLogger<MovementBuilder>.Instance);
var movementBuilderFactory = new MovementBuilderFactory(NullLogger<MovementBuilder>.Instance);
var generatorResult = generator
.Generate(1, 1, DateTime.UtcNow, config)
.First(x => x is AlvsClearanceRequest);

var internalClearanceRequest = AlvsClearanceRequestMapper.Map((AlvsClearanceRequest)generatorResult);
var movement = movementBuilder
var movement = movementBuilderFactory
.From(internalClearanceRequest)
.Build();

Expand Down
9 changes: 5 additions & 4 deletions Btms.Business.Tests/Services/Matching/MatchingServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,16 @@ private static List<Movement> GenerateMovements()
{
CrNoMatchScenarioGenerator generator =
new CrNoMatchScenarioGenerator(NullLogger<CrNoMatchScenarioGenerator>.Instance);
var movementBuilder = new MovementBuilder(NullLogger<MovementBuilder>.Instance);
var movementBuilderFactory = new MovementBuilderFactory(NullLogger<MovementBuilder>.Instance);
var config = ScenarioFactory.CreateScenarioConfig(generator, 1, 1);

var generatorResult = generator
.Generate(1, 1, DateTime.UtcNow, config)
.First(x => x is AlvsClearanceRequest);

var internalClearanceRequest = AlvsClearanceRequestMapper.Map((AlvsClearanceRequest)generatorResult);
var movement = movementBuilder

var movement = movementBuilderFactory
.From(internalClearanceRequest)
.Build();

Expand All @@ -70,7 +71,7 @@ private static (List<ImportNotification> Notifications, List<Movement> Movements
ChedASimpleMatchScenarioGenerator generator =
new ChedASimpleMatchScenarioGenerator(NullLogger<ChedASimpleMatchScenarioGenerator>.Instance);
var config = ScenarioFactory.CreateScenarioConfig(generator, 1, 1);
var movementBuilder = new MovementBuilder(NullLogger<MovementBuilder>.Instance);
var movementBuilderFactory = new MovementBuilderFactory(NullLogger<MovementBuilder>.Instance);

var generatorResult = generator.Generate(1, 1, DateTime.UtcNow, config);

Expand All @@ -89,7 +90,7 @@ private static (List<ImportNotification> Notifications, List<Movement> Movements
case AlvsClearanceRequest cr:

var internalClearanceRequest = AlvsClearanceRequestMapper.Map(cr);
memo.Movements.Add(movementBuilder.From(internalClearanceRequest).Build());
memo.Movements.Add(movementBuilderFactory.From(internalClearanceRequest).Build());
break;
default:
throw new ArgumentException($"Unexpected type {x.GetType().Name}");
Expand Down
60 changes: 4 additions & 56 deletions Btms.Business/Builders/MovementBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,62 +10,10 @@

namespace Btms.Business.Builders;

public class MovementBuilder(ILogger<MovementBuilder> logger)
public class MovementBuilder(ILogger<MovementBuilder> logger, Movement movement, bool hasChanges = false)
{
private Movement? _movement;
public bool HasChanges = false;

public MovementBuilder From(Model.Cds.CdsClearanceRequest request)
{
logger.LogInformation("Creating movement from clearance request {0}", request.Header!.EntryReference);
HasChanges = true;
_movement = new Movement()
{
Id = request.Header!.EntryReference,
UpdatedSource = request.ServiceHeader?.ServiceCalled,
CreatedSource = request.ServiceHeader?.ServiceCalled,
ArrivesAt = request.Header.ArrivesAt,
EntryReference = request.Header.EntryReference!,
EntryVersionNumber = request.Header.EntryVersionNumber.GetValueOrDefault(),
MasterUcr = request.Header.MasterUcr!,
DeclarationType = request.Header.DeclarationType!,
SubmitterTurn = request.Header.SubmitterTurn!,
DeclarantId = request.Header.DeclarantId!,
DeclarantName = request.Header.DeclarantName!,
DispatchCountryCode = request.Header.DispatchCountryCode!,
GoodsLocationCode = request.Header.GoodsLocationCode!,
ClearanceRequests = [request],
Items = request.Items?.ToList()!,
BtmsStatus = new MovementStatus()
{
ChedTypes = GetChedTypes(request.Items!.ToList()),
Linked = false,
LinkStatus = MovementStatus.NotLinkedStatus
}
};

return this;
}

public MovementBuilder From(Movement movement)
{
HasChanges = true;
_movement = movement;
return this;
}

private ImportNotificationTypeEnum[] GetChedTypes(List<Items>? items = null)
{
return items?
.SelectMany(i => i.Documents!)
.Select(d =>
d.DocumentCode!.GetChedType()
)
.Distinct()
.Where(ct => ct.HasValue())
.Select(ct => ct!.Value)
.ToArray()!;
}
private Movement? _movement = movement;
public bool HasChanges = hasChanges;

public string Id
{
Expand Down Expand Up @@ -100,7 +48,7 @@ public void ReplaceClearanceRequests(MovementBuilder builder)
builder._movement.ClearanceRequests[0].Header?.EntryReference);
_movement.ClearanceRequests.AddRange(builder._movement.ClearanceRequests);

_movement.Items.AddRange(builder._movement.Items);
_movement.Items = builder._movement.Items;
}

public ChangeSet GenerateChangeSet(MovementBuilder builder)
Expand Down
60 changes: 60 additions & 0 deletions Btms.Business/Builders/MovementBuilderFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using Btms.Common.Extensions;
using Btms.Model.Cds;
using Microsoft.Extensions.Logging;
using Btms.Business.Extensions;
using Btms.Model;
using Btms.Model.Ipaffs;

namespace Btms.Business.Builders;

public class MovementBuilderFactory(ILogger<MovementBuilder> logger)
{
public MovementBuilder From(CdsClearanceRequest request)
{
logger.LogInformation("Creating movement from clearance request {0}", request.Header!.EntryReference);
var movement = new Movement()
{
Id = request.Header!.EntryReference,
UpdatedSource = request.ServiceHeader?.ServiceCalled,
CreatedSource = request.ServiceHeader?.ServiceCalled,
ArrivesAt = request.Header.ArrivesAt,
EntryReference = request.Header.EntryReference!,
EntryVersionNumber = request.Header.EntryVersionNumber.GetValueOrDefault(),
MasterUcr = request.Header.MasterUcr!,
DeclarationType = request.Header.DeclarationType!,
SubmitterTurn = request.Header.SubmitterTurn!,
DeclarantId = request.Header.DeclarantId!,
DeclarantName = request.Header.DeclarantName!,
DispatchCountryCode = request.Header.DispatchCountryCode!,
GoodsLocationCode = request.Header.GoodsLocationCode!,
ClearanceRequests = [request],
Items = request.Items?.ToList()!,
BtmsStatus = new MovementStatus()
{
ChedTypes = GetChedTypes(request.Items!.ToList()),
Linked = false,
LinkStatus = MovementStatus.NotLinkedStatus
}
};

return new MovementBuilder(logger, movement, true);
}

public MovementBuilder From(Movement movement)
{
return new MovementBuilder(logger, movement, true);
}

private ImportNotificationTypeEnum[] GetChedTypes(List<Items>? items = null)
{
return items?
.SelectMany(i => i.Documents!)
.Select(d =>
d.DocumentCode!.GetChedType()
)
.Distinct()
.Where(ct => ct.HasValue())
.Select(ct => ct!.Value)
.ToArray()!;
}
}
2 changes: 1 addition & 1 deletion Btms.Business/Extensions/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static IServiceCollection AddBusinessServices(this IServiceCollection ser
services.AddScoped<IDecisionService, DecisionService>();
services.AddScoped<IMatchingService, MatchingService>();

services.AddTransient<MovementBuilder>();
services.AddTransient<MovementBuilderFactory>();
services.AddScoped<IPreProcessor<ImportNotification, Model.Ipaffs.ImportNotification>, ImportNotificationPreProcessor>();
services.AddScoped<IPreProcessor<AlvsClearanceRequest, Model.Movement>, MovementPreProcessor>();

Expand Down
10 changes: 5 additions & 5 deletions Btms.Business/Pipelines/PreProcessing/MovementPreProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

namespace Btms.Business.Pipelines.PreProcessing;

public class MovementPreProcessor(IMongoDbContext dbContext, ILogger<MovementPreProcessor> logger, MovementBuilder movementBuilder) : IPreProcessor<AlvsClearanceRequest, Movement>
public class MovementPreProcessor(IMongoDbContext dbContext, ILogger<MovementPreProcessor> logger, MovementBuilderFactory movementBuilderFactory) : IPreProcessor<AlvsClearanceRequest, Movement>
{
public async Task<PreProcessingResult<Movement>> Process(PreProcessingContext<AlvsClearanceRequest> preProcessingContext)
{

var internalClearanceRequest = AlvsClearanceRequestMapper.Map(preProcessingContext.Message);
var mb = movementBuilder.From(internalClearanceRequest);
var mb = movementBuilderFactory.From(internalClearanceRequest);
var existingMovement = await dbContext.Movements.Find(mb.Id);

if (existingMovement is null)
Expand All @@ -36,17 +36,17 @@ public async Task<PreProcessingResult<Movement>> Process(PreProcessingContext<Al
// if (movement.ClearanceRequests[^1].Header?.EntryVersionNumber > existingMovement.ClearanceRequests[0].Header?.EntryVersionNumber)
if (mb.IsEntryVersionNumberGreaterThan(existingMovement.ClearanceRequests[0].Header?.EntryVersionNumber))
{
var existingBuilder = movementBuilder.From(existingMovement);
var existingBuilder = movementBuilderFactory.From(existingMovement);
// var changeSet = movement.ClearanceRequests[^1].GenerateChangeSet(existingMovement.ClearanceRequests[0]);
var changeSet = existingBuilder.GenerateChangeSet(mb);
var changeSet = mb.GenerateChangeSet(existingBuilder);

var auditEntry = mb.UpdateAuditEntry(
preProcessingContext.MessageId,
AuditEntry.CreatedByCds,
changeSet
);

mb.Update(auditEntry);
existingBuilder.Update(auditEntry);

existingBuilder.ReplaceClearanceRequests(mb);

Expand Down
12 changes: 5 additions & 7 deletions Btms.Consumers.Tests/ClearanceRequestConsumerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ public async Task WhenPreProcessingSucceeds_AndLastAuditEntryIsLinked_ThenLinkSh
{
// ARRANGE
var clearanceRequest = CreateAlvsClearanceRequest();
var movementBuilder = new MovementBuilder(NullLogger<MovementBuilder>.Instance);
var mb =
movementBuilder.From(AlvsClearanceRequestMapper.Map(clearanceRequest));
var mbFactory = new MovementBuilderFactory(NullLogger<MovementBuilder>.Instance);
var mb = mbFactory.From(AlvsClearanceRequestMapper.Map(clearanceRequest));

movementBuilder.Update(AuditEntry.CreateLinked("Test", 1));
mb.Update(AuditEntry.CreateLinked("Test", 1));

var movement = mb.Build();

Expand Down Expand Up @@ -67,11 +66,10 @@ public async Task WhenPreProcessingSucceeds_AndLastAuditEntryIsLinked_ThenLinkSh
public async Task WhenPreProcessingSucceeds_AndLastAuditEntryIsCreated_ThenLinkShouldBeRun()
{
// ARRANGE
var movementBuilder = new MovementBuilder(NullLogger<MovementBuilder>.Instance);
var mbFactory = new MovementBuilderFactory(NullLogger<MovementBuilder>.Instance);
var clearanceRequest = CreateAlvsClearanceRequest();

var mb =
movementBuilder.From(AlvsClearanceRequestMapper.Map(clearanceRequest));
var mb = mbFactory.From(AlvsClearanceRequestMapper.Map(clearanceRequest));

mb.Update(mb.CreateAuditEntry("Test", AuditEntry.CreatedByCds));

Expand Down
4 changes: 2 additions & 2 deletions Btms.Consumers/DecisionsConsumer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Btms.Consumers;

public class DecisionsConsumer(IMongoDbContext dbContext, MovementBuilder existingMovementBuilder)
public class DecisionsConsumer(IMongoDbContext dbContext, MovementBuilderFactory movementBuilderFactory)
: IConsumer<Decision>, IConsumerWithContext
{
public async Task OnHandle(Decision message)
Expand All @@ -21,7 +21,7 @@ public async Task OnHandle(Decision message)
var auditId = Context.Headers["messageId"].ToString();
var notificationContext = Context.Headers.GetValueOrDefault("notifications", null) as List<DecisionImportNotifications>;

existingMovementBuilder = existingMovementBuilder
var existingMovementBuilder = movementBuilderFactory
.From(existingMovement!)
.MergeDecision(auditId!, internalClearanceRequest, notificationContext);
// .Build();
Expand Down
2 changes: 1 addition & 1 deletion Btms.Model/Auditing/AuditEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public bool IsCreated()

public bool IsUpdated()
{
return Status == "Created";
return Status == "Updated";
}


Expand Down

0 comments on commit f77b026

Please sign in to comment.