From 885e3706680ba331649a211d4f3c43ef29401f81 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Mon, 28 Apr 2025 16:51:58 +0530 Subject: [PATCH] Implement null validation in attendance log API --- .../Controllers/AttendanceController.cs | 70 ++++++++++++++----- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/Marco.Pms.Services/Controllers/AttendanceController.cs b/Marco.Pms.Services/Controllers/AttendanceController.cs index d8d9f32..74eff5d 100644 --- a/Marco.Pms.Services/Controllers/AttendanceController.cs +++ b/Marco.Pms.Services/Controllers/AttendanceController.cs @@ -9,6 +9,7 @@ using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.AttendanceVM; using Marco.Pms.Services.Service; using MarcoBMS.Services.Helpers; +using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.CodeAnalysis; @@ -27,16 +28,18 @@ namespace MarcoBMS.Services.Controllers private readonly ProjectsHelper _projectsHelper; private readonly UserHelper _userHelper; private readonly S3UploadService _s3Service; + private readonly ILoggingService _logger; public AttendanceController( - ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper, S3UploadService s3Service) + ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper, S3UploadService s3Service, ILoggingService logger) { _context = context; _employeeHelper = employeeHelper; _projectsHelper = projectsHelper; _userHelper = userHelper; _s3Service = s3Service; + _logger = logger; } private int GetTenantId() @@ -56,10 +59,11 @@ namespace MarcoBMS.Services.Controllers List attendanceLogVMs = new List(); foreach (var attendanceLog in lstAttendance) { - string objectKey = attendanceLog.Document.S3Key; - string preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(objectKey); + string objectKey = attendanceLog.Document != null ? attendanceLog.Document.S3Key : string.Empty; + string preSignedUrl = string.IsNullOrEmpty(objectKey) ? _s3Service.GeneratePreSignedUrlAsync(objectKey) : string.Empty; attendanceLogVMs.Add(attendanceLog.ToAttendanceLogVMFromAttendanceLog(preSignedUrl, preSignedUrl)); } + _logger.LogInfo("{count} Attendance records fetched successfully", lstAttendance.Count); return Ok(ApiResponse.SuccessResponse(attendanceLogVMs, System.String.Format("{0} Attendance records fetched successfully", lstAttendance.Count), 200)); } @@ -77,6 +81,7 @@ namespace MarcoBMS.Services.Controllers } List lstAttendance = await _context.AttendanceLogs.Where(c => c.EmployeeID == employeeid && c.TenantId == TenantId).ToListAsync(); + _logger.LogInfo("{count} Attendance records fetched successfully", lstAttendance.Count); return Ok(ApiResponse.SuccessResponse(lstAttendance, System.String.Format("{0} Attendance records fetched successfully", lstAttendance.Count), 200)); @@ -98,15 +103,18 @@ namespace MarcoBMS.Services.Controllers if (dateFrom != null && DateTime.TryParse(dateFrom, out fromDate) == false) { + _logger.LogError("User sent Invalid from Date while featching attendance logs"); return BadRequest(ApiResponse.ErrorResponse("Invalid Date", "Invalid Date", 400)); } if (dateTo != null && DateTime.TryParse(dateTo, out toDate) == false) { + _logger.LogError("User sent Invalid to Date while featching attendance logs"); return BadRequest(ApiResponse.ErrorResponse("Invalid Date", "Invalid Date", 400)); } if (projectId <= 0) { + _logger.LogError("The project Id sent by user is less than or equal to zero"); return BadRequest(ApiResponse.ErrorResponse("Project ID is required and must be greater than zero.", "Project ID is required and must be greater than zero.", 400)); } @@ -136,13 +144,14 @@ namespace MarcoBMS.Services.Controllers { result1.EmployeeAvatar = null; result1.EmployeeId = teamMember.EmployeeId; - result1.FirstName = teamMember.Employee.FirstName; - result1.LastName = teamMember.Employee.LastName; + result1.FirstName = teamMember.Employee != null ? teamMember.Employee.FirstName : null; + result1.LastName = teamMember.Employee != null ? teamMember.Employee.LastName : null; result.Add(result1); } } + _logger.LogInfo("{count} Attendance records fetched successfully", result.Count); return Ok(ApiResponse.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200)); } @@ -161,11 +170,13 @@ namespace MarcoBMS.Services.Controllers if (date != null && DateTime.TryParse(date, out forDate) == false) { + _logger.LogError("User sent Invalid Date while featching attendance logs"); return BadRequest(ApiResponse.ErrorResponse("Invalid Date", "Invalid Date", 400)); } if (projectId <= 0) { + _logger.LogError("The project Id sent by user is less than or equal to zero"); return BadRequest(ApiResponse.ErrorResponse("Project ID is required and must be greater than zero.", "Project ID is required and must be greater than zero.", 400)); } @@ -184,7 +195,7 @@ namespace MarcoBMS.Services.Controllers foreach (ProjectAllocation teamMember in projectteam) { - if (teamMember.Employee.JobRole != null) + if (teamMember.Employee != null && teamMember.Employee.JobRole != null) { var result1 = new EmployeeAttendanceVM() { @@ -216,6 +227,7 @@ namespace MarcoBMS.Services.Controllers //return x.FirstName.CompareTo(y.FirstName); return string.Compare(x.FirstName, y.FirstName, StringComparison.Ordinal); }); + _logger.LogInfo("{count} Attendance records fetched successfully", result.Count); return Ok(ApiResponse.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200)); } @@ -230,7 +242,7 @@ namespace MarcoBMS.Services.Controllers List lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE && c.TenantId == TenantId).ToListAsync(); - List projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, IncludeInActive); + List projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, true); var idList = projectteam.Select(p => p.EmployeeId).ToList(); var jobRole = await _context.JobRoles.ToListAsync(); @@ -248,7 +260,7 @@ namespace MarcoBMS.Services.Controllers }; var teamMember = projectteam.Find(m => m.EmployeeId == attende.EmployeeID); - if (teamMember != null && teamMember.Employee.JobRole != null) + if (teamMember != null && teamMember.Employee != null && teamMember.Employee.JobRole != null) { result1.FirstName = teamMember.Employee.FirstName; result1.LastName = teamMember.Employee.LastName; @@ -262,7 +274,7 @@ namespace MarcoBMS.Services.Controllers { return string.Compare(x.FirstName, y.FirstName, StringComparison.Ordinal); }); - + _logger.LogInfo("{count} Attendance records fetched successfully", result.Count); return Ok(ApiResponse.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200)); } @@ -277,6 +289,7 @@ namespace MarcoBMS.Services.Controllers .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); + _logger.LogError("User sent Invalid Date while marking attendance"); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } @@ -287,10 +300,18 @@ namespace MarcoBMS.Services.Controllers { Attendance? attendance = await _context.Attendes.FirstOrDefaultAsync(a => a.Id == recordAttendanceDot.Id && a.TenantId == TenantId); ; - if (recordAttendanceDot.MarkTime == null) return BadRequest(ApiResponse.ErrorResponse("Invalid Mark Time", "Invalid Mark Time", 400)); + if (recordAttendanceDot.MarkTime == null) + { + _logger.LogError("User sent Invalid Mark Time while marking attendance"); + return BadRequest(ApiResponse.ErrorResponse("Invalid Mark Time", "Invalid Mark Time", 400)); + } DateTime finalDateTime = GetDateFromTimeStamp(recordAttendanceDot.Date, recordAttendanceDot.MarkTime); - if (recordAttendanceDot.Comment == null) return BadRequest(ApiResponse.ErrorResponse("Invalid Comment", "Invalid Comment", 400)); + if (recordAttendanceDot.Comment == null) + { + _logger.LogError("User sent Invalid comment while marking attendance"); + return BadRequest(ApiResponse.ErrorResponse("Invalid Comment", "Invalid Comment", 400)); + } if (attendance != null) { @@ -400,15 +421,17 @@ namespace MarcoBMS.Services.Controllers Activity = attendance.Activity, JobRoleName = employee.JobRole.Name }; - + _logger.LogInfo("Attendance for employee {FirstName} {LastName} has been marked", employee.FirstName ?? string.Empty, employee.LastName ?? string.Empty); return Ok(ApiResponse.SuccessResponse(vm, "Attendance marked successfully.", 200)); } + _logger.LogInfo("Attendance for employee {FirstName} {LastName} has been marked", employee.FirstName ?? string.Empty, employee.LastName ?? string.Empty); return Ok(ApiResponse.SuccessResponse(new EmployeeAttendanceVM(), "Attendance marked successfully.", 200)); } catch (Exception ex) { await transaction.RollbackAsync(); // Rollback on failure + _logger.LogError("{Error} while marking attendance", ex.Message); return BadRequest(ApiResponse.ErrorResponse(ex.Message, ex, 400)); } @@ -424,6 +447,7 @@ namespace MarcoBMS.Services.Controllers .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); + _logger.LogError("User sent Invalid Date while marking attendance"); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } @@ -434,10 +458,18 @@ namespace MarcoBMS.Services.Controllers { Attendance? attendance = await _context.Attendes.FirstOrDefaultAsync(a => a.Id == recordAttendanceDot.Id && a.TenantId == TenantId); ; - if (recordAttendanceDot.MarkTime == null) return BadRequest(ApiResponse.ErrorResponse("Invalid Mark Time", "Invalid Mark Time", 400)); + if (recordAttendanceDot.MarkTime == null) + { + _logger.LogError("User sent Invalid Mark Time while marking attendance"); + return BadRequest(ApiResponse.ErrorResponse("Invalid Mark Time", "Invalid Mark Time", 400)); + } DateTime finalDateTime = GetDateFromTimeStamp(recordAttendanceDot.Date, recordAttendanceDot.MarkTime); - if (recordAttendanceDot.Comment == null) return BadRequest(ApiResponse.ErrorResponse("Invalid Comment", "Invalid Comment", 400)); + if (recordAttendanceDot.Comment == null) + { + _logger.LogError("User sent Invalid comment while marking attendance"); + return BadRequest(ApiResponse.ErrorResponse("Invalid Comment", "Invalid Comment", 400)); + } if (attendance != null) { @@ -566,7 +598,7 @@ namespace MarcoBMS.Services.Controllers EmployeeID = recordAttendanceDot.EmployeeID, Latitude = recordAttendanceDot.Latitude, Longitude = recordAttendanceDot.Longitude, - DocumentId = document.Id, + DocumentId = document != null ? document.Id : null, TenantId = TenantId, UpdatedBy = recordAttendanceDot.EmployeeID, UpdatedOn = recordAttendanceDot.Date @@ -600,8 +632,8 @@ namespace MarcoBMS.Services.Controllers Activity = attendance.Activity, JobRoleName = employee.JobRole.Name, DocumentId = document.Id, - ThumbPreSignedUrl = preSignedUrl ?? string.Empty, - PreSignedUrl = preSignedUrl ?? string.Empty + ThumbPreSignedUrl = preSignedUrl, + PreSignedUrl = preSignedUrl }; } else @@ -623,19 +655,21 @@ namespace MarcoBMS.Services.Controllers }; } + _logger.LogInfo("Attendance for employee {FirstName} {LastName} has been marked", employee.FirstName ?? string.Empty, employee.LastName ?? string.Empty); return Ok(ApiResponse.SuccessResponse(vm, "Attendance marked successfully.", 200)); } + _logger.LogInfo("Attendance for employee {FirstName} {LastName} has been marked", employee.FirstName ?? string.Empty, employee.LastName ?? string.Empty); return Ok(ApiResponse.SuccessResponse(new EmployeeAttendanceVM(), "Attendance marked successfully.", 200)); } catch (Exception ex) { await transaction.RollbackAsync(); // Rollback on failure + _logger.LogError("{Error} while marking attendance", ex.Message); return BadRequest(ApiResponse.ErrorResponse(ex.Message, ex, 400)); } } - private static DateTime GetDateFromTimeStamp(DateTime date, string timeString) { //DateTime date = recordAttendanceDot.Date;