commit 47db00b826ad5066bd0cc70f301bae8ded54946b
Author: Silentkiller159 <milanhotovec@seznam.cz>
Date:   Tue Jun 1 23:49:59 2021 +0200

    Locking update

diff --git a/src/Core/Domain/Leuze.Core.Domain/Repositories/IDomainUserRepository.cs b/src/Core/Domain/Leuze.Core.Domain/Repositories/IDomainUserRepository.cs
index c990164..f447828 100644
--- a/src/Core/Domain/Leuze.Core.Domain/Repositories/IDomainUserRepository.cs
+++ b/src/Core/Domain/Leuze.Core.Domain/Repositories/IDomainUserRepository.cs
@@ -87,6 +87,13 @@ namespace Leuze.Core.Domain.Repositories
         /// <returns></returns>
         Task<List<UserShortDto>> GetAllUsersForTL(Guid id);
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        Task<List<UserShortDto>> GetAllTLsForUser(Guid id);
+
         /// <summary>
         /// 
         /// </summary>
diff --git a/src/Core/Infrastructure/Leuze.Core.Infrastructure.Persistence/Repository/DomainUserRepository.cs b/src/Core/Infrastructure/Leuze.Core.Infrastructure.Persistence/Repository/DomainUserRepository.cs
index 52414e4..a24b692 100644
--- a/src/Core/Infrastructure/Leuze.Core.Infrastructure.Persistence/Repository/DomainUserRepository.cs
+++ b/src/Core/Infrastructure/Leuze.Core.Infrastructure.Persistence/Repository/DomainUserRepository.cs
@@ -33,7 +33,7 @@ namespace Leuze.Core.Infrastructure.Persistence.Repository
 
         /// <inheritdoc/>
         public async Task<DomainUser> GetByIdAsync(Guid id)
-            => await dbSet.SingleOrDefaultAsync(o => o.UserId == id);
+            => await dbSet.Include(o => o.SeniorUser).SingleOrDefaultAsync(o => o.UserId == id);
 
         /// <inheritdoc/>
         public async Task<DomainUser?> GetOptionalByIdAsync(Guid? ownerId)
@@ -135,6 +135,25 @@ namespace Leuze.Core.Infrastructure.Persistence.Repository
             return result.ToList();
         }
 
