Merge pull request 'Implement an API endpoint that allows for to suspension of an employee.' (#35) from Ashutosh_Feature#174_Suspend_Employee into main

Reviewed-on: #35
This commit is contained in:
Vikas Nale 2025-05-05 12:03:30 +00:00
commit 64a178931c
3 changed files with 101 additions and 20 deletions

View File

@ -1,10 +1,12 @@
using System.Data; using System.Data;
using System.Net; using System.Net;
using Marco.Pms.DataAccess.Data; using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Dtos.Attendance;
using Marco.Pms.Model.Dtos.Employees; using Marco.Pms.Model.Dtos.Employees;
using Marco.Pms.Model.Employees; using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Mapper; using Marco.Pms.Model.Mapper;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Utilities; using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels; using Marco.Pms.Model.ViewModels;
using Marco.Pms.Model.ViewModels.Employee; using Marco.Pms.Model.ViewModels.Employee;
@ -30,10 +32,10 @@ namespace MarcoBMS.Services.Controllers
private readonly EmployeeHelper _employeeHelper; private readonly EmployeeHelper _employeeHelper;
private readonly UserHelper _userHelper; private readonly UserHelper _userHelper;
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private readonly ILoggingService _logger;
public EmployeeController(UserManager<ApplicationUser> userManager, IEmailSender emailSender, public EmployeeController(UserManager<ApplicationUser> userManager, IEmailSender emailSender,
ApplicationDbContext context, EmployeeHelper employeeHelper, UserHelper userHelper, IConfiguration configuration) ApplicationDbContext context, EmployeeHelper employeeHelper, UserHelper userHelper, IConfiguration configuration, ILoggingService logger)
{ {
_context = context; _context = context;
_userManager = userManager; _userManager = userManager;
@ -41,6 +43,7 @@ namespace MarcoBMS.Services.Controllers
_employeeHelper = employeeHelper; _employeeHelper = employeeHelper;
_userHelper = userHelper; _userHelper = userHelper;
_configuration = configuration; _configuration = configuration;
_logger = logger;
} }
[HttpGet] [HttpGet]
@ -204,15 +207,15 @@ namespace MarcoBMS.Services.Controllers
if (model.Email != null) if (model.Email != null)
{ {
// Check if user already exists by email // Check if user already exists by email
IdentityUser? existingUser = await _userHelper.GetRegisteredUser(model.Email); IdentityUser existingUser = await _userHelper.GetRegisteredUser(model.Email) ?? new IdentityUser();
var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id); var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id && e.IsActive == true);
if (existingUser != null) if (existingUser != null)
{ {
/* Identity user Exists - Create/update employee Employee */ /* Identity user Exists - Create/update employee Employee */
// Update Employee record // Update Employee record
existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Email == model.Email && e.Id == model.Id); existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Email == model.Email && e.Id == model.Id && e.IsActive == true);
if (existingEmployee != null) if (existingEmployee != null)
{ {
existingEmployee = GetUpdateEmployeeModel(model, existingEmployee, existingUser); existingEmployee = GetUpdateEmployeeModel(model, existingEmployee, existingUser);
@ -289,7 +292,7 @@ namespace MarcoBMS.Services.Controllers
} }
else else
{ {
var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id); var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id && e.IsActive == true);
if (existingEmployee != null) if (existingEmployee != null)
{ {
existingEmployee = GetUpdateEmployeeModel(model, existingEmployee); existingEmployee = GetUpdateEmployeeModel(model, existingEmployee);
@ -299,22 +302,100 @@ namespace MarcoBMS.Services.Controllers
else else
{ {
// Create Employee record if missing // Create Employee record if missing
Employee newEmployee = GetNewEmployeeModel(model, tenantId, null); Employee newEmployee = GetNewEmployeeModel(model, tenantId, string.Empty);
_context.Employees.Add(newEmployee); _context.Employees.Add(newEmployee);
} }
try
await _context.SaveChangesAsync(); {
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
return BadRequest(ex.InnerException?.Message ?? ex.Message);
}
responsemessage = "User created successfully."; responsemessage = "User created successfully.";
} }
return Ok(ApiResponse<object>.SuccessResponse("Success.", responsemessage, 200)); return Ok(ApiResponse<object>.SuccessResponse("Success.", responsemessage, 200));
} }
#nullable disable
[HttpDelete("{id}")]
public async Task<IActionResult> SuspendEmployee(Guid id)
{
Guid tenantId = _userHelper.GetTenantId();
Employee? employee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == id && e.TenantId == tenantId);
if (employee != null)
{
var assignedToTasks = await _context.TaskMembers.Where(t => t.EmployeeId == employee.Id).ToListAsync();
if (assignedToTasks.Count != 0)
{
List<Guid> taskIds = assignedToTasks.Select(t => t.TaskAllocationId).ToList();
var tasks = await _context.TaskAllocations.Where(t => taskIds.Contains(t.Id)).ToListAsync();
foreach (var assignedToTask in assignedToTasks)
{
var task = tasks.Find(t => t.Id == assignedToTask.TaskAllocationId);
if (task != null && task.CompletedTask == 0)
{
_logger.LogWarning("Employee with ID {EmployeeId} is currently assigned to any incomplete task", employee.Id);
return BadRequest(ApiResponse<object>.ErrorResponse("Employee is currently assigned to any incomplete task", "Employee is currently assigned to any incomplete task", 400));
}
}
}
var attendance = await _context.Attendes.Where(a => a.EmployeeID == employee.Id && (a.OutTime == null || a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE)).ToListAsync();
if (attendance.Count != 0)
{
_logger.LogWarning("Employee with ID {EmployeeId} have any pending check-out or regularization requests", employee.Id);
return BadRequest(ApiResponse<object>.ErrorResponse("Employee have any pending check-out or regularization requests", "Employee have any pending check-out or regularization requests", 400));
}
employee.IsActive = false;
var projectAllocations = await _context.ProjectAllocations.Where(a => a.EmployeeId == employee.Id).ToListAsync();
if (projectAllocations.Count != 0)
{
List<ProjectAllocation> allocations = new List<ProjectAllocation>();
foreach (var projectAllocation in projectAllocations)
{
projectAllocation.ReAllocationDate = DateTime.UtcNow;
projectAllocation.IsActive = false;
allocations.Add(projectAllocation);
}
_logger.LogInfo("Employee with ID {EmployeeId} has been removed from all assigned projects.", employee.Id);
}
var user = await _context.ApplicationUsers.FirstOrDefaultAsync(u => u.Id == employee.ApplicationUserId);
if (user != null)
{
user.IsActive = false;
_logger.LogInfo("The application user associated with employee ID {EmployeeId} has been suspended.", employee.Id);
var refreshTokens = await _context.RefreshTokens.AsNoTracking().Where(t => t.UserId == user.Id).ToListAsync();
if (refreshTokens.Count != 0)
{
_context.RefreshTokens.RemoveRange(refreshTokens);
_logger.LogInfo("Refresh tokens associated with employee ID {EmployeeId} has been removed.", employee.Id);
}
}
var roleMapping = await _context.EmployeeRoleMappings.AsNoTracking().Where(r => r.EmployeeId == employee.Id).ToListAsync();
if (roleMapping.Count != 0)
{
_context.EmployeeRoleMappings.RemoveRange(roleMapping);
_logger.LogInfo("Application role mapping associated with employee ID {EmployeeId} has been removed.", employee.Id);
}
await _context.SaveChangesAsync();
_logger.LogInfo("Employee with ID {EmployeId} Deleted successfully", employee.Id);
}
else
{
_logger.LogError("Employee with ID {EmploueeId} not found in database", id);
}
return Ok(ApiResponse<object>.SuccessResponse(new { }, "Employee Suspended successfully", 200));
}
private static Employee GetNewEmployeeModel(CreateUserDto model, Guid TenantId, string ApplicationUserId) private static Employee GetNewEmployeeModel(CreateUserDto model, Guid TenantId, string ApplicationUserId)
{ {
var newEmployee = new Employee var newEmployee = new Employee
{ {
ApplicationUserId = ApplicationUserId, ApplicationUserId = String.IsNullOrEmpty(ApplicationUserId) ? null : ApplicationUserId,
FirstName = model.FirstName, FirstName = model.FirstName,
LastName = model.LastName, LastName = model.LastName,
Email = model.Email, Email = model.Email,
@ -337,7 +418,7 @@ namespace MarcoBMS.Services.Controllers
return newEmployee; return newEmployee;
} }
private static Employee GetUpdateEmployeeModel(CreateUserDto model, Employee existingEmployee, IdentityUser existingIdentityUser = null) private static Employee GetUpdateEmployeeModel(CreateUserDto model, Employee existingEmployee, IdentityUser? existingIdentityUser = null)
{ {
if (existingEmployee.ApplicationUserId == null && existingIdentityUser != null) if (existingEmployee.ApplicationUserId == null && existingIdentityUser != null)
{ {

View File

@ -20,16 +20,16 @@ namespace MarcoBMS.Services.Helpers
public async Task<Employee> GetEmployeeByID(Guid EmployeeID) public async Task<Employee> GetEmployeeByID(Guid EmployeeID)
{ {
return await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.Id == EmployeeID) ?? new Employee { }; return await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.Id == EmployeeID && e.IsActive == true) ?? new Employee { };
} }
public async Task<Employee> GetEmployeeByApplicationUserID(string ApplicationUserID) public async Task<Employee> GetEmployeeByApplicationUserID(string ApplicationUserID)
{ {
try try
{ {
var result = await _context.Employees.Where(c => c.ApplicationUserId == ApplicationUserID).ToListAsync(); var result = await _context.Employees.Where(c => c.ApplicationUserId == ApplicationUserID && c.IsActive == true).ToListAsync();
return await _context.Employees.Where(c => c.ApplicationUserId == ApplicationUserID).SingleOrDefaultAsync() ?? new Employee { }; return await _context.Employees.Where(c => c.ApplicationUserId == ApplicationUserID && c.IsActive == true).SingleOrDefaultAsync() ?? new Employee { };
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -47,7 +47,7 @@ namespace MarcoBMS.Services.Helpers
{ {
result = await (from pa in _context.ProjectAllocations.Where(c => c.ProjectId == ProjectId) result = await (from pa in _context.ProjectAllocations.Where(c => c.ProjectId == ProjectId)
join em in _context.Employees.Where(c => c.TenantId == TenentId).Include(fp => fp.JobRole) // Include Feature join em in _context.Employees.Where(c => c.TenantId == TenentId && c.IsActive == true).Include(fp => fp.JobRole) // Include Feature
on pa.EmployeeId equals em.Id on pa.EmployeeId equals em.Id
where (em.FirstName != null ? em.FirstName.ToLower().Contains(searchString.ToLower()) : false) || (em.LastName != null ? em.LastName.ToLower().Contains(searchString.ToLower()) : false) where (em.FirstName != null ? em.FirstName.ToLower().Contains(searchString.ToLower()) : false) || (em.LastName != null ? em.LastName.ToLower().Contains(searchString.ToLower()) : false)
select em.ToEmployeeVMFromEmployee() select em.ToEmployeeVMFromEmployee()
@ -57,7 +57,7 @@ namespace MarcoBMS.Services.Helpers
} }
else else
{ {
result = await _context.Employees.Where(c => c.TenantId == TenentId && result = await _context.Employees.Where(c => c.TenantId == TenentId && c.IsActive == true &&
((c.FirstName != null ? c.FirstName.ToLower().Contains(searchString.ToLower()) : false) || (c.LastName != null ? c.LastName.ToLower().Contains(searchString.ToLower()) : false))).Include(fp => fp.JobRole) ((c.FirstName != null ? c.FirstName.ToLower().Contains(searchString.ToLower()) : false) || (c.LastName != null ? c.LastName.ToLower().Contains(searchString.ToLower()) : false))).Include(fp => fp.JobRole)
.Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync(); .Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync();
} }
@ -80,7 +80,7 @@ namespace MarcoBMS.Services.Helpers
{ {
result = await (from pa in _context.ProjectAllocations.Where(c => c.ProjectId == ProjectId) result = await (from pa in _context.ProjectAllocations.Where(c => c.ProjectId == ProjectId)
join em in _context.Employees.Where(c => c.TenantId == TenentId).Include(fp => fp.JobRole) // Include Feature join em in _context.Employees.Where(c => c.TenantId == TenentId && c.IsActive == true).Include(fp => fp.JobRole) // Include Feature
on pa.EmployeeId equals em.Id on pa.EmployeeId equals em.Id
select em.ToEmployeeVMFromEmployee() select em.ToEmployeeVMFromEmployee()
) )
@ -89,7 +89,7 @@ namespace MarcoBMS.Services.Helpers
} }
else else
{ {
result = await _context.Employees.Where(c => c.TenantId == TenentId).Include(fp => fp.JobRole) result = await _context.Employees.Where(c => c.TenantId == TenentId && c.IsActive == true).Include(fp => fp.JobRole)
.Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync(); .Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync();
} }

View File

@ -39,7 +39,7 @@ namespace MarcoBMS.Services.Helpers
{ {
var user = await GetCurrentUserAsync(); var user = await GetCurrentUserAsync();
if (user == null) return new Employee { }; if (user == null) return new Employee { };
var Employee = await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.ApplicationUserId == user.Id); var Employee = await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.ApplicationUserId == user.Id && e.IsActive);
return Employee ?? new Employee { }; return Employee ?? new Employee { };
} }