From 8ff71889700733c59d3e27c22ed875bcbad4800f Mon Sep 17 00:00:00 2001 From: Koen Metsu Date: Fri, 9 Aug 2024 15:34:19 +0200 Subject: [PATCH] feat: or-1394 add legal entity type field --- .../Magda/MagdaOrganisationResponse.cs | 18 ++++++++++++ .../Organisations/Organisation.cs | 20 ++++++++++++- .../OrganisationDocument.LegalEntityType.cs | 29 +++++++++++++++++++ .../Organisations/OrganisationDocument.cs | 8 +++++ .../Events/KboLegalEntityTypeAdded.cs | 20 +++++++++++++ .../IMagdaOrganisationResponse.cs | 7 +++++ .../KboOrganisationCommandHandlers.cs | 2 ++ .../Organisation/Organisation.cs | 15 ++++++++++ .../OrganisationHandlerTests.cs | 7 +++++ .../Kbo/CreateOrganisationFromKboTests.cs | 17 ++++++++++- ...nFromKboWithoutAddressAndLegalFormTests.cs | 2 +- .../Kbo/MockMagdaOrganisationResponse.cs | 3 ++ 12 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 src/OrganisationRegistry.ElasticSearch/Organisations/OrganisationDocument.LegalEntityType.cs create mode 100755 src/OrganisationRegistry/Organisation/Events/KboLegalEntityTypeAdded.cs diff --git a/src/OrganisationRegistry.Api/Infrastructure/Magda/MagdaOrganisationResponse.cs b/src/OrganisationRegistry.Api/Infrastructure/Magda/MagdaOrganisationResponse.cs index e6f631815..e1858f9d8 100644 --- a/src/OrganisationRegistry.Api/Infrastructure/Magda/MagdaOrganisationResponse.cs +++ b/src/OrganisationRegistry.Api/Infrastructure/Magda/MagdaOrganisationResponse.cs @@ -6,6 +6,7 @@ namespace OrganisationRegistry.Api.Infrastructure.Magda; using System.Linq; using global::Magda.GeefOnderneming; using Organisation; +using CodeSoortOndernemingType = global::Magda.ZoekOnderneming.CodeSoortOndernemingType; public class MagdaOrganisationResponse : IMagdaOrganisationResponse { @@ -30,6 +31,9 @@ public class MagdaOrganisationResponse : IMagdaOrganisationResponse public IMagdaTermination? Termination { get; } + public IMagdaLegalEntityType LegalEntityType { get; set; } + + public MagdaOrganisationResponse(Onderneming2_0Type? onderneming, IDateTimeProvider dateTimeProvider) { FormalName = new Name(onderneming?.Namen?.MaatschappelijkeNamen); @@ -65,6 +69,8 @@ public MagdaOrganisationResponse(Onderneming2_0Type? onderneming, IDateTimeProvi if (onderneming?.Stopzetting != null) Termination = new MagdaTermination(onderneming.Stopzetting); + + LegalEntityType = new MagdaLegalEntityType(onderneming?.SoortOnderneming.Code.Value, onderneming?.SoortOnderneming.Code.Value); } private static bool OverlapsWithToday(RechtsvormExtentieType type, DateTime today) @@ -214,3 +220,15 @@ public MagdaTermination(StopzettingExtentieType stopzetting) Reason = stopzetting.Code.Beschrijving ?? string.Empty; } } + +public class MagdaLegalEntityType : IMagdaLegalEntityType +{ + public string Code { get; } + public string Description { get; } + + public MagdaLegalEntityType(string code, string description) + { + Code = code; + Description = description; + } +} diff --git a/src/OrganisationRegistry.ElasticSearch.Projections/Organisations/Organisation.cs b/src/OrganisationRegistry.ElasticSearch.Projections/Organisations/Organisation.cs index 40ef45233..8633665ad 100644 --- a/src/OrganisationRegistry.ElasticSearch.Projections/Organisations/Organisation.cs +++ b/src/OrganisationRegistry.ElasticSearch.Projections/Organisations/Organisation.cs @@ -41,7 +41,8 @@ public class Organisation : IElasticEventHandler, IElasticEventHandler, IElasticEventHandler, - IElasticEventHandler + IElasticEventHandler, + IElasticEventHandler { private readonly Elastic _elastic; private readonly ElasticSearchConfiguration _elasticSearchOptions; @@ -120,6 +121,23 @@ public async Task Handle( } ).ToAsyncResult(); + public async Task Handle( + DbConnection dbConnection, + DbTransaction dbTransaction, + IEnvelope message) + => await new ElasticPerDocumentChange( + message.Body.OrganisationId, + document => + { + document.ChangeId = message.Number; + document.ChangeTime = message.Timestamp; + + document.LegalEntityType = new LegalEntityType( + message.Body.LegalEntityTypeCode, + message.Body.LegalEntityTypeDescription); + } + ).ToAsyncResult(); + public async Task Handle( DbConnection dbConnection, DbTransaction dbTransaction, diff --git a/src/OrganisationRegistry.ElasticSearch/Organisations/OrganisationDocument.LegalEntityType.cs b/src/OrganisationRegistry.ElasticSearch/Organisations/OrganisationDocument.LegalEntityType.cs new file mode 100644 index 000000000..e02ff6aec --- /dev/null +++ b/src/OrganisationRegistry.ElasticSearch/Organisations/OrganisationDocument.LegalEntityType.cs @@ -0,0 +1,29 @@ +namespace OrganisationRegistry.ElasticSearch.Organisations; + +using Osc; + +public class LegalEntityType +{ + public LegalEntityType(string code, string description) + { + Code = code; + Description = description; + } + + public LegalEntityType() + { + Code = string.Empty; + Description = string.Empty; + } + + public string Code { get; set; } + public string Description { get; set; } + + public static IPromise Mapping(PropertiesDescriptor map) + => map + .Keyword( + k => k + .Name(p => p.Code)).Keyword( + k => k + .Name(p => p.Description)); +} diff --git a/src/OrganisationRegistry.ElasticSearch/Organisations/OrganisationDocument.cs b/src/OrganisationRegistry.ElasticSearch/Organisations/OrganisationDocument.cs index 98f9aa9d5..d11fb7288 100644 --- a/src/OrganisationRegistry.ElasticSearch/Organisations/OrganisationDocument.cs +++ b/src/OrganisationRegistry.ElasticSearch/Organisations/OrganisationDocument.cs @@ -30,9 +30,12 @@ public OrganisationDocument() BankAccounts = new List(); OpeningHours = new List(); Regulations = new List(); + LegalEntityType = null; Validity = Period.Infinite(); } + public LegalEntityType? LegalEntityType { get; set; } + public int ChangeId { get; set; } public DateTimeOffset ChangeTime { get; set; } public Guid Id { get; set; } @@ -191,5 +194,10 @@ public static TypeMappingDescriptor Mapping( .Name(p => p.Regulations) .IncludeInRoot() .Properties(OrganisationRegulation.Mapping)) + .Nested( + n => n + .Name(p => p.LegalEntityType) + .IncludeInRoot() + .Properties(LegalEntityType.Mapping)) ); } diff --git a/src/OrganisationRegistry/Organisation/Events/KboLegalEntityTypeAdded.cs b/src/OrganisationRegistry/Organisation/Events/KboLegalEntityTypeAdded.cs new file mode 100755 index 000000000..a26e361eb --- /dev/null +++ b/src/OrganisationRegistry/Organisation/Events/KboLegalEntityTypeAdded.cs @@ -0,0 +1,20 @@ +namespace OrganisationRegistry.Organisation.Events; + +using System; +using Infrastructure; +using Newtonsoft.Json; + +public class KboLegalEntityTypeAdded : BaseEvent +{ + public KboLegalEntityTypeAdded(Guid organisationId, string legalEntityTypeCode, string legalEntityTypeDescription) + { + Id = organisationId; + LegalEntityTypeCode = legalEntityTypeCode; + LegalEntityTypeDescription = legalEntityTypeDescription; + } + + public Guid OrganisationId => Id; + + public string LegalEntityTypeCode { get; } + public string LegalEntityTypeDescription { get; } +} diff --git a/src/OrganisationRegistry/Organisation/IMagdaOrganisationResponse.cs b/src/OrganisationRegistry/Organisation/IMagdaOrganisationResponse.cs index 39badfa46..a0dadc56e 100755 --- a/src/OrganisationRegistry/Organisation/IMagdaOrganisationResponse.cs +++ b/src/OrganisationRegistry/Organisation/IMagdaOrganisationResponse.cs @@ -12,6 +12,7 @@ public interface IMagdaOrganisationResponse IMagdaLegalForm? LegalForm { get; } IMagdaAddress? Address { get; } IMagdaTermination? Termination { get; } + IMagdaLegalEntityType LegalEntityType { get; } } public interface IMagdaName @@ -51,3 +52,9 @@ public interface IMagdaTermination string Code { get; } string Reason { get; } } + +public interface IMagdaLegalEntityType +{ + string Code { get; } + string Description { get; } +} diff --git a/src/OrganisationRegistry/Organisation/KboOrganisationCommandHandlers.cs b/src/OrganisationRegistry/Organisation/KboOrganisationCommandHandlers.cs index a20cf2f9b..d47cbec9a 100755 --- a/src/OrganisationRegistry/Organisation/KboOrganisationCommandHandlers.cs +++ b/src/OrganisationRegistry/Organisation/KboOrganisationCommandHandlers.cs @@ -302,6 +302,8 @@ private async Task CreateFromKbo(CreateOrganisationFromKbo command, IUser user) AddLabel(organisation, kboOrganisation); + organisation.AddKboLegalEntityType(kboOrganisation.LegalEntityType); + await Session.Commit(user); } diff --git a/src/OrganisationRegistry/Organisation/Organisation.cs b/src/OrganisationRegistry/Organisation/Organisation.cs index 9c49cd80c..04e1dbcf8 100755 --- a/src/OrganisationRegistry/Organisation/Organisation.cs +++ b/src/OrganisationRegistry/Organisation/Organisation.cs @@ -991,6 +991,16 @@ public void AddKboLegalFormOrganisationClassification(Guid organisationOrganisat validity.End)); } + public void AddKboLegalEntityType(IMagdaLegalEntityType kboOrganisationLegalEntityType) + { + ApplyChange( + new KboLegalEntityTypeAdded( + Id, + kboOrganisationLegalEntityType.Code, + kboOrganisationLegalEntityType.Description + )); + } + public void UpdateKboLegalFormOrganisationClassification( IKboOrganisationClassificationRetriever organisationClassificationRetriever, OrganisationClassificationType legalFormOrganisationClassificationType, @@ -3114,4 +3124,9 @@ public void Apply(OrganisationLocationRemoved evnt) { State.OrganisationLocations.Remove(State.OrganisationLocations[evnt.OrganisationLocationId]); } + + public void Apply(KboLegalEntityTypeAdded evnt) + { + // no need to keep this in state at time of writing. + } } diff --git a/test/OrganisationRegistry.ElasticSearch.Tests/OrganisationHandlerTests.cs b/test/OrganisationRegistry.ElasticSearch.Tests/OrganisationHandlerTests.cs index 160c17c16..2924eca44 100644 --- a/test/OrganisationRegistry.ElasticSearch.Tests/OrganisationHandlerTests.cs +++ b/test/OrganisationRegistry.ElasticSearch.Tests/OrganisationHandlerTests.cs @@ -497,6 +497,8 @@ public async void LocationUpdated_UpdatesOrganisationLocation() var organisationLocationUpdated = scenario.CreateOrganisationLocationUpdated(organisationLocationAdded); var locationUpdated = scenario.CreateLocationUpdated(organisationLocationUpdated); + var kboLegalEntityTypeAdded = scenario.Create(); + await _eventProcessor.Handle( new List() { @@ -505,6 +507,7 @@ await _eventProcessor.Handle( organisationLocationAdded.ToEnvelope(), organisationLocationUpdated.ToEnvelope(), locationUpdated.ToEnvelope(), + kboLegalEntityTypeAdded.ToEnvelope(), } ); @@ -524,5 +527,9 @@ await _eventProcessor.Handle( locationUpdated.ZipCode, locationUpdated.City, locationUpdated.Country)); + + organisation.Source.LegalEntityType.Should().BeEquivalentTo(new LegalEntityType( + kboLegalEntityTypeAdded.LegalEntityTypeCode, + kboLegalEntityTypeAdded.LegalEntityTypeDescription)); } } diff --git a/test/OrganisationRegistry.UnitTests/Organisation/Kbo/CreateOrganisationFromKboTests.cs b/test/OrganisationRegistry.UnitTests/Organisation/Kbo/CreateOrganisationFromKboTests.cs index 5ccc4e631..467c8cdf0 100755 --- a/test/OrganisationRegistry.UnitTests/Organisation/Kbo/CreateOrganisationFromKboTests.cs +++ b/test/OrganisationRegistry.UnitTests/Organisation/Kbo/CreateOrganisationFromKboTests.cs @@ -319,9 +319,24 @@ await Given(Events) organisationLabelAdded.ValidTo.Should().Be(new ValidTo()); } + [Fact] + public async Task AddsLegalEntityType() + { + await Given(Events) + .When(CreateOrganisationFromKboCommand, TestUser.AlgemeenBeheerder) + .Then(); + + var organisationLabelAdded = PublishedEvents[9].UnwrapBody(); + organisationLabelAdded.Should().NotBeNull(); + + organisationLabelAdded.OrganisationId.Should().Be(_organisationId); + organisationLabelAdded.LegalEntityTypeCode.Should().Be("1"); + organisationLabelAdded.LegalEntityTypeDescription.Should().Be("Natuurlijke Persoon"); + } + [Fact] public async Task PublishesTheCorrectNumberOfEvents() => await Given(Events) .When(CreateOrganisationFromKboCommand, TestUser.AlgemeenBeheerder) - .ThenItPublishesTheCorrectNumberOfEvents(9); + .ThenItPublishesTheCorrectNumberOfEvents(10); } diff --git a/test/OrganisationRegistry.UnitTests/Organisation/Kbo/CreateOrganisationFromKboWithoutAddressAndLegalFormTests.cs b/test/OrganisationRegistry.UnitTests/Organisation/Kbo/CreateOrganisationFromKboWithoutAddressAndLegalFormTests.cs index 5487f6f32..fa379e8b2 100755 --- a/test/OrganisationRegistry.UnitTests/Organisation/Kbo/CreateOrganisationFromKboWithoutAddressAndLegalFormTests.cs +++ b/test/OrganisationRegistry.UnitTests/Organisation/Kbo/CreateOrganisationFromKboWithoutAddressAndLegalFormTests.cs @@ -262,5 +262,5 @@ await Given(Events) public async Task PublishesTheCorrectNumberOfEvents() => await Given(Events) .When(CreateOrganisationFromKboCommand, TestUser.AlgemeenBeheerder) - .ThenItPublishesTheCorrectNumberOfEvents(6); + .ThenItPublishesTheCorrectNumberOfEvents(7); } diff --git a/test/OrganisationRegistry.UnitTests/Organisation/Kbo/MockMagdaOrganisationResponse.cs b/test/OrganisationRegistry.UnitTests/Organisation/Kbo/MockMagdaOrganisationResponse.cs index 36396a818..8f31ff905 100755 --- a/test/OrganisationRegistry.UnitTests/Organisation/Kbo/MockMagdaOrganisationResponse.cs +++ b/test/OrganisationRegistry.UnitTests/Organisation/Kbo/MockMagdaOrganisationResponse.cs @@ -2,6 +2,7 @@ namespace OrganisationRegistry.UnitTests.Organisation.Kbo; using System; using System.Collections.Generic; +using Api.Infrastructure.Magda; using OrganisationRegistry.Organisation; public class MockMagdaOrganisationResponse : IMagdaOrganisationResponse @@ -13,10 +14,12 @@ public class MockMagdaOrganisationResponse : IMagdaOrganisationResponse public IMagdaLegalForm? LegalForm { get; set; } public IMagdaAddress? Address { get; set; } public IMagdaTermination? Termination { get; set; } + public IMagdaLegalEntityType LegalEntityType { get; } public MockMagdaOrganisationResponse() { + LegalEntityType = new MagdaLegalEntityType("1", "Natuurlijke Persoon"); BankAccounts = new List(); } }