Added the name of the project name in view model
This commit is contained in:
parent
629c4541d6
commit
b1af96b923
@ -10,6 +10,7 @@ namespace Marco.Pms.Model.ViewModels.AttendanceVM
|
||||
public string? LastName { get; set; }
|
||||
public string? EmployeeAvatar { get; set; }
|
||||
public string? OrganizationName { get; set; }
|
||||
public string? ProjectName { get; set; }
|
||||
public DateTime? CheckInTime { get; set; }
|
||||
public DateTime? CheckOutTime { get; set; }
|
||||
public string? JobRoleName { get; set; }
|
||||
|
@ -4,7 +4,6 @@ using Marco.Pms.Model.Dtos.Attendance;
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Marco.Pms.Model.Mapper;
|
||||
using Marco.Pms.Model.Projects;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Model.ViewModels.AttendanceVM;
|
||||
using Marco.Pms.Services.Hubs;
|
||||
@ -146,18 +145,11 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
[HttpGet("project/log")]
|
||||
|
||||
public async Task<IActionResult> EmployeeAttendanceByDateRange([FromQuery] Guid projectId, [FromQuery] Guid? organizationId, [FromQuery] string? dateFrom = null, [FromQuery] string? dateTo = null)
|
||||
public async Task<IActionResult> EmployeeAttendanceByDateRange([FromQuery] Guid? projectId, [FromQuery] Guid? organizationId, [FromQuery] string? dateFrom = null, [FromQuery] string? dateTo = null)
|
||||
{
|
||||
Guid tenantId = GetTenantId();
|
||||
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
var project = await _context.Projects.AsNoTracking().FirstOrDefaultAsync(p => p.Id == projectId && p.TenantId == tenantId);
|
||||
if (project == null)
|
||||
{
|
||||
_logger.LogWarning("Project {ProjectId} not found in database", projectId);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Project not found."));
|
||||
}
|
||||
|
||||
var hasTeamAttendancePermission = await _permission.HasPermission(PermissionsMaster.TeamAttendance, LoggedInEmployee.Id);
|
||||
var hasSelfAttendancePermission = await _permission.HasPermission(PermissionsMaster.SelfAttendance, LoggedInEmployee.Id);
|
||||
|
||||
@ -175,35 +167,41 @@ namespace MarcoBMS.Services.Controllers
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Date", "Invalid Date", 400));
|
||||
}
|
||||
|
||||
if (projectId == Guid.Empty)
|
||||
{
|
||||
_logger.LogWarning("The project Id sent by user is less than or equal to zero");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Project ID is required and must be greater than zero.", "Project ID is required and must be greater than zero.", 400));
|
||||
}
|
||||
|
||||
var result = new List<EmployeeAttendanceVM>();
|
||||
//Attendance? attendance = null;
|
||||
|
||||
if (dateFrom == null) fromDate = DateTime.UtcNow.Date;
|
||||
if (dateTo == null && dateFrom != null) toDate = fromDate.AddDays(-1);
|
||||
|
||||
if (hasTeamAttendancePermission)
|
||||
{
|
||||
List<Attendance> lstAttendance = await _context.Attendes
|
||||
var lstAttendanceQuery = _context.Attendes
|
||||
.Include(a => a.Employee)
|
||||
.ThenInclude(e => e!.Organization)
|
||||
.Include(a => a.Employee)
|
||||
.ThenInclude(e => e!.JobRole)
|
||||
.Where(a => a.ProjectID == projectId &&
|
||||
a.AttendanceDate.Date >= fromDate.Date &&
|
||||
a.AttendanceDate.Date <= toDate.Date &&
|
||||
a.TenantId == tenantId &&
|
||||
a.Employee != null &&
|
||||
a.Employee.Organization != null &&
|
||||
a.Employee.JobRole != null
|
||||
).ToListAsync();
|
||||
.Where(a =>
|
||||
a.AttendanceDate.Date >= fromDate.Date &&
|
||||
a.AttendanceDate.Date <= toDate.Date &&
|
||||
a.TenantId == tenantId &&
|
||||
a.Employee != null &&
|
||||
a.Employee.Organization != null &&
|
||||
a.Employee.JobRole != null);
|
||||
if (organizationId.HasValue)
|
||||
{
|
||||
lstAttendanceQuery = lstAttendanceQuery.Where(a => a.Employee != null && a.Employee.OrganizationId == organizationId);
|
||||
}
|
||||
|
||||
if (projectId.HasValue)
|
||||
{
|
||||
lstAttendanceQuery = lstAttendanceQuery.Where(a => a.ProjectID == projectId);
|
||||
}
|
||||
|
||||
if (hasTeamAttendancePermission)
|
||||
{
|
||||
List<Attendance> lstAttendance = await lstAttendanceQuery.ToListAsync();
|
||||
|
||||
var projectIds = lstAttendance.Select(a => a.ProjectID).ToList();
|
||||
var projects = await _context.Projects.Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).ToListAsync();
|
||||
|
||||
var jobRole = await _context.JobRoles.ToListAsync();
|
||||
foreach (Attendance? attendance in lstAttendance)
|
||||
{
|
||||
var result1 = new EmployeeAttendanceVM()
|
||||
@ -216,6 +214,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
FirstName = attendance.Employee?.FirstName,
|
||||
LastName = attendance.Employee?.LastName,
|
||||
JobRoleName = attendance.Employee?.JobRole?.Name,
|
||||
ProjectName = projects.Where(p => p.Id == attendance.ProjectID).Select(p => p.Name).FirstOrDefault(),
|
||||
OrganizationName = attendance.Employee?.Organization?.Name
|
||||
|
||||
};
|
||||
@ -224,26 +223,12 @@ namespace MarcoBMS.Services.Controllers
|
||||
}
|
||||
else if (hasSelfAttendancePermission)
|
||||
{
|
||||
var lstAttendanceQuery = _context.Attendes
|
||||
.Include(a => a.Employee)
|
||||
.ThenInclude(e => e!.Organization)
|
||||
.Include(a => a.Employee)
|
||||
.ThenInclude(e => e!.JobRole)
|
||||
.Where(a => a.ProjectID == projectId &&
|
||||
a.EmployeeId == LoggedInEmployee.Id &&
|
||||
a.AttendanceDate.Date >= fromDate.Date &&
|
||||
a.AttendanceDate.Date <= toDate.Date &&
|
||||
a.TenantId == tenantId &&
|
||||
a.Employee != null &&
|
||||
a.Employee.Organization != null &&
|
||||
a.Employee.JobRole != null);
|
||||
|
||||
if (organizationId.HasValue)
|
||||
{
|
||||
lstAttendanceQuery = lstAttendanceQuery.Where(a => a.Employee != null && a.Employee.OrganizationId == organizationId);
|
||||
}
|
||||
var lstAttendances = await lstAttendanceQuery.Where(a => a.EmployeeId == LoggedInEmployee.Id).ToListAsync();
|
||||
|
||||
var projectIds = lstAttendances.Select(a => a.ProjectID).ToList();
|
||||
var projects = await _context.Projects.Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).ToListAsync();
|
||||
|
||||
var lstAttendances = await lstAttendanceQuery.ToListAsync();
|
||||
|
||||
foreach (var attendance in lstAttendances)
|
||||
{
|
||||
@ -255,6 +240,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
FirstName = attendance.Employee?.FirstName,
|
||||
LastName = attendance.Employee?.LastName,
|
||||
JobRoleName = attendance.Employee?.JobRole?.Name,
|
||||
ProjectName = projects.Where(p => p.Id == attendance.ProjectID).Select(p => p.Name).FirstOrDefault(),
|
||||
OrganizationName = attendance.Employee?.Organization?.Name,
|
||||
CheckInTime = attendance.InTime,
|
||||
CheckOutTime = attendance.OutTime,
|
||||
@ -278,13 +264,13 @@ namespace MarcoBMS.Services.Controllers
|
||||
/// <param name="includeInactive">Optional. Includes inactive employees in the team list if true.</param>
|
||||
/// <param name="date">Optional. The date for which to fetch attendance, in "yyyy-MM-dd" format. Defaults to the current UTC date.</param>
|
||||
/// <returns>An IActionResult containing a list of employee attendance records or an error response.</returns>
|
||||
public async Task<IActionResult> EmployeeAttendanceByProjectAsync([FromQuery] Guid projectId, [FromQuery] Guid? organizationId, [FromQuery] bool includeInactive, [FromQuery] string? date = null)
|
||||
public async Task<IActionResult> EmployeeAttendanceByProjectAsync([FromQuery] Guid? projectId, [FromQuery] Guid? organizationId, [FromQuery] bool includeInactive, [FromQuery] string? date = null)
|
||||
{
|
||||
var tenantId = GetTenantId();
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
// --- 1. Initial Validation and Permission Checks ---
|
||||
_logger.LogInfo("Fetching attendance for ProjectId: {ProjectId}, TenantId: {TenantId}", projectId, tenantId);
|
||||
_logger.LogInfo("Fetching attendance for ProjectId: {ProjectId}, TenantId: {TenantId}", projectId ?? Guid.Empty, tenantId);
|
||||
|
||||
// Validate date format
|
||||
if (!DateTime.TryParse(date, out var forDate))
|
||||
@ -292,14 +278,6 @@ namespace MarcoBMS.Services.Controllers
|
||||
forDate = DateTime.UtcNow.Date; // Default to today's date
|
||||
}
|
||||
|
||||
// Check if the project exists and if the employee has access
|
||||
var project = await _context.Projects.AsNoTracking().FirstOrDefaultAsync(p => p.Id == projectId && p.TenantId == tenantId);
|
||||
if (project == null)
|
||||
{
|
||||
_logger.LogWarning("Project {ProjectId} not found in database", projectId);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Project not found."));
|
||||
}
|
||||
|
||||
// --- 2. Delegate to Specific Logic Based on Permissions ---
|
||||
try
|
||||
{
|
||||
@ -326,50 +304,63 @@ namespace MarcoBMS.Services.Controllers
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("You do not have permission to view attendance.", new { }, 403));
|
||||
}
|
||||
|
||||
_logger.LogInfo("Successfully fetched {Count} attendance records for ProjectId: {ProjectId}", result.Count, projectId);
|
||||
_logger.LogInfo("Successfully fetched {Count} attendance records for ProjectId: {ProjectId}", result.Count, projectId ?? Guid.Empty);
|
||||
return Ok(ApiResponse<object>.SuccessResponse(result, $"{result.Count} attendance records fetched successfully."));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "An error occurred while fetching attendance for ProjectId: {ProjectId}", projectId);
|
||||
_logger.LogError(ex, "An error occurred while fetching attendance for ProjectId: {ProjectId}", projectId ?? Guid.Empty);
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("An internal server error occurred."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("regularize")]
|
||||
public async Task<IActionResult> GetRequestRegularizeAttendance([FromQuery] Guid projectId, [FromQuery] Guid? organizationId, [FromQuery] bool IncludeInActive)
|
||||
public async Task<IActionResult> GetRequestRegularizeAttendance([FromQuery] Guid? projectId, [FromQuery] Guid? organizationId, [FromQuery] bool IncludeInActive)
|
||||
{
|
||||
Guid TenantId = GetTenantId();
|
||||
Employee LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var result = new List<EmployeeAttendanceVM>();
|
||||
|
||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE && c.TenantId == TenantId).ToListAsync();
|
||||
var lstAttendanceQuery = _context.Attendes
|
||||
.Include(a => a.Employee)
|
||||
.ThenInclude(e => e!.Organization)
|
||||
.Include(a => a.Employee)
|
||||
.ThenInclude(e => e!.JobRole)
|
||||
.Where(c => c.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE && c.Employee != null && c.Employee.JobRole != null && c.TenantId == TenantId);
|
||||
|
||||
List<ProjectAllocation> projectteam = await _projectServices.GetTeamByProject(TenantId, projectId, organizationId, true);
|
||||
var idList = projectteam.Select(p => p.EmployeeId).ToList();
|
||||
var jobRole = await _context.JobRoles.ToListAsync();
|
||||
if (organizationId.HasValue)
|
||||
{
|
||||
lstAttendanceQuery = lstAttendanceQuery.Where(a => a.Employee != null && a.Employee.OrganizationId == organizationId);
|
||||
}
|
||||
|
||||
if (projectId.HasValue)
|
||||
{
|
||||
lstAttendanceQuery = lstAttendanceQuery.Where(a => a.ProjectID == projectId);
|
||||
}
|
||||
|
||||
List<Attendance> lstAttendance = await lstAttendanceQuery.ToListAsync();
|
||||
|
||||
var projectIds = lstAttendance.Select(a => a.ProjectID).ToList();
|
||||
var projects = await _context.Projects.Where(p => projectIds.Contains(p.Id) && p.TenantId == TenantId).ToListAsync();
|
||||
|
||||
foreach (Attendance attende in lstAttendance)
|
||||
{
|
||||
var teamMember = projectteam.Find(m => m.EmployeeId == attende.EmployeeId);
|
||||
if (teamMember != null && teamMember.Employee != null && teamMember.Employee.JobRole != null)
|
||||
var result1 = new EmployeeAttendanceVM()
|
||||
{
|
||||
var result1 = new EmployeeAttendanceVM()
|
||||
{
|
||||
Id = attende.Id,
|
||||
CheckInTime = attende.InTime,
|
||||
CheckOutTime = attende.OutTime,
|
||||
Activity = attende.Activity,
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = attende.EmployeeId,
|
||||
FirstName = teamMember.Employee.FirstName,
|
||||
LastName = teamMember.Employee.LastName,
|
||||
JobRoleName = teamMember.Employee.JobRole.Name,
|
||||
OrganizationName = teamMember.Employee.Organization?.Name
|
||||
};
|
||||
result.Add(result1);
|
||||
}
|
||||
Id = attende.Id,
|
||||
CheckInTime = attende.InTime,
|
||||
CheckOutTime = attende.OutTime,
|
||||
Activity = attende.Activity,
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = attende.EmployeeId,
|
||||
FirstName = attende.Employee?.FirstName,
|
||||
ProjectName = projects.Where(p => p.Id == attende.ProjectID).Select(p => p.Name).FirstOrDefault(),
|
||||
LastName = attende.Employee?.LastName,
|
||||
JobRoleName = attende.Employee?.JobRole?.Name,
|
||||
OrganizationName = attende.Employee?.Organization?.Name
|
||||
};
|
||||
result.Add(result1);
|
||||
|
||||
|
||||
}
|
||||
@ -793,7 +784,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
/// <summary>
|
||||
/// Fetches attendance for an entire project team using a single, optimized database query.
|
||||
/// </summary>
|
||||
private async Task<List<EmployeeAttendanceVM>> GetTeamAttendanceAsync(Guid tenantId, Guid projectId, Guid organizationId, DateTime forDate, bool includeInactive)
|
||||
private async Task<List<EmployeeAttendanceVM>> GetTeamAttendanceAsync(Guid tenantId, Guid? projectId, Guid organizationId, DateTime forDate, bool includeInactive)
|
||||
{
|
||||
// This single query joins ProjectAllocations with Employees and performs a LEFT JOIN with Attendances.
|
||||
// This is far more efficient than fetching collections and joining them in memory.
|
||||
@ -803,12 +794,22 @@ namespace MarcoBMS.Services.Controllers
|
||||
.Where(e => e.OrganizationId == organizationId && e.Organization != null && e.JobRole != null && e.IsActive);
|
||||
|
||||
|
||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date == forDate && c.TenantId == tenantId).ToListAsync();
|
||||
var lstAttendanceQuery = _context.Attendes.Where(c => c.AttendanceDate.Date == forDate && c.TenantId == tenantId);
|
||||
|
||||
if (projectId.HasValue)
|
||||
{
|
||||
lstAttendanceQuery = lstAttendanceQuery.Where(a => a.ProjectID == projectId);
|
||||
}
|
||||
|
||||
List<Attendance> lstAttendance = await lstAttendanceQuery.ToListAsync();
|
||||
|
||||
var employees = await query
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
|
||||
var projectIds = lstAttendance.Select(a => a.ProjectID).ToList();
|
||||
var projects = await _context.Projects.Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).ToListAsync();
|
||||
|
||||
var response = employees
|
||||
.Select(employee =>
|
||||
{
|
||||
@ -822,9 +823,6 @@ namespace MarcoBMS.Services.Controllers
|
||||
JobRoleName = employee.JobRole!.Name,
|
||||
};
|
||||
|
||||
//var member = emp.Where(e => e.Id == teamMember.EmployeeId);
|
||||
|
||||
|
||||
var attendance = lstAttendance.Find(x => x.EmployeeId == employee.Id) ?? new Attendance();
|
||||
if (attendance != null)
|
||||
{
|
||||
@ -832,6 +830,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
result1.CheckInTime = attendance.InTime;
|
||||
result1.CheckOutTime = attendance.OutTime;
|
||||
result1.Activity = attendance.Activity;
|
||||
result1.ProjectName = projects.Where(p => p.Id == attendance.ProjectID).Select(p => p.Name).FirstOrDefault();
|
||||
}
|
||||
return result1;
|
||||
})
|
||||
@ -844,13 +843,23 @@ namespace MarcoBMS.Services.Controllers
|
||||
/// <summary>
|
||||
/// Fetches a single attendance record for the logged-in employee.
|
||||
/// </summary>
|
||||
private async Task<List<EmployeeAttendanceVM>> GetSelfAttendanceAsync(Guid tenantId, Guid projectId, Guid employeeId, DateTime forDate)
|
||||
private async Task<List<EmployeeAttendanceVM>> GetSelfAttendanceAsync(Guid tenantId, Guid? projectId, Guid employeeId, DateTime forDate)
|
||||
{
|
||||
List<EmployeeAttendanceVM> result = new List<EmployeeAttendanceVM>();
|
||||
|
||||
// This query fetches the employee's project allocation and their attendance in a single trip.
|
||||
Attendance lstAttendance = await _context.Attendes
|
||||
.FirstOrDefaultAsync(c => c.ProjectID == projectId && c.EmployeeId == employeeId && c.AttendanceDate.Date == forDate && c.TenantId == tenantId) ?? new Attendance();
|
||||
var lstAttendanceQuery = _context.Attendes
|
||||
.Where(c => c.EmployeeId == employeeId && c.AttendanceDate.Date == forDate && c.TenantId == tenantId);
|
||||
|
||||
if (projectId.HasValue)
|
||||
{
|
||||
lstAttendanceQuery = lstAttendanceQuery.Where(a => a.ProjectID == projectId);
|
||||
}
|
||||
|
||||
Attendance lstAttendance = await lstAttendanceQuery.FirstOrDefaultAsync() ?? new Attendance();
|
||||
|
||||
var project = await _context.Projects.FirstOrDefaultAsync(p => p.Id == lstAttendance.ProjectID && p.TenantId == tenantId);
|
||||
|
||||
|
||||
var employee = await _context.Employees
|
||||
.Include(e => e.Organization)
|
||||
@ -866,6 +875,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
EmployeeId = employee.Id,
|
||||
FirstName = employee.FirstName,
|
||||
OrganizationName = employee.Organization.Name,
|
||||
ProjectName = project?.Name,
|
||||
LastName = employee.LastName,
|
||||
JobRoleName = employee.JobRole.Name,
|
||||
CheckInTime = lstAttendance.InTime,
|
||||
|
Loading…
x
Reference in New Issue
Block a user