Skip to content

Commit

Permalink
Merge pull request #914 from Strongminds/feature/KITOSUDV-3812
Browse files Browse the repository at this point in the history
Feature/KITOSUDV-3812
  • Loading branch information
mrjsawdk authored Jan 16, 2023
2 parents 2c15768 + 7bd6a5a commit ef69c1a
Show file tree
Hide file tree
Showing 63 changed files with 1,200 additions and 348 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ private Maybe<OperationError> UpdateNoticePeriodMonthsUuid(ItContract contract,
private Maybe<OperationError> UpdateExternalReferences(ItContract contract, IEnumerable<UpdatedExternalReferenceProperties> externalReferences)
{
return _referenceService
.BatchUpdateExternalReferences(
.UpdateExternalReferences(
ReferenceRootType.Contract,
contract.Id,
externalReferences.ToList())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ private Result<DataProcessingRegistration, OperationError> PerformUpdates(DataPr

private Result<DataProcessingRegistration, OperationError> PerformReferencesUpdate(DataProcessingRegistration dpr, IEnumerable<UpdatedExternalReferenceProperties> externalReferences)
{
var updateResult = _referenceService.BatchUpdateExternalReferences(
var updateResult = _referenceService.UpdateExternalReferences(
ReferenceRootType.DataProcessingRegistration,
dpr.Id,
externalReferences.ToList());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
namespace Core.ApplicationServices.Model.Shared.Write
using System;

namespace Core.ApplicationServices.Model.Shared.Write
{
public class UpdatedExternalReferenceProperties
{
public Guid? Uuid { get; set; }
public string Title { get; set; }
public string DocumentId { get; set; }
public string Url { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion Core.ApplicationServices/References/IReferenceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ public interface IReferenceService
Result<IEnumerable<ExternalReference>, OperationFailure> DeleteBySystemUsageId(int usageId);
Result<IEnumerable<ExternalReference>, OperationFailure> DeleteByContractId(int contractId);
Result<IEnumerable<ExternalReference>, OperationFailure> DeleteByDataProcessingRegistrationId(int id);
Maybe<OperationError> BatchUpdateExternalReferences(ReferenceRootType rootType, int rootId, IEnumerable<UpdatedExternalReferenceProperties> externalReferences);
Maybe<OperationError> UpdateExternalReferences(ReferenceRootType rootType, int rootId, IEnumerable<UpdatedExternalReferenceProperties> externalReferences);
}
}
102 changes: 75 additions & 27 deletions Core.ApplicationServices/References/ReferenceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,30 +148,30 @@ private void RaiseRootUpdated(IEntityWithExternalReferences owner)
public Result<IEnumerable<ExternalReference>, OperationFailure> DeleteBySystemId(int systemId)
{
var system = _itSystemRepository.GetSystem(systemId);
return DeleteExternalReferences(system);
return DeleteExternalReferencesByRoot(system);
}

public Result<IEnumerable<ExternalReference>, OperationFailure> DeleteBySystemUsageId(int usageId)
{
var itSystemUsage = _systemUsageRepository.GetSystemUsage(usageId);
return DeleteExternalReferences(itSystemUsage);
return DeleteExternalReferencesByRoot(itSystemUsage);
}

public Result<IEnumerable<ExternalReference>, OperationFailure> DeleteByContractId(int contractId)
{
var contract = _contractRepository.GetById(contractId);
return DeleteExternalReferences(contract);
return DeleteExternalReferencesByRoot(contract);
}

public Result<IEnumerable<ExternalReference>, OperationFailure> DeleteByDataProcessingRegistrationId(int id)
{
return _dataProcessingRegistrationRepository
.GetById(id)
.Select(DeleteExternalReferences)
.Select(DeleteExternalReferencesByRoot)
.Match(r => r, () => OperationFailure.NotFound);
}

public Maybe<OperationError> BatchUpdateExternalReferences(
public Maybe<OperationError> UpdateExternalReferences(
ReferenceRootType rootType,
int rootId,
IEnumerable<UpdatedExternalReferenceProperties> externalReferences)
Expand All @@ -182,16 +182,26 @@ public Maybe<OperationError> BatchUpdateExternalReferences(
.GetRootEntity(rootId, rootType)
.Match(root =>
{
//Clear existing state
root.ClearMasterReference();
var deleteResult = DeleteExternalReferences(root);
var referenceList = externalReferences.ToList();
//External references with uuids not included in the update are going to be deleted
var uuidsToUpdateHashSet = referenceList
.Where(referenceToUpdate => referenceToUpdate.Uuid.HasValue)
.Select(referenceToUpdate => referenceToUpdate.Uuid)
.ToHashSet();
var referencesToDelete = root
.ExternalReferences
.Where(externalReference => !uuidsToUpdateHashSet.Contains(externalReference.Uuid));
//Delete all references not explicitly referenced by the input parameters
var deleteResult = DeleteExternalReferences(root, referencesToDelete);
if (deleteResult.Failed)
return new OperationError("Failed to delete old references", deleteResult.Error);
var newReferences = externalReferences.ToList();
if (newReferences.Any())
if (referenceList.Any())
{
var masterReferencesCount = newReferences.Count(x => x.MasterReference);
var masterReferencesCount = referenceList.Count(x => x.MasterReference);
switch (masterReferencesCount)
{
Expand All @@ -201,60 +211,98 @@ public Maybe<OperationError> BatchUpdateExternalReferences(
return new OperationError("Only one reference can be master reference", OperationFailure.BadInput);
}
foreach (var referenceProperties in newReferences)
foreach (var externalReferenceProperties in referenceList)
{
var result = AddReference(rootId, rootType, referenceProperties.Title, referenceProperties.DocumentId, referenceProperties.Url);
if (result.Failed)
return new OperationError($"Failed to add reference with data:{JsonConvert.SerializeObject(referenceProperties)}. Error:{result.Error.Message.GetValueOrEmptyString()}", result.Error.FailureType);
ExternalReference externalReference;
//Replace references, which are identified by the update using uuids
//If no existing reference is found by uuid, it is considered an input error
if (externalReferenceProperties.Uuid.HasValue)
{
var uuid = externalReferenceProperties.Uuid.Value;
var existingReferenceResult = _referenceRepository.GetByUuid(uuid);
if (existingReferenceResult.IsNone)
return new OperationError($"External reference with uuid: {uuid} was not found in the {rootType} with id: {root.Id}", OperationFailure.BadInput);
if (referenceProperties.MasterReference)
externalReference = existingReferenceResult.Value;
MapExternalReference(externalReferenceProperties, externalReference);
}
//If uuid is null a new reference is going to be created
else
{
var masterReferenceResult = root.SetMasterReference(result.Value);
if (masterReferenceResult.Failed)
return new OperationError($"Failed while setting the master reference:{masterReferenceResult.Error.Message.GetValueOrEmptyString()}", masterReferenceResult.Error.FailureType);
var addReferenceResult = AddReference(rootId, rootType, externalReferenceProperties.Title, externalReferenceProperties.DocumentId, externalReferenceProperties.Url);
if (addReferenceResult.Failed)
return new OperationError($"Failed to add reference with data:{JsonConvert.SerializeObject(externalReferenceProperties)}. Error:{addReferenceResult.Error.Message.GetValueOrEmptyString()}", addReferenceResult.Error.FailureType);
externalReference = addReferenceResult.Value;
}
if (!externalReferenceProperties.MasterReference)
continue;
var masterReferenceResult = root.SetMasterReference(externalReference);
if (masterReferenceResult.Failed)
return new OperationError($"Failed while setting the master reference:{masterReferenceResult.Error.Message.GetValueOrEmptyString()}", masterReferenceResult.Error.FailureType);
}
_referenceRepository.SaveRootEntity(root);
}
return Maybe<OperationError>.None;
}, () => new OperationError(OperationFailure.NotFound));

if (error.IsNone)
transaction.Commit();
else
transaction.Rollback();

return error;
}

private Result<IEnumerable<ExternalReference>, OperationFailure> DeleteExternalReferences(IEntityWithExternalReferences root)
private static void MapExternalReference(UpdatedExternalReferenceProperties updatedProperties,
ExternalReference externalReference)
{
externalReference.Title = updatedProperties.Title;
externalReference.ExternalReferenceId = updatedProperties.DocumentId;
externalReference.URL = updatedProperties.Url;
}

private Result<IEnumerable<ExternalReference>, OperationFailure> DeleteExternalReferencesByRoot(IEntityWithExternalReferences root)
{
if (root == null)
{
return OperationFailure.NotFound;
}

return DeleteExternalReferences(root, root.ExternalReferences);
}

private Result<IEnumerable<ExternalReference>, OperationFailure> DeleteExternalReferences(IEntityWithExternalReferences root, IEnumerable<ExternalReference> externalReferences)
{
if (!_authorizationContext.AllowModify(root))
{
return OperationFailure.Forbidden;
}

using var transaction = _transactionManager.Begin();
var systemExternalReferences = root.ExternalReferences.ToList();
var externalReferenceList = externalReferences.ToList();

if (systemExternalReferences.Count == 0)
if (externalReferenceList.Count == 0)
{
return systemExternalReferences;
return externalReferenceList;
}

foreach (var reference in systemExternalReferences)
foreach (var reference in externalReferenceList)
{
_domainEvents.Raise(new EntityBeingDeletedEvent<ExternalReference>(reference));
_referenceRepository.Delete(reference);
}

RaiseRootUpdated(root);
transaction.Commit();
return systemExternalReferences;

return Result<IEnumerable<ExternalReference>, OperationFailure>.Success(externalReferenceList);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ private Maybe<OperationError> UpdateSensitivePersonDataIds(ItSystemUsage systemU
private Result<ItSystemUsage, OperationError> PerformReferencesUpdate(ItSystemUsage systemUsage, IEnumerable<UpdatedExternalReferenceProperties> externalReferences)
{
//Clear existing state
var updateResult = _referenceService.BatchUpdateExternalReferences(
var updateResult = _referenceService.UpdateExternalReferences(
ReferenceRootType.SystemUsage,
systemUsage.Id,
externalReferences);
Expand Down
5 changes: 4 additions & 1 deletion Core.DomainModel/ExternalReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@

namespace Core.DomainModel
{
public class ExternalReference : Entity, ISystemModule, IContractModule, IDataProcessingModule
public class ExternalReference : Entity, ISystemModule, IContractModule, IDataProcessingModule, IHasUuid
{
public ExternalReference()
{
BrokenLinkReports = new List<BrokenLinkInExternalReference>();
Uuid = Guid.NewGuid();
}

public Guid Uuid { get; set; }

public int? Itcontract_Id { get; set; }
public virtual ItContract.ItContract ItContract { get; set; }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using Core.Abstractions.Types;
using Core.DomainModel;
using Core.DomainModel.References;
Expand All @@ -9,6 +10,7 @@ namespace Core.DomainServices.Repositories.Reference
public interface IReferenceRepository
{
Maybe<ExternalReference> Get(int referenceId);
Maybe<ExternalReference> GetByUuid(Guid uuid);
Maybe<IEntityWithExternalReferences> GetRootEntity(int id, ReferenceRootType rootType);
IQueryable<ExternalReference> GetByRootType(ReferenceRootType rootType);
void SaveRootEntity(IEntityWithExternalReferences root);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Core.Abstractions.Types;
using Core.DomainModel;
Expand All @@ -7,6 +8,7 @@
using Core.DomainModel.ItSystem;
using Core.DomainModel.ItSystemUsage;
using Core.DomainModel.References;
using Core.DomainServices.Extensions;


namespace Core.DomainServices.Repositories.Reference
Expand Down Expand Up @@ -53,6 +55,11 @@ public Maybe<ExternalReference> Get(int referenceId)
return _referenceRepository.GetByKey(referenceId);
}

public Maybe<ExternalReference> GetByUuid(Guid uuid)
{
return _referenceRepository.AsQueryable().ByUuid(uuid);
}

public Maybe<IEntityWithExternalReferences> GetRootEntity(int id, ReferenceRootType rootType)
{
return ResolveRepositoryOperations(rootType).Get(id);
Expand Down
8 changes: 8 additions & 0 deletions Infrastructure.DataAccess/Infrastructure.DataAccess.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -995,10 +995,15 @@
<Compile Include="Migrations\202301030910462_change_dpr_sub_data_processors.designer.cs">
<DependentUpon>202301030910462_change_dpr_sub_data_processors.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\202301120832587_added_uuid_to_external_reference.cs" />
<Compile Include="Migrations\202301120832587_added_uuid_to_external_reference.designer.cs">
<DependentUpon>202301120832587_added_uuid_to_external_reference.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\Configuration.cs" />
<Compile Include="Mapping\TerminationDeadlineTypeMap.cs" />
<Content Include="Migrations\SQLScripts\Manually run scripts to fix staging DB\Delete_Users_Other_Than_Preserved_Users.sql" />
<Content Include="Migrations\SQLScripts\Manually run scripts to fix staging DB\Get_Users_To_Preserve.sql" />
<EmbeddedResource Include="Migrations\SQLScripts\Patch_Uuid_ExternalReference.sql" />
<Compile Include="Services\DatabaseTransaction.cs" />
<Compile Include="Services\EntityFrameworkContextDatabaseControl.cs" />
<Compile Include="Services\PocoTypeFromProxyResolver.cs" />
Expand All @@ -1012,6 +1017,9 @@
<EmbeddedResource Include="Migrations\202301030910462_change_dpr_sub_data_processors.resx">
<DependentUpon>202301030910462_change_dpr_sub_data_processors.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Migrations\202301120832587_added_uuid_to_external_reference.resx">
<DependentUpon>202301120832587_added_uuid_to_external_reference.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Migrations\SQLScripts\Dpr_Migrate_SubDataProcessors.sql" />
</ItemGroup>
<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions Infrastructure.DataAccess/KitosContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Configurations.Add(new StsOrganizationChangeLogMap());
modelBuilder.Configurations.Add(new StsOrganizationConsequenceLogMap());
modelBuilder.Configurations.Add(new SubDataProcessorMap());
modelBuilder.Configurations.Add(new ExternalReferenceMap());
}
}
}
13 changes: 9 additions & 4 deletions Infrastructure.DataAccess/Mapping/ExternalReferenceMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ namespace Infrastructure.DataAccess.Mapping
public class ExternalReferenceMap : EntityMap<ExternalReference>
{
public ExternalReferenceMap() {
this.ToTable("ExternalReferences");
this.Property(t => t.Itcontract_Id).HasColumnName("ItContract_Id").IsOptional();
this.Property(t => t.ItSystemUsage_Id).HasColumnName("ItSystemUsage_Id").IsOptional();
this.Property(t => t.ItSystem_Id).HasColumnName("ItSystem_Id").IsOptional();
ToTable("ExternalReferences");

Property(t => t.Itcontract_Id).HasColumnName("ItContract_Id").IsOptional();
Property(t => t.ItSystemUsage_Id).HasColumnName("ItSystemUsage_Id").IsOptional();
Property(t => t.ItSystem_Id).HasColumnName("ItSystem_Id").IsOptional();

Property(x => x.Uuid)
.IsRequired()
.HasUniqueIndexAnnotation("UX_ExternalReference_Uuid", 0);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ef69c1a

Please sign in to comment.