Remove the projectHelper and ProjetsHelper and move its bussiness logic to project services
This commit is contained in:
parent
089ae7e9e5
commit
ccce0d48d5
@ -33,6 +33,8 @@ namespace Marco.Pms.CacheHelper
|
|||||||
|
|
||||||
var result = await _collection.UpdateOneAsync(filter, update, options);
|
var result = await _collection.UpdateOneAsync(filter, update, options);
|
||||||
|
|
||||||
|
await InitializeCollectionAsync();
|
||||||
|
|
||||||
// 6. Return a more accurate result indicating success for both updates and upserts.
|
// 6. Return a more accurate result indicating success for both updates and upserts.
|
||||||
// The operation is successful if an existing document was modified OR a new one was created.
|
// The operation is successful if an existing document was modified OR a new one was created.
|
||||||
return result.IsAcknowledged && (result.ModifiedCount > 0 || result.UpsertedId != null);
|
return result.IsAcknowledged && (result.ModifiedCount > 0 || result.UpsertedId != null);
|
||||||
@ -51,6 +53,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
await InitializeCollectionAsync();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public async Task<List<Guid>> GetProjectsFromCache(Guid employeeId)
|
public async Task<List<Guid>> GetProjectsFromCache(Guid employeeId)
|
||||||
@ -177,5 +180,22 @@ namespace Marco.Pms.CacheHelper
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A private method to handle the one-time setup of the collection's indexes.
|
||||||
|
private async Task InitializeCollectionAsync()
|
||||||
|
{
|
||||||
|
// 1. Define the TTL (Time-To-Live) index on the 'ExpireAt' field.
|
||||||
|
var indexKeys = Builders<EmployeePermissionMongoDB>.IndexKeys.Ascending(x => x.ExpireAt);
|
||||||
|
var indexOptions = new CreateIndexOptions
|
||||||
|
{
|
||||||
|
// This tells MongoDB to automatically delete documents when their 'ExpireAt' time is reached.
|
||||||
|
ExpireAfter = TimeSpan.FromSeconds(0)
|
||||||
|
};
|
||||||
|
var indexModel = new CreateIndexModel<EmployeePermissionMongoDB>(indexKeys, indexOptions);
|
||||||
|
|
||||||
|
// 2. Create the index. This is an idempotent operation if the index already exists.
|
||||||
|
// Use CreateOneAsync since we are only creating a single index.
|
||||||
|
await _collection.Indexes.CreateOneAsync(indexModel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,27 +11,59 @@ namespace Marco.Pms.CacheHelper
|
|||||||
{
|
{
|
||||||
public class ProjectCache
|
public class ProjectCache
|
||||||
{
|
{
|
||||||
private readonly ApplicationDbContext _context;
|
private readonly IMongoCollection<ProjectMongoDB> _projectCollection;
|
||||||
private readonly IMongoCollection<ProjectMongoDB> _projetCollection;
|
|
||||||
private readonly IMongoCollection<WorkItemMongoDB> _taskCollection;
|
private readonly IMongoCollection<WorkItemMongoDB> _taskCollection;
|
||||||
public ProjectCache(ApplicationDbContext context, IConfiguration configuration)
|
public ProjectCache(ApplicationDbContext context, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
var connectionString = configuration["MongoDB:ConnectionString"];
|
var connectionString = configuration["MongoDB:ConnectionString"];
|
||||||
_context = context;
|
|
||||||
var mongoUrl = new MongoUrl(connectionString);
|
var mongoUrl = new MongoUrl(connectionString);
|
||||||
var client = new MongoClient(mongoUrl); // Your MongoDB connection string
|
var client = new MongoClient(mongoUrl); // Your MongoDB connection string
|
||||||
var mongoDB = client.GetDatabase(mongoUrl.DatabaseName); // Your MongoDB Database name
|
var mongoDB = client.GetDatabase(mongoUrl.DatabaseName); // Your MongoDB Database name
|
||||||
_projetCollection = mongoDB.GetCollection<ProjectMongoDB>("ProjectDetails");
|
_projectCollection = mongoDB.GetCollection<ProjectMongoDB>("ProjectDetails");
|
||||||
_taskCollection = mongoDB.GetCollection<WorkItemMongoDB>("WorkItemDetails");
|
_taskCollection = mongoDB.GetCollection<WorkItemMongoDB>("WorkItemDetails");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddProjectDetailsToCache(ProjectMongoDB projectDetails)
|
public async Task AddProjectDetailsToCache(ProjectMongoDB projectDetails)
|
||||||
{
|
{
|
||||||
await _projetCollection.InsertOneAsync(projectDetails);
|
await _projectCollection.InsertOneAsync(projectDetails);
|
||||||
|
|
||||||
|
var indexKeys = Builders<ProjectMongoDB>.IndexKeys.Ascending(x => x.ExpireAt);
|
||||||
|
var indexOptions = new CreateIndexOptions
|
||||||
|
{
|
||||||
|
ExpireAfter = TimeSpan.Zero // required for fixed expiration time
|
||||||
|
};
|
||||||
|
var indexModel = new CreateIndexModel<ProjectMongoDB>(indexKeys, indexOptions);
|
||||||
|
await _projectCollection.Indexes.CreateOneAsync(indexModel);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// The method should focus only on inserting data.
|
||||||
public async Task AddProjectDetailsListToCache(List<ProjectMongoDB> projectDetailsList)
|
public async Task AddProjectDetailsListToCache(List<ProjectMongoDB> projectDetailsList)
|
||||||
{
|
{
|
||||||
await _projetCollection.InsertManyAsync(projectDetailsList);
|
// 1. Add a guard clause to avoid an unnecessary database call for an empty list.
|
||||||
|
if (projectDetailsList == null || !projectDetailsList.Any())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Perform the insert operation. This is the only responsibility of this method.
|
||||||
|
await _projectCollection.InsertManyAsync(projectDetailsList);
|
||||||
|
await InitializeCollectionAsync();
|
||||||
|
}
|
||||||
|
// A private method to handle the one-time setup of the collection's indexes.
|
||||||
|
private async Task InitializeCollectionAsync()
|
||||||
|
{
|
||||||
|
// 1. Define the TTL (Time-To-Live) index on the 'ExpireAt' field.
|
||||||
|
var indexKeys = Builders<ProjectMongoDB>.IndexKeys.Ascending(x => x.ExpireAt);
|
||||||
|
var indexOptions = new CreateIndexOptions
|
||||||
|
{
|
||||||
|
// This tells MongoDB to automatically delete documents when their 'ExpireAt' time is reached.
|
||||||
|
ExpireAfter = TimeSpan.FromSeconds(0)
|
||||||
|
};
|
||||||
|
var indexModel = new CreateIndexModel<ProjectMongoDB>(indexKeys, indexOptions);
|
||||||
|
|
||||||
|
// 2. Create the index. This is an idempotent operation if the index already exists.
|
||||||
|
// Use CreateOneAsync since we are only creating a single index.
|
||||||
|
await _projectCollection.Indexes.CreateOneAsync(indexModel);
|
||||||
}
|
}
|
||||||
public async Task<bool> UpdateProjectDetailsOnlyToCache(Project project, StatusMaster projectStatus)
|
public async Task<bool> UpdateProjectDetailsOnlyToCache(Project project, StatusMaster projectStatus)
|
||||||
{
|
{
|
||||||
@ -51,7 +83,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Perform the update
|
// Perform the update
|
||||||
var result = await _projetCollection.UpdateOneAsync(
|
var result = await _projectCollection.UpdateOneAsync(
|
||||||
filter: r => r.Id == project.Id.ToString(),
|
filter: r => r.Id == project.Id.ToString(),
|
||||||
update: updates
|
update: updates
|
||||||
);
|
);
|
||||||
@ -71,7 +103,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
var projection = Builders<ProjectMongoDB>.Projection.Exclude(p => p.Buildings);
|
var projection = Builders<ProjectMongoDB>.Projection.Exclude(p => p.Buildings);
|
||||||
|
|
||||||
// Perform query
|
// Perform query
|
||||||
var project = await _projetCollection
|
var project = await _projectCollection
|
||||||
.Find(filter)
|
.Find(filter)
|
||||||
.Project<ProjectMongoDB>(projection)
|
.Project<ProjectMongoDB>(projection)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
@ -83,7 +115,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
List<string> stringProjectIds = projectIds.Select(p => p.ToString()).ToList();
|
List<string> stringProjectIds = projectIds.Select(p => p.ToString()).ToList();
|
||||||
var filter = Builders<ProjectMongoDB>.Filter.In(p => p.Id, stringProjectIds);
|
var filter = Builders<ProjectMongoDB>.Filter.In(p => p.Id, stringProjectIds);
|
||||||
var projection = Builders<ProjectMongoDB>.Projection.Exclude(p => p.Buildings);
|
var projection = Builders<ProjectMongoDB>.Projection.Exclude(p => p.Buildings);
|
||||||
var projects = await _projetCollection
|
var projects = await _projectCollection
|
||||||
.Find(filter)
|
.Find(filter)
|
||||||
.Project<ProjectMongoDB>(projection)
|
.Project<ProjectMongoDB>(projection)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
@ -92,14 +124,14 @@ namespace Marco.Pms.CacheHelper
|
|||||||
public async Task<bool> DeleteProjectByIdFromCacheAsync(Guid projectId)
|
public async Task<bool> DeleteProjectByIdFromCacheAsync(Guid projectId)
|
||||||
{
|
{
|
||||||
var filter = Builders<ProjectMongoDB>.Filter.Eq(e => e.Id, projectId.ToString());
|
var filter = Builders<ProjectMongoDB>.Filter.Eq(e => e.Id, projectId.ToString());
|
||||||
var result = await _projetCollection.DeleteOneAsync(filter);
|
var result = await _projectCollection.DeleteOneAsync(filter);
|
||||||
return result.DeletedCount > 0;
|
return result.DeletedCount > 0;
|
||||||
}
|
}
|
||||||
public async Task<bool> RemoveProjectsFromCacheAsync(List<Guid> projectIds)
|
public async Task<bool> RemoveProjectsFromCacheAsync(List<Guid> projectIds)
|
||||||
{
|
{
|
||||||
var stringIds = projectIds.Select(id => id.ToString()).ToList();
|
var stringIds = projectIds.Select(id => id.ToString()).ToList();
|
||||||
var filter = Builders<ProjectMongoDB>.Filter.In(p => p.Id, stringIds);
|
var filter = Builders<ProjectMongoDB>.Filter.In(p => p.Id, stringIds);
|
||||||
var result = await _projetCollection.DeleteManyAsync(filter);
|
var result = await _projectCollection.DeleteManyAsync(filter);
|
||||||
return result.DeletedCount > 0;
|
return result.DeletedCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +157,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
var filter = Builders<ProjectMongoDB>.Filter.Eq(p => p.Id, stringProjectId);
|
var filter = Builders<ProjectMongoDB>.Filter.Eq(p => p.Id, stringProjectId);
|
||||||
var update = Builders<ProjectMongoDB>.Update.Push("Buildings", buildingMongo);
|
var update = Builders<ProjectMongoDB>.Update.Push("Buildings", buildingMongo);
|
||||||
|
|
||||||
var result = await _projetCollection.UpdateOneAsync(filter, update);
|
var result = await _projectCollection.UpdateOneAsync(filter, update);
|
||||||
|
|
||||||
if (result.MatchedCount == 0)
|
if (result.MatchedCount == 0)
|
||||||
{
|
{
|
||||||
@ -155,7 +187,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
);
|
);
|
||||||
|
|
||||||
var update = Builders<ProjectMongoDB>.Update.Push("Buildings.$.Floors", floorMongo);
|
var update = Builders<ProjectMongoDB>.Update.Push("Buildings.$.Floors", floorMongo);
|
||||||
var result = await _projetCollection.UpdateOneAsync(filter, update);
|
var result = await _projectCollection.UpdateOneAsync(filter, update);
|
||||||
|
|
||||||
if (result.MatchedCount == 0)
|
if (result.MatchedCount == 0)
|
||||||
{
|
{
|
||||||
@ -189,7 +221,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
var update = Builders<ProjectMongoDB>.Update.Push("Buildings.$[b].Floors.$[f].WorkAreas", workAreaMongo);
|
var update = Builders<ProjectMongoDB>.Update.Push("Buildings.$[b].Floors.$[f].WorkAreas", workAreaMongo);
|
||||||
var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };
|
var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };
|
||||||
|
|
||||||
var result = await _projetCollection.UpdateOneAsync(filter, update, updateOptions);
|
var result = await _projectCollection.UpdateOneAsync(filter, update, updateOptions);
|
||||||
|
|
||||||
if (result.MatchedCount == 0)
|
if (result.MatchedCount == 0)
|
||||||
{
|
{
|
||||||
@ -221,7 +253,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
Builders<ProjectMongoDB>.Update.Set("Buildings.$.Description", building.Description)
|
Builders<ProjectMongoDB>.Update.Set("Buildings.$.Description", building.Description)
|
||||||
);
|
);
|
||||||
|
|
||||||
var result = await _projetCollection.UpdateOneAsync(filter, update);
|
var result = await _projectCollection.UpdateOneAsync(filter, update);
|
||||||
|
|
||||||
if (result.MatchedCount == 0)
|
if (result.MatchedCount == 0)
|
||||||
{
|
{
|
||||||
@ -246,7 +278,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };
|
var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };
|
||||||
var filter = Builders<ProjectMongoDB>.Filter.Eq(p => p.Id, stringProjectId);
|
var filter = Builders<ProjectMongoDB>.Filter.Eq(p => p.Id, stringProjectId);
|
||||||
|
|
||||||
var result = await _projetCollection.UpdateOneAsync(filter, update, updateOptions);
|
var result = await _projectCollection.UpdateOneAsync(filter, update, updateOptions);
|
||||||
|
|
||||||
if (result.MatchedCount == 0)
|
if (result.MatchedCount == 0)
|
||||||
{
|
{
|
||||||
@ -272,7 +304,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };
|
var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };
|
||||||
var filter = Builders<ProjectMongoDB>.Filter.Eq(p => p.Id, stringProjectId);
|
var filter = Builders<ProjectMongoDB>.Filter.Eq(p => p.Id, stringProjectId);
|
||||||
|
|
||||||
var result = await _projetCollection.UpdateOneAsync(filter, update, updateOptions);
|
var result = await _projectCollection.UpdateOneAsync(filter, update, updateOptions);
|
||||||
|
|
||||||
if (result.MatchedCount == 0)
|
if (result.MatchedCount == 0)
|
||||||
{
|
{
|
||||||
@ -296,7 +328,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
var filter = Builders<ProjectMongoDB>.Filter.Eq(p => p.Id, projectId.ToString());
|
var filter = Builders<ProjectMongoDB>.Filter.Eq(p => p.Id, projectId.ToString());
|
||||||
|
|
||||||
// Project only the "Buildings" field from the document
|
// Project only the "Buildings" field from the document
|
||||||
var buildings = await _projetCollection
|
var buildings = await _projectCollection
|
||||||
.Find(filter)
|
.Find(filter)
|
||||||
.Project(p => p.Buildings)
|
.Project(p => p.Buildings)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
@ -315,7 +347,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
public async Task UpdatePlannedAndCompleteWorksInBuildingFromCache(Guid workAreaId, double plannedWork, double completedWork)
|
public async Task UpdatePlannedAndCompleteWorksInBuildingFromCache(Guid workAreaId, double plannedWork, double completedWork)
|
||||||
{
|
{
|
||||||
var filter = Builders<ProjectMongoDB>.Filter.Eq("Buildings.Floors.WorkAreas._id", workAreaId.ToString());
|
var filter = Builders<ProjectMongoDB>.Filter.Eq("Buildings.Floors.WorkAreas._id", workAreaId.ToString());
|
||||||
var project = await _projetCollection.Find(filter).FirstOrDefaultAsync();
|
var project = await _projectCollection.Find(filter).FirstOrDefaultAsync();
|
||||||
|
|
||||||
string? selectedBuildingId = null;
|
string? selectedBuildingId = null;
|
||||||
string? selectedFloorId = null;
|
string? selectedFloorId = null;
|
||||||
@ -353,7 +385,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
.Inc("Buildings.$[b].CompletedWork", completedWork)
|
.Inc("Buildings.$[b].CompletedWork", completedWork)
|
||||||
.Inc("PlannedWork", plannedWork)
|
.Inc("PlannedWork", plannedWork)
|
||||||
.Inc("CompletedWork", completedWork);
|
.Inc("CompletedWork", completedWork);
|
||||||
var result = await _projetCollection.UpdateOneAsync(filter, update, updateOptions);
|
var result = await _projectCollection.UpdateOneAsync(filter, update, updateOptions);
|
||||||
|
|
||||||
}
|
}
|
||||||
public async Task<WorkAreaInfoMongoDB?> GetBuildingAndFloorByWorkAreaIdFromCache(Guid workAreaId)
|
public async Task<WorkAreaInfoMongoDB?> GetBuildingAndFloorByWorkAreaIdFromCache(Guid workAreaId)
|
||||||
@ -393,7 +425,7 @@ namespace Marco.Pms.CacheHelper
|
|||||||
{ "WorkArea", "$Buildings.Floors.WorkAreas" }
|
{ "WorkArea", "$Buildings.Floors.WorkAreas" }
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
var result = await _projetCollection.Aggregate<WorkAreaInfoMongoDB>(pipeline).FirstOrDefaultAsync();
|
var result = await _projectCollection.Aggregate<WorkAreaInfoMongoDB>(pipeline).FirstOrDefaultAsync();
|
||||||
if (result == null)
|
if (result == null)
|
||||||
return null;
|
return null;
|
||||||
return result;
|
return result;
|
||||||
|
@ -9,5 +9,6 @@ namespace Marco.Pms.Model.MongoDBModels
|
|||||||
public List<string> ApplicationRoleIds { get; set; } = new List<string>();
|
public List<string> ApplicationRoleIds { get; set; } = new List<string>();
|
||||||
public List<string> PermissionIds { get; set; } = new List<string>();
|
public List<string> PermissionIds { get; set; } = new List<string>();
|
||||||
public List<string> ProjectIds { get; set; } = new List<string>();
|
public List<string> ProjectIds { get; set; } = new List<string>();
|
||||||
|
public DateTime ExpireAt { get; set; } = DateTime.UtcNow.Date.AddDays(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,5 +14,6 @@
|
|||||||
public int TeamSize { get; set; }
|
public int TeamSize { get; set; }
|
||||||
public double CompletedWork { get; set; }
|
public double CompletedWork { get; set; }
|
||||||
public double PlannedWork { get; set; }
|
public double PlannedWork { get; set; }
|
||||||
|
public DateTime ExpireAt { get; set; } = DateTime.UtcNow.Date.AddDays(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ using Marco.Pms.Model.Utilities;
|
|||||||
using Marco.Pms.Model.ViewModels.AttendanceVM;
|
using Marco.Pms.Model.ViewModels.AttendanceVM;
|
||||||
using Marco.Pms.Services.Hubs;
|
using Marco.Pms.Services.Hubs;
|
||||||
using Marco.Pms.Services.Service;
|
using Marco.Pms.Services.Service;
|
||||||
|
using Marco.Pms.Services.Service.ServiceInterfaces;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
using MarcoBMS.Services.Service;
|
using MarcoBMS.Services.Service;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@ -28,7 +29,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
private readonly ApplicationDbContext _context;
|
private readonly ApplicationDbContext _context;
|
||||||
private readonly EmployeeHelper _employeeHelper;
|
private readonly EmployeeHelper _employeeHelper;
|
||||||
private readonly ProjectsHelper _projectsHelper;
|
private readonly IProjectServices _projectServices;
|
||||||
private readonly UserHelper _userHelper;
|
private readonly UserHelper _userHelper;
|
||||||
private readonly S3UploadService _s3Service;
|
private readonly S3UploadService _s3Service;
|
||||||
private readonly PermissionServices _permission;
|
private readonly PermissionServices _permission;
|
||||||
@ -37,11 +38,11 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
|
|
||||||
public AttendanceController(
|
public AttendanceController(
|
||||||
ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper, S3UploadService s3Service, ILoggingService logger, PermissionServices permission, IHubContext<MarcoHub> signalR)
|
ApplicationDbContext context, EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, S3UploadService s3Service, ILoggingService logger, PermissionServices permission, IHubContext<MarcoHub> signalR)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_employeeHelper = employeeHelper;
|
_employeeHelper = employeeHelper;
|
||||||
_projectsHelper = projectsHelper;
|
_projectServices = projectServices;
|
||||||
_userHelper = userHelper;
|
_userHelper = userHelper;
|
||||||
_s3Service = s3Service;
|
_s3Service = s3Service;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@ -188,7 +189,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date >= fromDate.Date && c.AttendanceDate.Date <= toDate.Date && c.TenantId == TenantId).ToListAsync();
|
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date >= fromDate.Date && c.AttendanceDate.Date <= toDate.Date && c.TenantId == TenantId).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
List<ProjectAllocation> projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, true);
|
List<ProjectAllocation> projectteam = await _projectServices.GetTeamByProject(TenantId, projectId, true);
|
||||||
var jobRole = await _context.JobRoles.ToListAsync();
|
var jobRole = await _context.JobRoles.ToListAsync();
|
||||||
foreach (Attendance? attendance in lstAttendance)
|
foreach (Attendance? attendance in lstAttendance)
|
||||||
{
|
{
|
||||||
@ -295,7 +296,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date == forDate && c.TenantId == TenantId).ToListAsync();
|
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date == forDate && c.TenantId == TenantId).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
List<ProjectAllocation> projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, IncludeInActive);
|
List<ProjectAllocation> projectteam = await _projectServices.GetTeamByProject(TenantId, projectId, IncludeInActive);
|
||||||
var idList = projectteam.Select(p => p.EmployeeId).ToList();
|
var idList = projectteam.Select(p => p.EmployeeId).ToList();
|
||||||
//var emp = await _context.Employees.Where(e => idList.Contains(e.Id)).Include(e => e.JobRole).ToListAsync();
|
//var emp = await _context.Employees.Where(e => idList.Contains(e.Id)).Include(e => e.JobRole).ToListAsync();
|
||||||
var jobRole = await _context.JobRoles.ToListAsync();
|
var jobRole = await _context.JobRoles.ToListAsync();
|
||||||
@ -378,7 +379,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE && c.TenantId == TenantId).ToListAsync();
|
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE && c.TenantId == TenantId).ToListAsync();
|
||||||
|
|
||||||
List<ProjectAllocation> projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, true);
|
List<ProjectAllocation> projectteam = await _projectServices.GetTeamByProject(TenantId, projectId, true);
|
||||||
var idList = projectteam.Select(p => p.EmployeeId).ToList();
|
var idList = projectteam.Select(p => p.EmployeeId).ToList();
|
||||||
var jobRole = await _context.JobRoles.ToListAsync();
|
var jobRole = await _context.JobRoles.ToListAsync();
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ using Marco.Pms.Model.Utilities;
|
|||||||
using Marco.Pms.Model.ViewModels.Employee;
|
using Marco.Pms.Model.ViewModels.Employee;
|
||||||
using Marco.Pms.Services.Hubs;
|
using Marco.Pms.Services.Hubs;
|
||||||
using Marco.Pms.Services.Service;
|
using Marco.Pms.Services.Service;
|
||||||
|
using Marco.Pms.Services.Service.ServiceInterfaces;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
using MarcoBMS.Services.Service;
|
using MarcoBMS.Services.Service;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@ -37,13 +38,13 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
private readonly ILoggingService _logger;
|
private readonly ILoggingService _logger;
|
||||||
private readonly IHubContext<MarcoHub> _signalR;
|
private readonly IHubContext<MarcoHub> _signalR;
|
||||||
private readonly PermissionServices _permission;
|
private readonly PermissionServices _permission;
|
||||||
private readonly ProjectsHelper _projectsHelper;
|
private readonly IProjectServices _projectServices;
|
||||||
private readonly Guid tenantId;
|
private readonly Guid tenantId;
|
||||||
|
|
||||||
|
|
||||||
public EmployeeController(UserManager<ApplicationUser> userManager, IEmailSender emailSender,
|
public EmployeeController(UserManager<ApplicationUser> userManager, IEmailSender emailSender,
|
||||||
ApplicationDbContext context, EmployeeHelper employeeHelper, UserHelper userHelper, IConfiguration configuration, ILoggingService logger,
|
ApplicationDbContext context, EmployeeHelper employeeHelper, UserHelper userHelper, IConfiguration configuration, ILoggingService logger,
|
||||||
IHubContext<MarcoHub> signalR, PermissionServices permission, ProjectsHelper projectsHelper)
|
IHubContext<MarcoHub> signalR, PermissionServices permission, IProjectServices projectServices)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
@ -54,7 +55,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
_signalR = signalR;
|
_signalR = signalR;
|
||||||
_permission = permission;
|
_permission = permission;
|
||||||
_projectsHelper = projectsHelper;
|
_projectServices = projectServices;
|
||||||
tenantId = _userHelper.GetTenantId();
|
tenantId = _userHelper.GetTenantId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +120,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
loggedInEmployee.Id, projectid ?? Guid.Empty, ShowInactive);
|
loggedInEmployee.Id, projectid ?? Guid.Empty, ShowInactive);
|
||||||
|
|
||||||
// Step 3: Fetch project access and permissions
|
// Step 3: Fetch project access and permissions
|
||||||
var projectIds = await _projectsHelper.GetMyProjects(tenantId, loggedInEmployee);
|
var projectIds = await _projectServices.GetMyProjectIdsAsync(tenantId, loggedInEmployee);
|
||||||
|
|
||||||
var hasViewAllEmployeesPermission = await _permission.HasPermission(PermissionsMaster.ViewAllEmployees, loggedInEmployee.Id);
|
var hasViewAllEmployeesPermission = await _permission.HasPermission(PermissionsMaster.ViewAllEmployees, loggedInEmployee.Id);
|
||||||
var hasViewTeamMembersPermission = await _permission.HasPermission(PermissionsMaster.ViewTeamMembers, loggedInEmployee.Id);
|
var hasViewTeamMembersPermission = await _permission.HasPermission(PermissionsMaster.ViewTeamMembers, loggedInEmployee.Id);
|
||||||
|
@ -4,6 +4,7 @@ using Marco.Pms.Model.Mapper;
|
|||||||
using Marco.Pms.Model.Projects;
|
using Marco.Pms.Model.Projects;
|
||||||
using Marco.Pms.Model.Utilities;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.ViewModels.Employee;
|
using Marco.Pms.Model.ViewModels.Employee;
|
||||||
|
using Marco.Pms.Services.Service.ServiceInterfaces;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -19,14 +20,14 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
private readonly UserHelper _userHelper;
|
private readonly UserHelper _userHelper;
|
||||||
private readonly EmployeeHelper _employeeHelper;
|
private readonly EmployeeHelper _employeeHelper;
|
||||||
|
|
||||||
private readonly ProjectsHelper _projectsHelper;
|
private readonly IProjectServices _projectServices;
|
||||||
private readonly RolesHelper _rolesHelper;
|
private readonly RolesHelper _rolesHelper;
|
||||||
|
|
||||||
public UserController(EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper, RolesHelper rolesHelper)
|
public UserController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper)
|
||||||
{
|
{
|
||||||
_userHelper = userHelper;
|
_userHelper = userHelper;
|
||||||
_employeeHelper = employeeHelper;
|
_employeeHelper = employeeHelper;
|
||||||
_projectsHelper = projectsHelper;
|
_projectServices = projectServices;
|
||||||
_rolesHelper = rolesHelper;
|
_rolesHelper = rolesHelper;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -56,12 +57,12 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
/* User with permission manage project can see all projects */
|
/* User with permission manage project can see all projects */
|
||||||
if (featurePermission != null && featurePermission.Exists(c => c.Id.ToString() == "172fc9b6-755b-4f62-ab26-55c34a330614"))
|
if (featurePermission != null && featurePermission.Exists(c => c.Id.ToString() == "172fc9b6-755b-4f62-ab26-55c34a330614"))
|
||||||
{
|
{
|
||||||
List<Project> projects = await _projectsHelper.GetAllProjectByTanentID(emp.TenantId);
|
List<Project> projects = await _projectServices.GetAllProjectByTanentID(emp.TenantId);
|
||||||
projectsId = projects.Select(c => c.Id.ToString()).ToArray();
|
projectsId = projects.Select(c => c.Id.ToString()).ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<ProjectAllocation> allocation = await _projectsHelper.GetProjectByEmployeeID(emp.Id);
|
List<ProjectAllocation> allocation = await _projectServices.GetProjectByEmployeeID(emp.Id);
|
||||||
projectsId = allocation.Select(c => c.ProjectId.ToString()).ToArray();
|
projectsId = allocation.Select(c => c.ProjectId.ToString()).ToArray();
|
||||||
}
|
}
|
||||||
EmployeeProfile profile = new EmployeeProfile() { };
|
EmployeeProfile profile = new EmployeeProfile() { };
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
using Marco.Pms.DataAccess.Data;
|
|
||||||
using Marco.Pms.Model.Projects;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
|
|
||||||
namespace ModelServices.Helpers
|
|
||||||
{
|
|
||||||
public class ProjectHelper
|
|
||||||
{
|
|
||||||
private readonly ApplicationDbContext _context;
|
|
||||||
public ProjectHelper(ApplicationDbContext context)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<ProjectAllocation>> GetTeamByProject(Guid TenantId, Guid ProjectId, bool IncludeInactive)
|
|
||||||
{
|
|
||||||
if (IncludeInactive)
|
|
||||||
{
|
|
||||||
|
|
||||||
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId).Include(e => e.Employee).ToListAsync();
|
|
||||||
|
|
||||||
return employees;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId && c.IsActive == true).Include(e => e.Employee).ToListAsync();
|
|
||||||
|
|
||||||
return employees;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
using Marco.Pms.DataAccess.Data;
|
|
||||||
using Marco.Pms.Model.Employees;
|
|
||||||
using Marco.Pms.Model.Entitlements;
|
|
||||||
using Marco.Pms.Model.Projects;
|
|
||||||
using Marco.Pms.Services.Helpers;
|
|
||||||
using Marco.Pms.Services.Service;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace MarcoBMS.Services.Helpers
|
|
||||||
{
|
|
||||||
public class ProjectsHelper
|
|
||||||
{
|
|
||||||
private readonly ApplicationDbContext _context;
|
|
||||||
private readonly CacheUpdateHelper _cache;
|
|
||||||
private readonly PermissionServices _permission;
|
|
||||||
|
|
||||||
public ProjectsHelper(ApplicationDbContext context, CacheUpdateHelper cache, PermissionServices permission)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
_cache = cache;
|
|
||||||
_permission = permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<Project>> GetAllProjectByTanentID(Guid tanentID)
|
|
||||||
{
|
|
||||||
List<Project> alloc = await _context.Projects.Where(c => c.TenantId == tanentID).ToListAsync();
|
|
||||||
return alloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<ProjectAllocation>> GetProjectByEmployeeID(Guid employeeID)
|
|
||||||
{
|
|
||||||
List<ProjectAllocation> alloc = await _context.ProjectAllocations.Where(c => c.EmployeeId == employeeID && c.IsActive == true).Include(c => c.Project).ToListAsync();
|
|
||||||
return alloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<ProjectAllocation>> GetTeamByProject(Guid TenantId, Guid ProjectId, bool IncludeInactive)
|
|
||||||
{
|
|
||||||
if (IncludeInactive)
|
|
||||||
{
|
|
||||||
|
|
||||||
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId).Include(e => e.Employee).ToListAsync();
|
|
||||||
|
|
||||||
return employees;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId && c.IsActive == true).Include(e => e.Employee).ToListAsync();
|
|
||||||
|
|
||||||
return employees;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<Guid>> GetMyProjects(Guid tenantId, Employee LoggedInEmployee)
|
|
||||||
{
|
|
||||||
var projectIds = await _cache.GetProjects(LoggedInEmployee.Id);
|
|
||||||
|
|
||||||
if (projectIds == null)
|
|
||||||
{
|
|
||||||
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageProject, LoggedInEmployee.Id);
|
|
||||||
if (hasPermission)
|
|
||||||
{
|
|
||||||
var projects = await _context.Projects.Where(c => c.TenantId == tenantId).ToListAsync();
|
|
||||||
projectIds = projects.Select(p => p.Id).ToList();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var allocation = await GetProjectByEmployeeID(LoggedInEmployee.Id);
|
|
||||||
if (!allocation.Any())
|
|
||||||
{
|
|
||||||
return new List<Guid>();
|
|
||||||
}
|
|
||||||
projectIds = allocation.Select(c => c.ProjectId).Distinct().ToList();
|
|
||||||
}
|
|
||||||
await _cache.AddProjects(LoggedInEmployee.Id, projectIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -167,7 +167,6 @@ builder.Services.AddScoped<GeneralHelper>();
|
|||||||
builder.Services.AddScoped<UserHelper>();
|
builder.Services.AddScoped<UserHelper>();
|
||||||
builder.Services.AddScoped<RolesHelper>();
|
builder.Services.AddScoped<RolesHelper>();
|
||||||
builder.Services.AddScoped<EmployeeHelper>();
|
builder.Services.AddScoped<EmployeeHelper>();
|
||||||
builder.Services.AddScoped<ProjectsHelper>();
|
|
||||||
builder.Services.AddScoped<DirectoryHelper>();
|
builder.Services.AddScoped<DirectoryHelper>();
|
||||||
builder.Services.AddScoped<MasterHelper>();
|
builder.Services.AddScoped<MasterHelper>();
|
||||||
builder.Services.AddScoped<ReportHelper>();
|
builder.Services.AddScoped<ReportHelper>();
|
||||||
|
@ -12,7 +12,6 @@ using Marco.Pms.Model.ViewModels.Employee;
|
|||||||
using Marco.Pms.Model.ViewModels.Projects;
|
using Marco.Pms.Model.ViewModels.Projects;
|
||||||
using Marco.Pms.Services.Helpers;
|
using Marco.Pms.Services.Helpers;
|
||||||
using Marco.Pms.Services.Service.ServiceInterfaces;
|
using Marco.Pms.Services.Service.ServiceInterfaces;
|
||||||
using MarcoBMS.Services.Helpers;
|
|
||||||
using MarcoBMS.Services.Service;
|
using MarcoBMS.Services.Service;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -25,7 +24,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
|
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
|
||||||
private readonly ApplicationDbContext _context; // Keeping this for direct scoped context use where appropriate
|
private readonly ApplicationDbContext _context; // Keeping this for direct scoped context use where appropriate
|
||||||
private readonly ILoggingService _logger;
|
private readonly ILoggingService _logger;
|
||||||
private readonly ProjectsHelper _projectsHelper;
|
|
||||||
private readonly PermissionServices _permission;
|
private readonly PermissionServices _permission;
|
||||||
private readonly CacheUpdateHelper _cache;
|
private readonly CacheUpdateHelper _cache;
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
@ -34,7 +32,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
IDbContextFactory<ApplicationDbContext> dbContextFactory,
|
IDbContextFactory<ApplicationDbContext> dbContextFactory,
|
||||||
ApplicationDbContext context,
|
ApplicationDbContext context,
|
||||||
ILoggingService logger,
|
ILoggingService logger,
|
||||||
ProjectsHelper projectsHelper,
|
|
||||||
PermissionServices permission,
|
PermissionServices permission,
|
||||||
CacheUpdateHelper cache,
|
CacheUpdateHelper cache,
|
||||||
IMapper mapper,
|
IMapper mapper,
|
||||||
@ -43,7 +40,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
_dbContextFactory = dbContextFactory ?? throw new ArgumentNullException(nameof(dbContextFactory));
|
_dbContextFactory = dbContextFactory ?? throw new ArgumentNullException(nameof(dbContextFactory));
|
||||||
_context = context ?? throw new ArgumentNullException(nameof(context));
|
_context = context ?? throw new ArgumentNullException(nameof(context));
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
_projectsHelper = projectsHelper ?? throw new ArgumentNullException(nameof(projectsHelper));
|
|
||||||
_permission = permission ?? throw new ArgumentNullException(nameof(permission));
|
_permission = permission ?? throw new ArgumentNullException(nameof(permission));
|
||||||
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
|
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
|
||||||
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
|
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
|
||||||
@ -64,7 +60,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
_logger.LogInfo("Basic project list requested by EmployeeId {EmployeeId}", loggedInEmployee.Id);
|
_logger.LogInfo("Basic project list requested by EmployeeId {EmployeeId}", loggedInEmployee.Id);
|
||||||
|
|
||||||
// Step 2: Get the list of project IDs the user has access to
|
// Step 2: Get the list of project IDs the user has access to
|
||||||
List<Guid> accessibleProjectIds = await _projectsHelper.GetMyProjects(tenantId, loggedInEmployee);
|
List<Guid> accessibleProjectIds = await GetMyProjects(tenantId, loggedInEmployee);
|
||||||
|
|
||||||
if (accessibleProjectIds == null || !accessibleProjectIds.Any())
|
if (accessibleProjectIds == null || !accessibleProjectIds.Any())
|
||||||
{
|
{
|
||||||
@ -94,7 +90,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
_logger.LogInfo("Starting GetAllProjects for TenantId: {TenantId}, User: {UserId}", tenantId, loggedInEmployee.Id);
|
_logger.LogInfo("Starting GetAllProjects for TenantId: {TenantId}, User: {UserId}", tenantId, loggedInEmployee.Id);
|
||||||
|
|
||||||
// --- Step 1: Get a list of project IDs the user can access ---
|
// --- Step 1: Get a list of project IDs the user can access ---
|
||||||
List<Guid> projectIds = await _projectsHelper.GetMyProjects(tenantId, loggedInEmployee);
|
List<Guid> projectIds = await GetMyProjects(tenantId, loggedInEmployee);
|
||||||
if (!projectIds.Any())
|
if (!projectIds.Any())
|
||||||
{
|
{
|
||||||
_logger.LogInfo("User has no assigned projects. Returning empty list.");
|
_logger.LogInfo("User has no assigned projects. Returning empty list.");
|
||||||
@ -743,7 +739,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
// This is a placeholder for your actual, more specific permission logic.
|
// This is a placeholder for your actual, more specific permission logic.
|
||||||
// It should also handle the case where a user is requesting their own projects (employeeId == loggedInEmployee.Id).
|
// It should also handle the case where a user is requesting their own projects (employeeId == loggedInEmployee.Id).
|
||||||
var hasPermission = await _permission.HasPermission(PermissionsMaster.ViewProject, loggedInEmployee.Id);
|
var hasPermission = await _permission.HasPermission(PermissionsMaster.ViewProject, loggedInEmployee.Id);
|
||||||
var projectIds = await _projectsHelper.GetMyProjects(tenantId, loggedInEmployee);
|
var projectIds = await GetMyProjects(tenantId, loggedInEmployee);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access DENIED for user {UserId} trying to view projects for employee {TargetEmployeeId}.", loggedInEmployee.Id, employeeId);
|
_logger.LogWarning("Access DENIED for user {UserId} trying to view projects for employee {TargetEmployeeId}.", loggedInEmployee.Id, employeeId);
|
||||||
@ -1329,6 +1325,110 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
#region =================================================================== Helper Functions ===================================================================
|
#region =================================================================== Helper Functions ===================================================================
|
||||||
|
|
||||||
|
public async Task<List<Project>> GetAllProjectByTanentID(Guid tanentId)
|
||||||
|
{
|
||||||
|
List<Project> alloc = await _context.Projects.Where(c => c.TenantId == tanentId).ToListAsync();
|
||||||
|
return alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<ProjectAllocation>> GetProjectByEmployeeID(Guid employeeId)
|
||||||
|
{
|
||||||
|
List<ProjectAllocation> alloc = await _context.ProjectAllocations.Where(c => c.EmployeeId == employeeId && c.IsActive == true).Include(c => c.Project).ToListAsync();
|
||||||
|
return alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<ProjectAllocation>> GetTeamByProject(Guid TenantId, Guid ProjectId, bool IncludeInactive)
|
||||||
|
{
|
||||||
|
if (IncludeInactive)
|
||||||
|
{
|
||||||
|
|
||||||
|
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId).Include(e => e.Employee).ToListAsync();
|
||||||
|
|
||||||
|
return employees;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId && c.IsActive == true).Include(e => e.Employee).ToListAsync();
|
||||||
|
|
||||||
|
return employees;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Guid>> GetMyProjects(Guid tenantId, Employee LoggedInEmployee)
|
||||||
|
{
|
||||||
|
var projectIds = await _cache.GetProjects(LoggedInEmployee.Id);
|
||||||
|
|
||||||
|
if (projectIds == null)
|
||||||
|
{
|
||||||
|
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageProject, LoggedInEmployee.Id);
|
||||||
|
if (hasPermission)
|
||||||
|
{
|
||||||
|
var projects = await _context.Projects.Where(c => c.TenantId == tenantId).ToListAsync();
|
||||||
|
projectIds = projects.Select(p => p.Id).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var allocation = await GetProjectByEmployeeID(LoggedInEmployee.Id);
|
||||||
|
if (!allocation.Any())
|
||||||
|
{
|
||||||
|
return new List<Guid>();
|
||||||
|
}
|
||||||
|
projectIds = allocation.Select(c => c.ProjectId).Distinct().ToList();
|
||||||
|
}
|
||||||
|
await _cache.AddProjects(LoggedInEmployee.Id, projectIds);
|
||||||
|
}
|
||||||
|
return projectIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Guid>> GetMyProjectIdsAsync(Guid tenantId, Employee loggedInEmployee)
|
||||||
|
{
|
||||||
|
// 1. Attempt to retrieve the list of project IDs from the cache first.
|
||||||
|
// This is the "happy path" and should be as fast as possible.
|
||||||
|
List<Guid>? projectIds = await _cache.GetProjects(loggedInEmployee.Id);
|
||||||
|
|
||||||
|
if (projectIds != null)
|
||||||
|
{
|
||||||
|
// Cache Hit: Return the cached list immediately.
|
||||||
|
return projectIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Cache Miss: The list was not in the cache, so we must fetch it from the database.
|
||||||
|
List<Guid> newProjectIds;
|
||||||
|
|
||||||
|
// Check for the specific permission.
|
||||||
|
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageProject, loggedInEmployee.Id);
|
||||||
|
|
||||||
|
if (hasPermission)
|
||||||
|
{
|
||||||
|
// 3a. OPTIMIZATION: User has permission to see all projects.
|
||||||
|
// Fetch *only* the Ids directly from the database. This is far more efficient
|
||||||
|
// than fetching full Project objects and then selecting the Ids in memory.
|
||||||
|
newProjectIds = await _context.Projects
|
||||||
|
.Where(p => p.TenantId == tenantId)
|
||||||
|
.Select(p => p.Id) // This translates to `SELECT Id FROM Projects...` in SQL.
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 3b. OPTIMIZATION: User can only see projects they are allocated to.
|
||||||
|
// We go directly to the source (ProjectAllocations) and ask the database
|
||||||
|
// for a distinct list of ProjectIds. This is much better than calling a
|
||||||
|
// helper function that might return full allocation objects.
|
||||||
|
newProjectIds = await _context.ProjectAllocations
|
||||||
|
.Where(a => a.EmployeeId == loggedInEmployee.Id && a.ProjectId != Guid.Empty)
|
||||||
|
.Select(a => a.ProjectId)
|
||||||
|
.Distinct() // Pushes the DISTINCT operation to the database.
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Populate the cache with the newly fetched list (even if it's empty).
|
||||||
|
// This prevents repeated database queries for employees with no projects.
|
||||||
|
await _cache.AddProjects(loggedInEmployee.Id, newProjectIds);
|
||||||
|
|
||||||
|
return newProjectIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves a list of ProjectInfoVMs by their IDs, using an efficient partial cache-hit strategy.
|
/// Retrieves a list of ProjectInfoVMs by their IDs, using an efficient partial cache-hit strategy.
|
||||||
/// It fetches what it can from the cache (as ProjectMongoDB), gets the rest from the
|
/// It fetches what it can from the cache (as ProjectMongoDB), gets the rest from the
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Marco.Pms.Model.Dtos.Project;
|
using Marco.Pms.Model.Dtos.Project;
|
||||||
using Marco.Pms.Model.Employees;
|
using Marco.Pms.Model.Employees;
|
||||||
|
using Marco.Pms.Model.Projects;
|
||||||
using Marco.Pms.Model.Utilities;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.ViewModels.Projects;
|
using Marco.Pms.Model.ViewModels.Projects;
|
||||||
|
|
||||||
@ -25,5 +26,10 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
Task<ApiResponse<List<WorkItemVM>>> CreateProjectTaskAsync(List<WorkItemDto> workItemDtos, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<List<WorkItemVM>>> CreateProjectTaskAsync(List<WorkItemDto> workItemDtos, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ServiceResponse> DeleteProjectTaskAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
Task<ServiceResponse> DeleteProjectTaskAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
||||||
|
|
||||||
|
Task<List<Project>> GetAllProjectByTanentID(Guid tanentId);
|
||||||
|
Task<List<ProjectAllocation>> GetProjectByEmployeeID(Guid employeeId);
|
||||||
|
Task<List<ProjectAllocation>> GetTeamByProject(Guid TenantId, Guid ProjectId, bool IncludeInactive);
|
||||||
|
Task<List<Guid>> GetMyProjectIdsAsync(Guid tenantId, Employee LoggedInEmployee);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user