diff --git a/Marco.Pms.Helpers/CacheHelper/ProjectCache.cs b/Marco.Pms.Helpers/CacheHelper/ProjectCache.cs index 6f11b07..77ca7d4 100644 --- a/Marco.Pms.Helpers/CacheHelper/ProjectCache.cs +++ b/Marco.Pms.Helpers/CacheHelper/ProjectCache.cs @@ -8,6 +8,7 @@ using Marco.Pms.Model.Projects; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using MongoDB.Bson; +using MongoDB.Bson.Serialization; using MongoDB.Driver; namespace Marco.Pms.Helpers @@ -16,6 +17,11 @@ namespace Marco.Pms.Helpers { private readonly IMongoCollection _projectCollection; private readonly IMongoCollection _taskCollection; + + private readonly string ActiveProjectStatusId = "b74da4c2-d07e-46f2-9919-e75e49b12731"; + private readonly string InProgressProjectStatusId = "cdad86aa-8a56-4ff4-b633-9c629057dfef"; + private readonly string OnHoldProjectStatusId = "603e994b-a27f-4e5d-a251-f3d69b0498ba"; + private readonly string InActiveProjectStatusId = "ef1c356e-0fe0-42df-a5d3-8daee355492d"; public ProjectCache(ApplicationDbContext context, IConfiguration configuration) { var connectionString = configuration["MongoDB:ConnectionString"]; @@ -135,16 +141,68 @@ namespace Marco.Pms.Helpers return project; } + + //public async Task> GetProjectDetailsListFromCache(List projectIds) + //{ + // List stringProjectIds = projectIds.Select(p => p.ToString()).ToList(); + // var filter = Builders.Filter.In(p => p.Id, stringProjectIds); + // var projection = Builders.Projection.Exclude(p => p.Buildings); + // var projects = await _projectCollection + // .Find(filter) + // .Project(projection) + // .ToListAsync(); + // return projects; + //} + public async Task> GetProjectDetailsListFromCache(List projectIds) { - List stringProjectIds = projectIds.Select(p => p.ToString()).ToList(); + var stringProjectIds = projectIds.Select(p => p.ToString()).ToList(); + var filter = Builders.Filter.In(p => p.Id, stringProjectIds); - var projection = Builders.Projection.Exclude(p => p.Buildings); - var projects = await _projectCollection - .Find(filter) + + var projection = Builders.Projection + .Exclude(p => p.Buildings); + + // base aggregation + var aggregate = _projectCollection.Aggregate() + .Match(filter) .Project(projection) - .ToListAsync(); - return projects; + .AppendStage( + @"{ + $addFields: { + statusPriority: { + $cond: [ + { $eq: [""$ProjectStatus.Id"", """ + ActiveProjectStatusId + @"""] }, 0, + { + $cond: [ + { $eq: [""$ProjectStatus.Id"", """ + InProgressProjectStatusId + @"""] }, 1, + { + $cond: [ + { $eq: [""$ProjectStatus.Id"", """ + OnHoldProjectStatusId + @"""] }, 2, + { + $cond: [ + { $eq: [""$ProjectStatus.Id"", """ + InActiveProjectStatusId + @"""] }, 3, + 4 + ] + } + ] + } + ] + } + ] + } + } + }") + .Sort(Builders.Sort + .Ascending("statusPriority") // custom status order + .Ascending("ShortName")); // then by Name + + var docs = await aggregate.ToListAsync(); + + var items = docs + .Select(d => BsonSerializer.Deserialize(d)) + .ToList(); + return items; } public async Task DeleteProjectByIdFromCacheAsync(Guid projectId) { diff --git a/Marco.Pms.Model/MongoDBModels/Project/ProjectMongoDB.cs b/Marco.Pms.Model/MongoDBModels/Project/ProjectMongoDB.cs index d64d358..982adf9 100644 --- a/Marco.Pms.Model/MongoDBModels/Project/ProjectMongoDB.cs +++ b/Marco.Pms.Model/MongoDBModels/Project/ProjectMongoDB.cs @@ -18,6 +18,7 @@ namespace Marco.Pms.Model.MongoDBModels.Project public int TeamSize { get; set; } public double CompletedWork { get; set; } public double PlannedWork { get; set; } + public int statusPriority { get; set; } public DateTime ExpireAt { get; set; } = DateTime.UtcNow.Date.AddDays(1); } } diff --git a/Marco.Pms.Services/Service/ProjectServices.cs b/Marco.Pms.Services/Service/ProjectServices.cs index 760cc6b..304132d 100644 --- a/Marco.Pms.Services/Service/ProjectServices.cs +++ b/Marco.Pms.Services/Service/ProjectServices.cs @@ -36,6 +36,12 @@ namespace Marco.Pms.Services.Service private readonly ILoggingService _logger; private readonly CacheUpdateHelper _cache; private readonly IMapper _mapper; + + private readonly Guid ActiveProjectStatusId = Guid.Parse("b74da4c2-d07e-46f2-9919-e75e49b12731"); + private readonly Guid InProgressProjectStatusId = Guid.Parse("cdad86aa-8a56-4ff4-b633-9c629057dfef"); + private readonly Guid OnHoldProjectStatusId = Guid.Parse("603e994b-a27f-4e5d-a251-f3d69b0498ba"); + private readonly Guid InActiveProjectStatusId = Guid.Parse("ef1c356e-0fe0-42df-a5d3-8daee355492d"); + private readonly Guid CompletedProjectStatusId = Guid.Parse("33deaef9-9af1-4f2a-b443-681ea0d04f81"); public ProjectServices( IDbContextFactory dbContextFactory, IServiceScopeFactory serviceScopeFactory, @@ -3314,6 +3320,13 @@ namespace Marco.Pms.Services.Service using var context = _dbContextFactory.CreateDbContext(); return await context.Projects.AsNoTracking() .Where(p => projectIdsToFetch.Contains(p.Id) && p.TenantId == tenantId) + .OrderBy(p => + p.ProjectStatusId == ActiveProjectStatusId ? 0 : + p.ProjectStatusId == InProgressProjectStatusId ? 1 : + p.ProjectStatusId == OnHoldProjectStatusId ? 2 : + p.ProjectStatusId == InActiveProjectStatusId ? 3 : + p.ProjectStatusId == CompletedProjectStatusId ? 4 : 5) + .ThenBy(p => p.ShortName) .ToListAsync(); }); diff --git a/Marco.Pms.Services/Service/ServiceProjectService.cs b/Marco.Pms.Services/Service/ServiceProjectService.cs index 35e89df..24d57a2 100644 --- a/Marco.Pms.Services/Service/ServiceProjectService.cs +++ b/Marco.Pms.Services/Service/ServiceProjectService.cs @@ -41,6 +41,12 @@ namespace Marco.Pms.Services.Service private readonly Guid ClosedStatus = Guid.Parse("3ddeefb5-ae3c-4e10-a922-35e0a452bb69"); private readonly Guid OnHoldStatus = Guid.Parse("75a0c8b8-9c6a-41af-80bf-b35bab722eb2"); + private readonly Guid ActiveProjectStatusId = Guid.Parse("b74da4c2-d07e-46f2-9919-e75e49b12731"); + private readonly Guid InProgressProjectStatusId = Guid.Parse("cdad86aa-8a56-4ff4-b633-9c629057dfef"); + private readonly Guid OnHoldProjectStatusId = Guid.Parse("603e994b-a27f-4e5d-a251-f3d69b0498ba"); + private readonly Guid InActiveProjectStatusId = Guid.Parse("ef1c356e-0fe0-42df-a5d3-8daee355492d"); + private readonly Guid CompletedProjectStatusId = Guid.Parse("33deaef9-9af1-4f2a-b443-681ea0d04f81"); + public ServiceProjectService(IDbContextFactory dbContextFactory, IServiceScopeFactory serviceScopeFactory, ApplicationDbContext context, @@ -107,7 +113,13 @@ namespace Marco.Pms.Services.Service // Fetch projects for the requested page with ordering by newest var serviceProjects = await serviceProjectQuery - .OrderByDescending(sp => sp.CreatedAt) + .OrderBy(p => + p.ProjectStatusId == ActiveProjectStatusId ? 0 : + p.ProjectStatusId == InProgressProjectStatusId ? 1 : + p.ProjectStatusId == OnHoldProjectStatusId ? 2 : + p.ProjectStatusId == InActiveProjectStatusId ? 3 : + p.ProjectStatusId == CompletedProjectStatusId ? 4 : 5) + .ThenBy(p => p.ShortName) .Skip((pageNumber - 1) * pageSize) .Take(pageSize) .ToListAsync();