public async Task <CreateResult> Handle(GeoTaskCreateCommand command, CancellationToken cancellationToken) { if (command is null) { Logger.LogWarning(AppLogEvent.HandleArgumentError, "Handle create task got empty command"); return(ErrorResult("Empty Geo Task Create command")); } var validator = new GeoTaskCreateCommandValidator(); var validationResult = await validator .ValidateAsync(command) .ConfigureAwait(false); if (!validationResult.IsValid) { Logger.LogWarning(AppLogEvent.RequestValidationError, "Validation command error. Command = {command}. " + "Error = {Error}", command.ToDictionary(), validationResult.Errors); return(ErrorResult (validationResult.Errors.Select(x => x.ErrorMessage))); } try { var geoTask = new GeoTask() { CreatedAt = DateTime.UtcNow, Description = command.Description, StatusChangedAt = DateTime.UtcNow, IsArchived = command.IsArchived, PlanFinishAt = command.PlanFinishAt, PlanStartAt = command.PlanStartAt, Status = GeoTaskStatus.New, Title = command.Title, }; // Load from repository all mentioned actors var allActors = await GetActors( command.AssistentActorsIds .Concat(command.ObserverActorsIds) .Append(command.ResponsibleActorId) ).ConfigureAwait(false); // Add to the new entity only exist in the repository actors geoTask.AssistentActors.AddRange( command.AssistentActorsIds .Select(x => allActors .FirstOrDefault(a => a.Id == x)) .Where(a => a != null)); geoTask.ObserverActors.AddRange( command.ObserverActorsIds .Select(x => allActors .FirstOrDefault(a => a.Id == x)) .Where(a => a != null)); geoTask.ResponsibleActor = allActors .FirstOrDefault(a => a.Id == command.ResponsibleActorId); // Check that Geo Ids exist in repository geoTask.GeosIds.AddRange(await GetGeosIds(command.GeosIds) .ConfigureAwait(false)); // Get Actor for current user by user name var creatorResponse = await Mediator .Send(new DbGetActorByNameRequest (command.CurrentPrincipal?.Identity?.Name)) .ConfigureAwait(false); Actor createdBy = null; if (creatorResponse.Success) { createdBy = creatorResponse.Entity; } geoTask.CreatedBy = createdBy; Project project = await GetProject(command.ProjectId) .ConfigureAwait(false); geoTask.ProjectId = project?.Id; var historyRec = new GeoTaskHistory { ChangedAt = DateTime.UtcNow, ChangedBy = createdBy, }; historyRec.Operations.Add(new Operation { OperationType = addOperation, Path = "/", NewValue = geoTask.ToDictionary() }); geoTask.History.Add(historyRec); var validatorBeforeSave = new GeoTaskBeforeSaveValidator(); var validationBeforeSaveResult = await validatorBeforeSave .ValidateAsync(geoTask) .ConfigureAwait(false); if (!validationBeforeSaveResult.IsValid) { Logger.LogWarning(AppLogEvent.RequestNotValid, "GeoTask validation error. Entity={Entity}. " + "Error={Error}.", geoTask.ToDictionary(), validationBeforeSaveResult.Errors); return(ErrorResult(validationBeforeSaveResult.Errors .Select(x => x.ErrorMessage))); } var checkPermissionResult = await CheckPermission (geoTask, createdBy, project) .ConfigureAwait(false); if (!checkPermissionResult.Success) { Logger.LogWarning(AppLogEvent.SecurityNotPassed, "GeoTask check create permission error. " + "Entity={Entity}. CurrentActor={CurrentActor}. " + "Project={Project}. Error={Error}.", geoTask.ToDictionary(), createdBy?.ToDictionary(), project?.ToDictionary(), checkPermissionResult.Errors); return(checkPermissionResult); } return(await Mediator .Send(new DbCreateCommand <GeoTask>(geoTask)) .ConfigureAwait(false)); } catch (Exception e) { Logger.LogError(AppLogEvent.HandleErrorResponse, e, "Call repository exception"); return(ErrorResult("Not found")); } }
public async Task <UpdateResult> Handle(GeoTaskUpdateCommand command, CancellationToken cancellationToken) { try { Logger.LogInformation(AppLogEvent.HandleRequest, "Handle update task {Command}", command.ToDictionary()); if (command is null || string.IsNullOrWhiteSpace(command.Id)) { Logger.LogWarning(AppLogEvent.HandleArgumentError, "Handle update task command with empty request"); return(ErrorResult("Command empty argument")); } var validator = new GeoTaskUpdateCommandValidator(); var validationResult = await validator.ValidateAsync(command) .ConfigureAwait(false); if (!validationResult.IsValid) { var validationErrors = validationResult.Errors .Select(x => x.ErrorMessage).ToList(); Logger.LogWarning(AppLogEvent.HandleArgumentError, "Task update command validation error. " + "Command={Command}. Error={Error}", command.ToDictionary(), validationErrors); return(ErrorResult(validationErrors)); } var oldGeoTaskResponse = await Mediator .Send(new DbGetEntityByIdRequest <GeoTask>(command.Id)) .ConfigureAwait(false); if (!oldGeoTaskResponse.Success) { Logger.LogWarning(AppLogEvent.HandleErrorResponse, "Get task for update error. Id={Id}. Error={Error}.", command.Id, oldGeoTaskResponse.Errors); return(ErrorResult(oldGeoTaskResponse.Errors)); } var oldGeoTask = oldGeoTaskResponse.Entity; var currentActorResponse = await Mediator .Send(new DbGetActorByNameRequest (command.CurrentPrincipal?.Identity?.Name)) .ConfigureAwait(false); var currentActor = currentActorResponse.Entity; OldProject = await GetProjectAsync(oldGeoTask.ProjectId) .ConfigureAwait(false); // Check Project Id NewProject = null; if (command.ProjectId != OldProject?.Id) { NewProject = await GetProjectAsync(command.ProjectId) .ConfigureAwait(false); } else { NewProject = OldProject; } GeoTask newGeoTask = await BuildUpdatedGeoTask(command, oldGeoTask, currentActor).ConfigureAwait(false); var validatorBeforeSave = new GeoTaskBeforeSaveValidator(); var validationBeforeSaveResult = await validatorBeforeSave .ValidateAsync(newGeoTask) .ConfigureAwait(false); if (!validationBeforeSaveResult.IsValid) { Logger.LogWarning(AppLogEvent.RequestValidationError, "Update GeoTask validation error. " + "Entity={Entity}. Error={Error}.", newGeoTask.ToDictionary(), validationBeforeSaveResult.Errors); return(ErrorResult(validationBeforeSaveResult.Errors .Select(x => x.ErrorMessage))); } ActorRole oldProjectRole = null; OldProject?.ProjectActorRoles? .TryGetValue(currentActor.Id, out oldProjectRole); ActorRole newProjectRole = null; if (oldGeoTask.ProjectId != newGeoTask.ProjectId) { NewProject?.ProjectActorRoles? .TryGetValue(currentActor.Id, out newProjectRole); } else { newProjectRole = oldProjectRole; } var permissionValidateResult = await CheckPermissionAsync (oldGeoTask, newGeoTask, currentActor, oldProjectRole, newProjectRole) .ConfigureAwait(false); if (!permissionValidateResult.IsValid) { Logger.LogWarning(AppLogEvent.SecurityNotPassed, "Current actor has no rights to update GeoTask. " + "Actor={Actor}. Entity before update={OldEntity}." + " Entity after update={NewEntity}. Error={Error}.", currentActor.ToDictionary(), oldGeoTask.ToDictionary(), newGeoTask.ToDictionary(), permissionValidateResult.Errors .Select(x => x.ErrorMessage)); return(ErrorResult(permissionValidateResult.Errors .Select(x => x.ErrorMessage))); } var updateResult = await Mediator .Send(new DbUpdateCommand <GeoTask>(newGeoTask)) .ConfigureAwait(false); return(updateResult); } catch (Exception e) { Logger.LogError(AppLogEvent.HandleErrorResponse, e, "Geo task update exception"); return(ErrorResult("Geo task update exception")); } }