-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #473 from Strongminds/release/11.2.4
Release/11.2.4
- Loading branch information
Showing
165 changed files
with
4,842 additions
and
1,019 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
Core.ApplicationServices/Extensions/OrganizationTreeUpdateConsequencesExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
using Core.Abstractions.Types; | ||
using Core.DomainModel.Organization; | ||
using Core.DomainServices.Context; | ||
using Core.DomainServices.Time; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace Core.ApplicationServices.Extensions | ||
{ | ||
public static class OrganizationTreeUpdateConsequencesExtensions | ||
{ | ||
public static ExternalConnectionAddNewLogInput ToLogEntries(this OrganizationTreeUpdateConsequences consequences, Maybe<ActiveUserIdContext> activeUserIdContext, IOperationClock operationClock) | ||
{ | ||
var changeLogType = ExternalOrganizationChangeLogResponsible.Background; | ||
int? changeLogUserId = null; | ||
if (activeUserIdContext.HasValue) | ||
{ | ||
var userId = activeUserIdContext.Value.ActiveUserId; | ||
changeLogType = ExternalOrganizationChangeLogResponsible.User; | ||
changeLogUserId = userId; | ||
} | ||
|
||
var changeLogEntries = consequences.ConvertConsequencesToConsequenceLogs().ToList(); | ||
var changeLogLogTime = operationClock.Now; | ||
|
||
return new ExternalConnectionAddNewLogInput(changeLogUserId, changeLogType, changeLogLogTime, MapToExternalConnectionAddNewLogEntryInput(changeLogEntries)); | ||
} | ||
|
||
private static IEnumerable<ExternalConnectionAddNewLogEntryInput> MapToExternalConnectionAddNewLogEntryInput(IEnumerable<StsOrganizationConsequenceLog> entry) | ||
{ | ||
return entry | ||
.Select(x => new ExternalConnectionAddNewLogEntryInput(x.ExternalUnitUuid, x.Name, x.Type, x.Description)) | ||
.ToList(); | ||
} | ||
|
||
public static IEnumerable<StsOrganizationConsequenceLog> ConvertConsequencesToConsequenceLogs(this OrganizationTreeUpdateConsequences consequences) | ||
{ | ||
var logs = new List<StsOrganizationConsequenceLog>(); | ||
logs.AddRange(MapAddedOrganizationUnits(consequences)); | ||
logs.AddRange(MapRenamedOrganizationUnits(consequences)); | ||
logs.AddRange(MapMovedOrganizationUnits(consequences)); | ||
logs.AddRange(MapRemovedOrganizationUnits(consequences)); | ||
logs.AddRange(MapConvertedOrganizationUnits(consequences)); | ||
|
||
return logs; | ||
} | ||
|
||
private static IEnumerable<StsOrganizationConsequenceLog> MapConvertedOrganizationUnits(OrganizationTreeUpdateConsequences consequences) | ||
{ | ||
return consequences | ||
.DeletedExternalUnitsBeingConvertedToNativeUnits | ||
.Select(converted => new StsOrganizationConsequenceLog | ||
{ | ||
Name = converted.organizationUnit.Name, | ||
Type = ConnectionUpdateOrganizationUnitChangeType.Converted, | ||
ExternalUnitUuid = converted.externalOriginUuid, | ||
Description = $"'{converted.organizationUnit.Name}' er slettet i FK Organisation men konverteres til KITOS enhed, da den anvendes aktivt i KITOS." | ||
}) | ||
.ToList(); | ||
} | ||
|
||
private static IEnumerable<StsOrganizationConsequenceLog> MapRemovedOrganizationUnits(OrganizationTreeUpdateConsequences consequences) | ||
{ | ||
return consequences | ||
.DeletedExternalUnitsBeingDeleted | ||
.Select(deleted => new StsOrganizationConsequenceLog | ||
{ | ||
Name = deleted.organizationUnit.Name, | ||
Type = ConnectionUpdateOrganizationUnitChangeType.Deleted, | ||
ExternalUnitUuid = deleted.externalOriginUuid, | ||
Description = $"'{deleted.organizationUnit.Name}' slettes." | ||
}) | ||
.ToList(); | ||
} | ||
|
||
private static IEnumerable<StsOrganizationConsequenceLog> MapMovedOrganizationUnits(OrganizationTreeUpdateConsequences consequences) | ||
{ | ||
return consequences | ||
.OrganizationUnitsBeingMoved | ||
.Select(moved => | ||
{ | ||
var (movedUnit, oldParent, newParent) = moved; | ||
return new StsOrganizationConsequenceLog | ||
{ | ||
Name = movedUnit.Name, | ||
Type = ConnectionUpdateOrganizationUnitChangeType.Moved, | ||
ExternalUnitUuid = movedUnit.ExternalOriginUuid.GetValueOrDefault(), | ||
Description = $"'{movedUnit.Name}' flyttes fra at være underenhed til '{oldParent.Name}' til fremover at være underenhed for {newParent.Name}" | ||
}; | ||
}) | ||
.ToList(); | ||
} | ||
|
||
private static IEnumerable<StsOrganizationConsequenceLog> MapRenamedOrganizationUnits(OrganizationTreeUpdateConsequences consequences) | ||
{ | ||
return consequences | ||
.OrganizationUnitsBeingRenamed | ||
.Select(renamed => | ||
{ | ||
var (affectedUnit, oldName, newName) = renamed; | ||
return new StsOrganizationConsequenceLog | ||
{ | ||
Name = oldName, | ||
Type = ConnectionUpdateOrganizationUnitChangeType.Renamed, | ||
ExternalUnitUuid = affectedUnit.ExternalOriginUuid.GetValueOrDefault(), | ||
Description = $"'{oldName}' omdøbes til '{newName}'" | ||
}; | ||
}) | ||
.ToList(); | ||
} | ||
|
||
private static IEnumerable<StsOrganizationConsequenceLog> MapAddedOrganizationUnits(OrganizationTreeUpdateConsequences consequences) | ||
{ | ||
return consequences | ||
.AddedExternalOrganizationUnits | ||
.Select(added => new StsOrganizationConsequenceLog | ||
{ | ||
Name = added.unitToAdd.Name, | ||
Type = ConnectionUpdateOrganizationUnitChangeType.Added, | ||
ExternalUnitUuid = added.unitToAdd.Uuid, | ||
Description = $"'{added.unitToAdd.Name}' tilføjes som underenhed til '{added.parent?.Name}'" | ||
} | ||
) | ||
.ToList(); | ||
} | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...tionServices/Model/Organizations/AuthorizedUpdateOrganizationFromFKOrganisationCommand.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using Core.Abstractions.Types; | ||
using Core.DomainModel.Commands; | ||
using Core.DomainModel.Organization; | ||
|
||
namespace Core.ApplicationServices.Model.Organizations | ||
{ | ||
/// <summary> | ||
/// Describes a pre-authorized update command for the FK Org synchronization. | ||
/// Make sure to authorize the call prior to executing this command | ||
/// </summary> | ||
public class AuthorizedUpdateOrganizationFromFKOrganisationCommand : ICommand | ||
{ | ||
public bool SubscribeToChanges { get; } | ||
public Maybe<int> SynchronizationDepth { get; } | ||
public Organization Organization { get; } | ||
public Maybe<ExternalOrganizationUnit> PreloadedExternalTree { get; } | ||
|
||
public AuthorizedUpdateOrganizationFromFKOrganisationCommand(Organization organization, Maybe<int> synchronizationDepth, bool subscribeToChanges, Maybe<ExternalOrganizationUnit> preloadedExternalTree) | ||
{ | ||
SubscribeToChanges = subscribeToChanges; | ||
PreloadedExternalTree = preloadedExternalTree; | ||
SynchronizationDepth = synchronizationDepth; | ||
Organization = organization; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
...es/Organizations/Handlers/AuthorizedUpdateOrganizationFromFKOrganisationCommandHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
using Core.Abstractions.Types; | ||
using Core.ApplicationServices.Model.Organizations; | ||
using Core.DomainModel.Commands; | ||
using Core.DomainModel.Events; | ||
using Core.DomainModel.Organization; | ||
using System; | ||
using System.Linq; | ||
using Core.ApplicationServices.Extensions; | ||
using Core.DomainServices; | ||
using Core.DomainServices.Organizations; | ||
using Infrastructure.Services.DataAccess; | ||
using Serilog; | ||
using Core.DomainServices.Context; | ||
using Core.DomainServices.Time; | ||
|
||
namespace Core.ApplicationServices.Organizations.Handlers | ||
{ | ||
public class AuthorizedUpdateOrganizationFromFKOrganisationCommandHandler : ICommandHandler<AuthorizedUpdateOrganizationFromFKOrganisationCommand, Maybe<OperationError>> | ||
{ | ||
private readonly IStsOrganizationUnitService _stsOrganizationUnitService; | ||
private readonly IGenericRepository<OrganizationUnit> _organizationUnitRepository; | ||
private readonly ILogger _logger; | ||
private readonly IDomainEvents _domainEvents; | ||
private readonly IDatabaseControl _databaseControl; | ||
private readonly ITransactionManager _transactionManager; | ||
private readonly Maybe<ActiveUserIdContext> _userContext; | ||
private readonly IOperationClock _operationClock; | ||
private readonly IGenericRepository<StsOrganizationChangeLog> _stsChangeLogRepository; | ||
|
||
public AuthorizedUpdateOrganizationFromFKOrganisationCommandHandler( | ||
IStsOrganizationUnitService stsOrganizationUnitService, | ||
IGenericRepository<OrganizationUnit> organizationUnitRepository, | ||
ILogger logger, | ||
IDomainEvents domainEvents, | ||
IDatabaseControl databaseControl, | ||
ITransactionManager transactionManager, | ||
Maybe<ActiveUserIdContext> userContext, | ||
IOperationClock operationClock, | ||
IGenericRepository<StsOrganizationChangeLog> stsChangeLogRepository) | ||
{ | ||
_stsOrganizationUnitService = stsOrganizationUnitService; | ||
_organizationUnitRepository = organizationUnitRepository; | ||
_logger = logger; | ||
_domainEvents = domainEvents; | ||
_databaseControl = databaseControl; | ||
_transactionManager = transactionManager; | ||
_userContext = userContext; | ||
_operationClock = operationClock; | ||
_stsChangeLogRepository = stsChangeLogRepository; | ||
} | ||
|
||
public Maybe<OperationError> Execute(AuthorizedUpdateOrganizationFromFKOrganisationCommand command) | ||
{ | ||
var organization = command.Organization; | ||
using var transaction = _transactionManager.Begin(); | ||
try | ||
{ | ||
//Load the external tree if not already provided | ||
var organizationTree = command | ||
.PreloadedExternalTree | ||
.Match(tree => tree, () => _stsOrganizationUnitService.ResolveOrganizationTree(organization)); | ||
|
||
if (organizationTree.Failed) | ||
{ | ||
var error = organizationTree.Error; | ||
_logger.Error("Unable to resolve external org tree for organization with uuid {uuid}. Failed with: {code}:{detail}:{message}", command.Organization.Uuid, error.FailureType, error.Detail, error.Message); | ||
return new OperationError($"Failed to resolve org tree:{error.Message.GetValueOrFallback("")}:{error.Detail:G}:{error.FailureType:G}", error.FailureType); | ||
} | ||
|
||
//Import the external tree into the organization | ||
var updateResult = organization.UpdateConnectionToExternalOrganizationHierarchy(OrganizationUnitOrigin.STS_Organisation, organizationTree.Value, command.SynchronizationDepth, command.SubscribeToChanges); | ||
if (updateResult.Failed) | ||
{ | ||
var error = updateResult.Error; | ||
_logger.Error("Failed importing org tree for organization with uuid {uuid}. Failed with: {code}:{message}", command.Organization.Uuid, error.FailureType, error.Message); | ||
transaction.Rollback(); | ||
return new OperationError($"Failed to import org tree:{error.Message.GetValueOrFallback("")}:{error.FailureType:G}", error.FailureType); | ||
} | ||
|
||
//React on import consequences | ||
var consequences = updateResult.Value; | ||
|
||
if (consequences.DeletedExternalUnitsBeingDeleted.Any()) | ||
{ | ||
_organizationUnitRepository.RemoveRange(consequences.DeletedExternalUnitsBeingDeleted.Select(x => x.organizationUnit).ToList()); | ||
} | ||
foreach (var (affectedUnit, _, _) in consequences.OrganizationUnitsBeingRenamed) | ||
{ | ||
_domainEvents.Raise(new EntityUpdatedEvent<OrganizationUnit>(affectedUnit)); | ||
} | ||
|
||
if (IsBackgroundImport()) | ||
{ | ||
organization.StsOrganizationConnection.DateOfLatestCheckBySubscription = DateTime.Now; | ||
} | ||
|
||
var logEntries = consequences.ToLogEntries(_userContext, _operationClock); | ||
|
||
//We only add a change log entry if any changes were detected | ||
if (logEntries.Entries.Any()) | ||
{ | ||
var addLogResult = organization.AddExternalImportLog(OrganizationUnitOrigin.STS_Organisation, logEntries); | ||
if (addLogResult.Failed) | ||
{ | ||
var error = addLogResult.Error; | ||
_logger.Error("Failed adding change log while importing org tree for organization with uuid {uuid}. Failed with: {code}:{message}", command.Organization.Uuid, error.FailureType, error.Message); | ||
transaction.Rollback(); | ||
return error; | ||
} | ||
|
||
var addNewLogsResult = addLogResult.Value; | ||
var removedChangeLogs = addNewLogsResult.RemovedChangeLogs.OfType<StsOrganizationChangeLog>().ToList(); | ||
if (removedChangeLogs.Any()) | ||
{ | ||
_stsChangeLogRepository.RemoveRange(removedChangeLogs); | ||
} | ||
} | ||
|
||
_domainEvents.Raise(new EntityUpdatedEvent<Organization>(organization)); | ||
_databaseControl.SaveChanges(); | ||
transaction.Commit(); | ||
|
||
_domainEvents.Raise(new ExternalOrganizationConnectionUpdated(organization, organization.StsOrganizationConnection, logEntries)); | ||
|
||
return Maybe<OperationError>.None; | ||
|
||
} | ||
catch (Exception e) | ||
{ | ||
_logger.Error(e, "Exception during FK Org sync of organization with uuid:{uuid}", command.Organization.Uuid); | ||
transaction.Rollback(); | ||
return new OperationError("Exception during import", OperationFailure.UnknownError); | ||
} | ||
} | ||
|
||
private bool IsBackgroundImport() | ||
{ | ||
return _userContext.IsNone; | ||
} | ||
} | ||
} |
Oops, something went wrong.