+        /// <inheritdoc/>
+        public async Task<List<UserShortDto>> GetAllTLsForUser(Guid id)
+        {
+            var results = new HashSet<UserShortDto>();
+            var curr = await GetDtoByIdAsync(id);
+
+            while (curr.SeniorId != null)
+            {
+                curr = await GetDtoByIdAsync(curr.SeniorId.Value);
+                if (!results.Contains(curr))
+                {
+                    results.Add(curr);
+                }
+            }
+
+
+            return results.ToList();
+        }
+
         /// <inheritdoc/>
         public async Task<UserShortDto> GetDtoByIdAsync(Guid id)
         {
diff --git a/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/GoalDefinitions/Commands/LockDefinition.cs b/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/GoalDefinitions/Commands/LockDefinition.cs
new file mode 100644
index 0000000..1c80fb2
--- /dev/null
+++ b/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/GoalDefinitions/Commands/LockDefinition.cs
@@ -0,0 +1,82 @@
+﻿using Leuze.Core.Application.CQRS;
+using Leuze.Core.Domain.Domains.Users.DTOs;
+using Leuze.Core.Domain.Repositories;
+using Leuze.Modules.Goal.Application.CQRS.GoalDefinitions.Queries;
+using Leuze.Modules.Goal.Domain.Domains;
+using Leuze.Modules.Goal.Domain.Repositories;
+using MediatR;
+using Microsoft.AspNetCore.Components.Authorization;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Leuze.Modules.Goal.Application.CQRS.GoalDefinitions.Commands
+{
+    public static class LockDefinition
+    {
+        public record Command(Guid definitionId) : IBaseRequest<Response>;
+
+        public record Response();
+
+
+        public class Handler : IBaseRequestHandler<Command, Response>
+        {
+            private readonly IGlobalDefinitionAreaRepository _globalDefinitionAreaRepo;
+            private readonly IGoalDefinitionRepository _goalDefinitionRepo;
+            private readonly AuthenticationStateProvider _authenticationStateProvider;
+            private readonly IDomainUserRepository _domainUserRepo;
+
+            public Handler(IGlobalDefinitionAreaRepository globalDefinitionAreaRepo, IGoalDefinitionRepository goalDefinitionRepo, AuthenticationStateProvider authStateProvider, IDomainUserRepository domainUserRepo)
+            {
+                _globalDefinitionAreaRepo = globalDefinitionAreaRepo;
+                _goalDefinitionRepo = goalDefinitionRepo;
+                _authenticationStateProvider = authStateProvider;
+                _domainUserRepo = domainUserRepo;
+            }
+
+            public async Task<RequestResponse<Response>> Handle(Command request, CancellationToken cancellationToken)
+            {
+                //TODO: user muze byt null, ale to my nechceme!!!
+                var state = await _authenticationStateProvider.GetAuthenticationStateAsync();
+                var id = Guid.Parse(state.User!.FindFirst(ClaimTypes.NameIdentifier)!.Value);
+                var editor = await _domainUserRepo.GetByIdAsync(id);
+                var definition = await _goalDefinitionRepo.GetByIdAsync(request.definitionId);
+
+                if (editor == null)
+                {
+                    return RequestResponse<Response>.CreateErrorResponse($"Creator user with id: {id} not found!");
+                }
+
+                if (definition == null)
+                {
+                    return RequestResponse<Response>.CreateErrorResponse($"Definition with id: {request.definitionId} not found!");
+                }
+
+
+                if (definition.OwnerId == id)
+                {
+                    definition.LockByOwner();
+
+                    await _goalDefinitionRepo.UpdateRepo();
+                    return RequestResponse<Response>.CreateSuccessResponse(new());
+                }
+
+                var tlList = await _domainUserRepo.GetAllTLsForUser(id);
+
+                if (tlList.Where(o => o.Id == id).Any())
+                {
+                    definition.LockBySupervisor();
+
+                    await _goalDefinitionRepo.UpdateRepo();
+                    return RequestResponse<Response>.CreateSuccessResponse(new());
+                }
+
+                return RequestResponse<Response>.CreateErrorResponse("Nothing changed!");
+            }
+        }
+    }
+}
diff --git a/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/Goals/Commands/EditGoal.cs b/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/Goals/Commands/EditGoal.cs
index be2098d..0eb304e 100644
--- a/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/Goals/Commands/EditGoal.cs
+++ b/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/Goals/Commands/EditGoal.cs
@@ -23,14 +23,16 @@ namespace Leuze.Modules.Goal.Application.CQRS.Goals.Commands
         public class Handler : IBaseRequestHandler<Command, Response>
         {
             private readonly IGoalItemRepository _goalItemRepo;
+            private readonly IGoalDefinitionRepository _goalDefinitionRepo;
             private readonly IGoalUpdateRepository _goalUpdateRepo;
             private readonly AuthenticationStateProvider _authenticationStateProvider;
             private readonly IDomainUserRepository _domainUserRepository;
 
-            public Handler(IGoalItemRepository goalItemRepo, IGoalUpdateRepository goalUpdateRepo, 
+            public Handler(IGoalItemRepository goalItemRepo, IGoalDefinitionRepository goalDefinitioNrepo, IGoalUpdateRepository goalUpdateRepo, 
                 AuthenticationStateProvider authenticationStateProvider, IDomainUserRepository domainUserRepository)
             {
                 _goalItemRepo = goalItemRepo;
+                _goalDefinitionRepo = goalDefinitioNrepo;
                 _goalUpdateRepo = goalUpdateRepo;
                 _authenticationStateProvider = authenticationStateProvider;
                 _domainUserRepository = domainUserRepository;
@@ -71,6 +73,8 @@ namespace Leuze.Modules.Goal.Application.CQRS.Goals.Commands
                     GoalUpdate nameUpdate = new(user, goal, UpdateType.Name, goal.Name, request.name);
 
                     await _goalItemRepo.SetNameAsync(request.goalId, request.name);
+                    await _goalItemRepo.LocksReset(request.goalId);
+                    await _goalDefinitionRepo.LocksReset(goal.GoalDefinitionId);
                     await _goalUpdateRepo.AddAsync(nameUpdate);
 
                     sendState = true;
@@ -81,6 +85,8 @@ namespace Leuze.Modules.Goal.Application.CQRS.Goals.Commands
                     GoalUpdate descUpdate = new(user, goal, UpdateType.Description, goal.Description, request.description);
 
                     await _goalItemRepo.SetDescriptionAsync(request.goalId, request.description);
+                    await _goalItemRepo.LocksReset(request.goalId);
+                    await _goalDefinitionRepo.LocksReset(goal.GoalDefinitionId);
                     await _goalUpdateRepo.AddAsync(descUpdate);
 
                     sendState = true;
diff --git a/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/Goals/Commands/LockGoal.cs b/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/Goals/Commands/LockGoal.cs
new file mode 100644
index 0000000..cf10834
--- /dev/null
+++ b/src/Modules/Goal/Application/Leuze.Modules.Goal.Application/CQRS/Goals/Commands/LockGoal.cs
@@ -0,0 +1,94 @@
+﻿using Leuze.Core.Application.CQRS;
+using Leuze.Core.Domain.Repositories;
+using Leuze.Modules.Goal.Domain.Domains;
+using Leuze.Modules.Goal.Domain.Repositories;
+using Microsoft.AspNetCore.Components.Authorization;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Leuze.Modules.Goal.Application.CQRS.Goals.Commands
+{
+    public static class LockGoal
+    {
+        public record Command(Guid goalId) : IBaseRequest<Response>;
+
+        public record Response();
+
+
+        public class Handler : IBaseRequestHandler<Command, Response>
+        {
+            private readonly IGoalItemRepository _goalItemRepo;
+            private readonly IGoalUpdateRepository _goalUpdateRepo;
+            private readonly AuthenticationStateProvider _authenticationStateProvider;
+            private readonly IDomainUserRepository _domainUserRepository;
+
+            public Handler(IGoalItemRepository goalItemRepo, IGoalUpdateRepository goalUpdateRepo,
+                AuthenticationStateProvider authenticationStateProvider, IDomainUserRepository domainUserRepository)
+            {
+                _goalItemRepo = goalItemRepo;
+                _goalUpdateRepo = goalUpdateRepo;
+                _authenticationStateProvider = authenticationStateProvider;
+                _domainUserRepository = domainUserRepository;
+            }
+
+            public async Task<RequestResponse<Response>> Handle(Command request, CancellationToken cancellationToken)
+            {
+                //TODO: user muze byt null, ale to my nechceme!!!
+                var state = await _authenticationStateProvider.GetAuthenticationStateAsync();
+                var id = Guid.Parse(state.User!.FindFirst(ClaimTypes.NameIdentifier)!.Value);
+                var user = await _domainUserRepository.GetByIdAsync(id);
+
+                var goal = await _goalItemRepo.GetByIdAsync(request.goalId);
+
+                if (user == null)
+                {
+                    return RequestResponse<Response>.CreateErrorResponse($"Uživatel s ID: {id} nebyl nalezen!");
+                }
+
+                if (goal == null)
+                {
+                    return RequestResponse<Response>.CreateErrorResponse($"Cíl s ID: {request.goalId} nebyl nalezen!");
+                }
+
+                if (goal.IsLocked())
+                {
+                    return RequestResponse<Response>.CreateErrorResponse($"Cíl s ID: {request.goalId} byl uzamčen proti přepsání!");
+                }
+
+                if (goal.GoalDefinition.IsLocked())
+                {
+                    return RequestResponse<Response>.CreateErrorResponse($"Definice s cílem je uzamčena proti přepsání!");
+                }
+
+                if(goal.GoalDefinition.OwnerId == id)
+                {
+                    GoalUpdate ownerUpdate = new(user, goal, UpdateType.OwnerLock, "true", goal.OwnerLocked.ToString());
+                    goal.LockByOwner();
+
+                    await _goalItemRepo.UpdateRepo();
+                    await _goalUpdateRepo.AddAsync(ownerUpdate);
+                    return RequestResponse<Response>.CreateSuccessResponse(new());
+                }
+
+                var tlList = await _domainUserRepository.GetAllTLsForUser(id);
+
+                if (tlList.Where(o => o.Id == id).Any())
+                {
+                    GoalUpdate supervisorUpdate = new(user, goal, UpdateType.OwnerLock, "true", goal.SupervisorLocked.ToString());
+                    goal.LockBySupervisor();
+
+                    await _goalItemRepo.UpdateRepo();
+                    await _goalUpdateRepo.AddAsync(supervisorUpdate);
+                    return RequestResponse<Response>.CreateSuccessResponse(new());
+                }
+
+                return RequestResponse<Response>.CreateErrorResponse($"Nic se nezměnilo!");
+            }
+        }
+    }
+}
diff --git a/src/Modules/Goal/Domain/Leuze.Modules.Goal.Domain/Domains/DTOs/CommentGenericConvertor.cs b/src/Modules/Goal/Domain/Leuze.Modules.Goal.Domain/Domains/DTOs/CommentGenericConvertor.cs
index 711313d..708f961 100644
--- a/src/Modules/Goal/Domain/Leuze.Modules.Goal.Domain/Domains/DTOs/CommentGenericConvertor.cs
+++ b/src/Modules/Goal/Domain/Leuze.Modules.Goal.Domain/Domains/DTOs/CommentGenericConvertor.cs
@@ -20,6 +20,10 @@ namespace Leuze.Modules.Goal.Domain.Domains.DTOs
                     return "UpdatedPercentileUser";
                 case UpdateType.PercentileFinal:
                     return "UpdatedPercentileFinal";
+                case UpdateType.OwnerLock:
+                    return "UpdatedOwnerLock";
+                case UpdateType.SupervisorLock:
+                    return "UpdatedSupervisorLock";
                 default:
                     return "NOT IMPLEMENTED";
             }
diff --git a/src/Modules/Goal/Domain/Leuze.Modules.Goal.Domain/Domains/UpdateType.cs b/src/Modules/Goal/Domain/Leuze.Modules.Goal.Domain/Domains/UpdateType.cs
index 577beea..69e467c 100644
--- a/src/Modules/Goal/Domain/Leuze.Modules.Goal.Domain/Domains/UpdateType.cs
+++ b/src/Modules/Goal/Domain/Leuze.Modules.Goal.Domain/Domains/UpdateType.cs
@@ -8,6 +8,6 @@ namespace Leuze.Modules.Goal.Domain.Domains
 {
     public enum UpdateType
     {
-        Name, Description, PercentileUser, PercentileFinal, None
+        Name, Description, PercentileUser, PercentileFinal, OwnerLock, SupervisorLock, None
     }
 }
