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 Guid Id { get; set; }
|
||||
public Guid JobTcketId { 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 BasicEmployeeVM? Employee { get; set; }
|
||||
public DateTime TaggedInTime { get; set; }
|
||||
public DateTime? TaggedInTime { 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 ===================================================================
|
||||
|
||||
[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)
|
||||
{
|
||||
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
@ -37,6 +37,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
||||
#endregion
|
||||
|
||||
#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>> ManageJobTaggingAsync(JobAttendanceDto model, Employee loggedInEmployee, Guid tenantId);
|
||||
#endregion
|
||||
|
||||
@ -2014,6 +2014,63 @@ namespace Marco.Pms.Services.Service
|
||||
#endregion
|
||||
|
||||
#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)
|
||||
{
|
||||
_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
|
||||
var jobTicket = await _context.JobTickets
|
||||
.AsNoTracking()
|
||||
.Include(jt => jt.Status)
|
||||
.FirstOrDefaultAsync(jt => jt.Id == jobTicketId && jt.TenantId == tenantId && jt.IsActive);
|
||||
|
||||
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
|
||||
var attendances = await _context.JobAttendance
|
||||
.AsNoTracking()
|
||||
.Include(ja => ja.JobTicket).ThenInclude(jt => jt.Status)
|
||||
.Include(ja => ja.Employee).ThenInclude(e => e.JobRole)
|
||||
.Include(ja => ja.JobTicket).ThenInclude(jt => jt!.Status)
|
||||
.Include(ja => ja.Employee).ThenInclude(e => e!.JobRole)
|
||||
.Where(ja => ja.JobTcketId == jobTicketId
|
||||
&& ja.TaggedInTime.Date >= fromDate
|
||||
&& 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
|
||||
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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user