diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardDetail/ProjectBoardDetailQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardDetail/ProjectBoardDetailQueryHandler.cs new file mode 100644 index 00000000..f10ee486 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardDetail/ProjectBoardDetailQueryHandler.cs @@ -0,0 +1,74 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardDetail; + +public record ProjectBoardDetailQuery(Guid SectionId) : IBaseQuery; + +public record ProjectBoardDetailResponse(List Users, string TotalTime); + +public record ProjectBoardDetailUserResponse +{ + public List Histories { get; set; } = new(); + public string UserFullName { get; set; } + public long UserId { get; set; } +} + +public class ProjectBoardDetailUserHistoryResponse +{ + public string Date { get; set; } + public string startTime { get; set; } + public string EndTime { get; set; } + public string TotalTime { get; set; } +} + +public class ProjectBoardDetailQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _programManagerDbContext; + + public ProjectBoardDetailQueryHandler(IProgramManagerDbContext programManagerDbContext) + { + _programManagerDbContext = programManagerDbContext; + } + + public async Task> Handle(ProjectBoardDetailQuery request, + CancellationToken cancellationToken) + { + var section = await _programManagerDbContext.TaskSections + .Include(x => x.Activities) + .FirstOrDefaultAsync(x => x.Id == request.SectionId, cancellationToken: cancellationToken); + + if (section == null) + return OperationResult.NotFound("بخش مورد نظر یافت نشد"); + + var userIds = section.Activities.Select(x => x.UserId).Distinct().ToList(); + + var usersDict = await _programManagerDbContext.Users + .Where(x => userIds.Contains(x.Id)) + .ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken); + + var totalTimeSpan = section.Activities + .Select(x => x.GetTimeSpent()) + .Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next)); + + var users = section.Activities.GroupBy(x => x.UserId).Select(x => + { + return new ProjectBoardDetailUserResponse() + { + UserId = x.Key, + UserFullName = usersDict[x.Key], + Histories = x.Select(h => new ProjectBoardDetailUserHistoryResponse() + { + Date = h.StartDate.ToFarsi(), + startTime = h.StartDate.ToString("HH:mm"), + EndTime = h.EndDate?.ToString("HH:mm") ?? "-", + TotalTime = h.GetTimeSpent().ToString(@"hh\:mm") + }).ToList() + }; + }).ToList(); + var response = new ProjectBoardDetailResponse(users, $"{totalTimeSpan.TotalHours}:{totalTimeSpan.Minutes:D2}"); + return OperationResult.Success(response); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQuery.cs index db180808..2d42152a 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQuery.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQuery.cs @@ -6,5 +6,5 @@ namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.Project public record ProjectBoardListQuery: IBaseQuery> { -} - + public TaskSectionStatus? Status { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs index 0edfdc0b..4ee9564e 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs @@ -1,6 +1,9 @@ +using GozareshgirProgramManager.Application._Common.Constants; using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Query.Internal; namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList; @@ -19,15 +22,24 @@ public class ProjectBoardListQueryHandler : IBaseQueryHandler x.CurrentAssignedUserId == currentUserId) + var queryable = _programManagerDbContext.TaskSections.AsNoTracking() .Where(x => x.InitialEstimatedHours > TimeSpan.Zero) .Include(x => x.Task) .ThenInclude(x => x.Phase) .ThenInclude(x => x.Project) .Include(x => x.Activities) - .Include(x => x.AdditionalTimes) - .ToListAsync(cancellationToken); + .Include(x => x.AdditionalTimes).AsQueryable(); + + if (!_authHelper.HasPermission(ProgramManagerPermissionCode.Board.All.ViewAll)) + { + queryable = queryable.Where(x => x.CurrentAssignedUserId == currentUserId); + } + if (request.Status != null) + { + queryable = queryable.Where(x => x.Status == request.Status); + } + + var data = await queryable.ToListAsync(cancellationToken); var activityUserIds = data.SelectMany(x => x.Activities).Select(a => a.UserId).Distinct().ToList(); var users = await _programManagerDbContext.Users.AsNoTracking() diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IAuthHelper.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IAuthHelper.cs index a41dad2b..314c5984 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IAuthHelper.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IAuthHelper.cs @@ -71,6 +71,10 @@ public interface IAuthHelper /// دریافت نام کامل کاربر جاری از Claims /// string? GetCurrentFullName(); + bool HasPermission(int permission); + List GetPermissions(); + + } diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/GozareshgirProgramManager.Domain.csproj b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/GozareshgirProgramManager.Domain.csproj index 9ae2365c..9b9a0605 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/GozareshgirProgramManager.Domain.csproj +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/GozareshgirProgramManager.Domain.csproj @@ -8,6 +8,7 @@ + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Tools.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Tools.cs index 0f1ed2da..a7ff25de 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Tools.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Tools.cs @@ -1,5 +1,7 @@ using System.Globalization; using System.Text.RegularExpressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Bson; using PersianTools.Core; @@ -1704,25 +1706,25 @@ public static class Tools // return Convert.ToBase64String(bsonData); //} ////بیسان هایی که بصورت لیست بودند استخراج میشود - //public static List DeserializeFromBsonList(string base64Data) - //{ - // byte[] data = Convert.FromBase64String(base64Data); + public static List DeserializeFromBsonList(string base64Data) + { + byte[] data = Convert.FromBase64String(base64Data); - // using MemoryStream memoryStream = new MemoryStream(data); - // using BsonDataReader reader = new BsonDataReader(memoryStream); - // reader.ReadRootValueAsArray = true; - // JsonSerializer serializer = new JsonSerializer(); - // return serializer.Deserialize>(reader); - //} - ////بیسان هایی که بصورت تکی بودند استخراج میشود - //public static T DeserializeFromBson(string base64Data) - //{ - // byte[] bsonData = Convert.FromBase64String(base64Data); - // using MemoryStream memoryStream = new MemoryStream(bsonData); - // using BsonDataReader bsonReader = new BsonDataReader(memoryStream); - // JsonSerializer serializer = new JsonSerializer(); - // return serializer.Deserialize(bsonReader); - //} + using MemoryStream memoryStream = new MemoryStream(data); + using BsonDataReader reader = new BsonDataReader(memoryStream); + reader.ReadRootValueAsArray = true; + JsonSerializer serializer = new JsonSerializer(); + return serializer.Deserialize>(reader); + } + //بیسان هایی که بصورت تکی بودند استخراج میشود + public static T DeserializeFromBson(string base64Data) + { + byte[] bsonData = Convert.FromBase64String(base64Data); + using MemoryStream memoryStream = new MemoryStream(bsonData); + using BsonDataReader bsonReader = new BsonDataReader(memoryStream); + JsonSerializer serializer = new JsonSerializer(); + return serializer.Deserialize(bsonReader); + } //public static TimeOnly CalculateOffset(ICollection shiftDetailsRegularShifts) //{ diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/AuthHelper.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/AuthHelper.cs index ec2ccd4f..aeb76f2e 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/AuthHelper.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/AuthHelper.cs @@ -1,5 +1,6 @@ using System.Security.Claims; using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain._Common; using Microsoft.AspNetCore.Http; namespace GozareshgirProgramManager.Infrastructure.Services.Authentication; @@ -106,6 +107,21 @@ public class AuthHelper : IAuthHelper return _httpContextAccessor.HttpContext?.User?.FindFirst("FullName")?.Value; } + public bool HasPermission(int permission) + { + return GetPermissions().Any(x => x == permission); + } + + public List GetPermissions() + { + if (!IsAuthenticated()) + return new List(); + + var permissions = _httpContextAccessor.HttpContext.User.Claims.FirstOrDefault(x => x.Type == "permissions") + ?.Value; + return Tools.DeserializeFromBsonList(permissions); //Mahan + } + // /// // /// دریافت AccountId کاربر جاری از Claims // ///