Added the API to get latest tagging entitry for current employee
This commit is contained in:
parent
08a336be37
commit
897537a60c
@ -6,14 +6,11 @@ namespace Marco.Pms.Model.ViewModels.ServiceProject
|
|||||||
public class JobAttendanceVM
|
public class JobAttendanceVM
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid JobTcketId { get; set; }
|
|
||||||
public BasicJobTicketVM? JobTicket { get; set; }
|
public BasicJobTicketVM? JobTicket { get; set; }
|
||||||
public TAGGING_MARK_TYPE Action { get; set; }
|
public TAGGING_MARK_TYPE? Action { get; set; }
|
||||||
public TAGGING_MARK_TYPE? NextAction { get; set; }
|
public TAGGING_MARK_TYPE? NextAction { get; set; }
|
||||||
public BasicEmployeeVM? Employee { get; set; }
|
public BasicEmployeeVM? Employee { get; set; }
|
||||||
public DateTime TaggedInTime { get; set; }
|
public DateTime? TaggedInTime { get; set; }
|
||||||
public DateTime? TaggedOutTime { get; set; }
|
public DateTime? TaggedOutTime { get; set; }
|
||||||
public DateTime TaggedInAt { get; set; }
|
|
||||||
public DateTime? TaggedOutAt { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -262,7 +262,16 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
|
|
||||||
#region =================================================================== Job Tagging Functions ===================================================================
|
#region =================================================================== Job Tagging Functions ===================================================================
|
||||||
|
|
||||||
[HttpGet("job/attendance/team")]
|
[HttpGet("job/attendance/self/{jobTicketId}")]
|
||||||
|
public async Task<IActionResult> GetAttendanceForSelf(Guid jobTicketId)
|
||||||
|
{
|
||||||
|
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
var response = await _serviceProject.GetAttendanceForSelfAsync(jobTicketId, loggedInEmployee, tenantId);
|
||||||
|
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("job/attendance/team/history")]
|
||||||
public async Task<IActionResult> GetAttendanceForJobTeam([FromQuery] Guid jobTicketId, [FromQuery] DateTime? fromDate, [FromQuery] DateTime? toDate)
|
public async Task<IActionResult> GetAttendanceForJobTeam([FromQuery] Guid jobTicketId, [FromQuery] DateTime? fromDate, [FromQuery] DateTime? toDate)
|
||||||
{
|
{
|
||||||
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
|||||||
@ -37,6 +37,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Job Tagging Functions ===================================================================
|
#region =================================================================== Job Tagging Functions ===================================================================
|
||||||
|
Task<ApiResponse<object>> GetAttendanceForSelfAsync(Guid jobTicketId, Employee loggedInEmployee, Guid tenantId);
|
||||||
Task<ApiResponse<object>> GetAttendanceForJobTeamAsync(Guid jobTicketId, DateTime? startDate, DateTime? endDate, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetAttendanceForJobTeamAsync(Guid jobTicketId, DateTime? startDate, DateTime? endDate, Employee loggedInEmployee, Guid tenantId);
|
||||||
Task<ApiResponse<object>> ManageJobTaggingAsync(JobAttendanceDto model, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> ManageJobTaggingAsync(JobAttendanceDto model, Employee loggedInEmployee, Guid tenantId);
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -2014,6 +2014,63 @@ namespace Marco.Pms.Services.Service
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Job Tagging Functions ===================================================================
|
#region =================================================================== Job Tagging Functions ===================================================================
|
||||||
|
public async Task<ApiResponse<object>> GetAttendanceForSelfAsync(Guid jobTicketId, Employee loggedInEmployee, Guid tenantId)
|
||||||
|
{
|
||||||
|
_logger.LogInfo("GetAttendanceForSelfAsync initiated for EmployeeId: {EmployeeId}, JobTicketId: {JobTicketId}", loggedInEmployee.Id, jobTicketId);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Validate existence of the Job Ticket with related Status
|
||||||
|
var jobTicket = await _context.JobTickets
|
||||||
|
.AsNoTracking()
|
||||||
|
.Include(jt => jt.Status)
|
||||||
|
.FirstOrDefaultAsync(jt => jt.Id == jobTicketId && jt.TenantId == tenantId && jt.IsActive);
|
||||||
|
|
||||||
|
if (jobTicket == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("JobTicket not found. JobTicketId: {JobTicketId}, TenantId: {TenantId}", jobTicketId, tenantId);
|
||||||
|
return ApiResponse<object>.ErrorResponse("Job not found", "Job is not found", 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the most recent attendance record for the logged-in employee for the specified job
|
||||||
|
var jobAttendance = await _context.JobAttendance
|
||||||
|
.AsNoTracking()
|
||||||
|
.Include(ja => ja.JobTicket).ThenInclude(jt => jt!.Status)
|
||||||
|
.Include(ja => ja.Employee).ThenInclude(e => e!.JobRole)
|
||||||
|
.Where(ja => ja.JobTcketId == jobTicketId && ja.EmployeeId == loggedInEmployee.Id && ja.TenantId == tenantId)
|
||||||
|
.OrderByDescending(ja => ja.TaggedInTime)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
JobAttendanceVM response;
|
||||||
|
|
||||||
|
// If no attendance record exists or last record is tagged out or for a different day, prepare a default response with next action TAG_IN
|
||||||
|
if (jobAttendance == null || (jobAttendance.TaggedOutTime.HasValue && jobAttendance.TaggedInTime.Date != DateTime.UtcNow.Date))
|
||||||
|
{
|
||||||
|
response = new JobAttendanceVM
|
||||||
|
{
|
||||||
|
JobTicket = _mapper.Map<BasicJobTicketVM>(jobTicket),
|
||||||
|
Employee = _mapper.Map<BasicEmployeeVM>(loggedInEmployee),
|
||||||
|
NextAction = TAGGING_MARK_TYPE.TAG_IN
|
||||||
|
};
|
||||||
|
_logger.LogInfo("No current active attendance found for EmployeeId: {EmployeeId}. Prompting to TAG_IN.", loggedInEmployee.Id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Active attendance exists, returning last attendance with details
|
||||||
|
response = _mapper.Map<JobAttendanceVM>(jobAttendance);
|
||||||
|
_logger.LogInfo("Latest attendance fetched for EmployeeId: {EmployeeId} on JobTicketId: {JobTicketId}", loggedInEmployee.Id, jobTicketId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return success with the constructed response
|
||||||
|
return ApiResponse<object>.SuccessResponse(response, "Latest job tagging for current employee fetched successfully", 200);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Unhandled exception in GetAttendanceForSelfAsync for EmployeeId: {EmployeeId}, JobTicketId: {JobTicketId}", loggedInEmployee.Id, jobTicketId);
|
||||||
|
return ApiResponse<object>.ErrorResponse("An unexpected error occurred.", ex.Message, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<ApiResponse<object>> GetAttendanceForJobTeamAsync(Guid jobTicketId, DateTime? startDate, DateTime? endDate, Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> GetAttendanceForJobTeamAsync(Guid jobTicketId, DateTime? startDate, DateTime? endDate, Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
_logger.LogInfo("GetAttendanceForJobTeamAsync called for JobTicketId: {JobTicketId}, TenantId: {TenantId}, EmployeeId: {EmployeeId}", jobTicketId, tenantId, loggedInEmployee.Id);
|
_logger.LogInfo("GetAttendanceForJobTeamAsync called for JobTicketId: {JobTicketId}, TenantId: {TenantId}, EmployeeId: {EmployeeId}", jobTicketId, tenantId, loggedInEmployee.Id);
|
||||||
@ -2023,7 +2080,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
// Validate the existence and active status of the job ticket including its status related data
|
// Validate the existence and active status of the job ticket including its status related data
|
||||||
var jobTicket = await _context.JobTickets
|
var jobTicket = await _context.JobTickets
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Include(jt => jt.Status)
|
|
||||||
.FirstOrDefaultAsync(jt => jt.Id == jobTicketId && jt.TenantId == tenantId && jt.IsActive);
|
.FirstOrDefaultAsync(jt => jt.Id == jobTicketId && jt.TenantId == tenantId && jt.IsActive);
|
||||||
|
|
||||||
if (jobTicket == null)
|
if (jobTicket == null)
|
||||||
@ -2039,8 +2095,8 @@ namespace Marco.Pms.Services.Service
|
|||||||
// Fetch attendance records within the date range for the specified job ticket and tenant
|
// Fetch attendance records within the date range for the specified job ticket and tenant
|
||||||
var attendances = await _context.JobAttendance
|
var attendances = await _context.JobAttendance
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Include(ja => ja.JobTicket).ThenInclude(jt => jt.Status)
|
.Include(ja => ja.JobTicket).ThenInclude(jt => jt!.Status)
|
||||||
.Include(ja => ja.Employee).ThenInclude(e => e.JobRole)
|
.Include(ja => ja.Employee).ThenInclude(e => e!.JobRole)
|
||||||
.Where(ja => ja.JobTcketId == jobTicketId
|
.Where(ja => ja.JobTcketId == jobTicketId
|
||||||
&& ja.TaggedInTime.Date >= fromDate
|
&& ja.TaggedInTime.Date >= fromDate
|
||||||
&& ja.TaggedInTime.Date <= toDate
|
&& ja.TaggedInTime.Date <= toDate
|
||||||
@ -2054,7 +2110,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
// Determine if current attendance record is not the latest, if so clear NextAction
|
// Determine if current attendance record is not the latest, if so clear NextAction
|
||||||
var isNotLast = attendances.Any(attendance => attendance.TaggedInTime.Date > ja.TaggedInTime.Date);
|
var isNotLast = attendances.Any(attendance => attendance.TaggedInTime.Date > ja.TaggedInTime.Date);
|
||||||
if (isNotLast || (ja.TaggedOutTime.HasValue && ja.TaggedInTime.Date != DateTime.UtcNow.Date))
|
if (isNotLast || (ja.TaggedOutTime.HasValue && ja.TaggedInTime.Date != DateTime.UtcNow.Date) || ja.EmployeeId != loggedInEmployee.Id)
|
||||||
{
|
{
|
||||||
result.NextAction = null;
|
result.NextAction = null;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user