marco.pms.api/Marco.Pms.Services/Controllers/AttendanceController.cs

366 lines
15 KiB
C#

using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.AttendanceModule;
using Marco.Pms.Model.Dtos.Attendance;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Attendance;
using MarcoBMS.Services.Helpers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
using System.Globalization;
namespace MarcoBMS.Services.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class AttendanceController : ControllerBase
{
private readonly ApplicationDbContext _context;
private readonly EmployeeHelper _employeeHelper;
private readonly ProjectsHelper _projectsHelper;
private readonly UserHelper _userHelper;
public AttendanceController(
ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper)
{
_context = context;
_employeeHelper = employeeHelper;
_projectsHelper = projectsHelper;
_userHelper = userHelper;
}
private int GetTenantId()
{
return _userHelper.GetTenantId();
//var tenant = User.FindFirst("TenantId")?.Value;
//return (tenant != null ? Convert.ToInt32(tenant) : 1);
}
private int GetUserId()
{
var tenant = User.FindFirst("Id")?.Value;
return (tenant != null ? Convert.ToInt32(tenant) : 1);
}
[HttpGet("log/attendance/{attendanceid}")]
public async Task<IActionResult> GetAttendanceLogById(int attendanceid)
{
int TenantId = GetUserId();
List<AttendanceLog> lstAttendance = await _context.AttendanceLogs.Where(c => c.AttendanceId == attendanceid && c.TenantId == TenantId).ToListAsync();
return Ok(ApiResponse<object>.SuccessResponse(lstAttendance, String.Format("{0} Attendance records fetched successfully", lstAttendance.Count), 200));
}
[HttpGet("log/employee/{employeeid}")]
public async Task<IActionResult> GetAttendanceLogByEmployeeId(int employeeid, [FromQuery] string? date = null)
{
int TenantId = GetUserId();
DateOnly forDate = new DateOnly();
if (date != null && DateOnly.TryParse(date, out forDate) == false)
{
return StatusCode(400, ApiResponse<object>.SuccessResponse(date, "Invalid Date", 400));// new { error = ex.Message });
}
List<AttendanceLog> lstAttendance = await _context.AttendanceLogs.Where(c => c.EmployeeID == employeeid && c.TenantId == TenantId).ToListAsync();
return Ok(ApiResponse<object>.SuccessResponse(lstAttendance, System.String.Format("{0} Attendance records fetched successfully", lstAttendance.Count), 200));
}
/// <summary>
///
/// </summary>
/// <param name="projectId">ProjectID</param>
/// <param name="date">YYYY-MM-dd</param>
/// <returns></returns>
[HttpGet("project/log")]
public async Task<IActionResult> EmployeeAttendanceByDateRange([FromQuery] int projectId, [FromQuery] string? dateFrom = null, [FromQuery] string? dateTo = null)
{
int TenantId = GetUserId();
DateTime fromDate = new DateTime();
DateTime toDate = new DateTime();
if (dateFrom != null && DateTime.TryParse(dateFrom, out fromDate) == false)
{
return StatusCode(400, ApiResponse<object>.SuccessResponse(dateFrom, "Invalid Date", 400));// new { error = ex.Message });
}
if (dateTo != null && DateTime.TryParse(dateTo, out toDate) == false)
{
return StatusCode(400, ApiResponse<object>.SuccessResponse(dateTo, "Invalid Date", 400));// new { error = ex.Message });
}
if (projectId <= 0)
{
return BadRequest("Project ID is required and must be greater than zero.");
}
var result = new List<EmployeeAttendanceVM>();
Attendance attendance = null;
if (dateFrom == null) fromDate = DateTime.UtcNow.Date;
if (dateTo == null && dateFrom != null) toDate = fromDate.AddDays(-1);
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date <= fromDate && c.AttendanceDate.Date >= toDate && c.TenantId == TenantId).ToListAsync();
List<ProjectAllocation> projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, true);
foreach (ProjectAllocation teamMember in projectteam)
{
var result1 = new EmployeeAttendanceVM()
{
EmployeeAvatar = null,
EmployeeId = teamMember.EmployeeId,
FirstName = teamMember.Employee.FirstName,
LastName = teamMember.Employee.LastName
};
attendance = lstAttendance.Find(x => x.EmployeeID == teamMember.EmployeeId);
if (attendance != null)
{
result1.Id = attendance.Id;
result1.CheckInTime = attendance.InTime;
result1.CheckOutTime = attendance.OutTime;
result1.Activity = attendance.Activity;
}
result.Add(result1);
}
return Ok(ApiResponse<object>.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200));
}
/// <summary>
///
/// </summary>
/// <param name="projectId">ProjectID</param>
/// <param name="date">YYYY-MM-dd</param>
/// <returns></returns>
[HttpGet("project/team")]
public async Task<IActionResult> EmployeeAttendanceByProject([FromQuery] int projectId, [FromQuery] string? date = null)
{
int TenantId = GetUserId();
DateTime forDate = new DateTime();
if (date != null && DateTime.TryParse(date, out forDate) == false)
{
return StatusCode(400, ApiResponse<object>.SuccessResponse(date, "Invalid Date", 400));// new { error = ex.Message });
}
if (projectId <= 0)
{
return BadRequest("Project ID is required and must be greater than zero.");
}
var result = new List<EmployeeAttendanceVM>();
Attendance attendance = null;
if (date == null) forDate = DateTime.UtcNow.Date;
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date == forDate && c.TenantId == TenantId).ToListAsync();
List<ProjectAllocation> projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, true);
foreach (ProjectAllocation teamMember in projectteam)
{
var result1 = new EmployeeAttendanceVM()
{
EmployeeAvatar = null,
EmployeeId = teamMember.EmployeeId,
FirstName = teamMember.Employee.FirstName,
LastName = teamMember.Employee.LastName
};
attendance = lstAttendance.Find(x => x.EmployeeID == teamMember.EmployeeId);
if (attendance != null)
{
result1.Id = attendance.Id;
result1.CheckInTime = attendance.InTime;
result1.CheckOutTime = attendance.OutTime;
result1.Activity = attendance.Activity;
}
result.Add(result1);
}
result.Sort(delegate (EmployeeAttendanceVM x, EmployeeAttendanceVM y) {
return x.FirstName.CompareTo(y.FirstName);
});
return Ok(ApiResponse<object>.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200));
}
[HttpPost]
[Route("record")]
public async Task<IActionResult> RecordAttendance([FromBody] RecordAttendanceDot recordAttendanceDot)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
int TenantId = GetTenantId();
using var transaction = await _context.Database.BeginTransactionAsync();
try
{
Attendance attendance = await _context.Attendes.FirstOrDefaultAsync(a => a.EmployeeID == recordAttendanceDot.EmployeeID &&
a.AttendanceDate.Date == recordAttendanceDot.Date.Date && a.TenantId == TenantId);
DateTime finalDateTime = GetDateFromTimeStamp(recordAttendanceDot, recordAttendanceDot.MarkTime);
if (attendance != null)
{
attendance.Comment = recordAttendanceDot.Comment;
if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.CHECK_IN)
{
attendance.OutTime = null;
attendance.Activity = ATTENDANCE_MARK_TYPE.CHECK_OUT;
}
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.CHECK_OUT)
{
attendance.IsApproved = true;
attendance.Activity = ATTENDANCE_MARK_TYPE.REGULARIZE;
//string timeString = "10:30 PM"; // Format: "hh:mm tt"
//DateTime finalDateTime = GetDateFromTimeStamp(recordAttendanceDot, recordAttendanceDot.MarkTime);
attendance.OutTime = finalDateTime;
}
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE)
{
//DateTime finalDateTime = GetDateFromTimeStamp(recordAttendanceDot, recordAttendanceDot.MarkTime);
attendance.OutTime = finalDateTime;
attendance.Activity = ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE;
// do nothing
}
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.REGULARIZE)
{
attendance.IsApproved = true;
attendance.Activity = ATTENDANCE_MARK_TYPE.REGULARIZE;
// do nothing
}
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.REGULARIZE_REJECT)
{
attendance.IsApproved = false;
attendance.Activity = ATTENDANCE_MARK_TYPE.REGULARIZE_REJECT;
// do nothing
}
attendance.Date = DateTime.UtcNow;
// update code
_context.Attendes.Update(attendance);
}
else
{
attendance = new Attendance();
attendance.TenantId = TenantId;
attendance.AttendanceDate = recordAttendanceDot.Date;
// attendance.Activity = recordAttendanceDot.Action;
attendance.Comment = recordAttendanceDot.Comment;
attendance.EmployeeID = recordAttendanceDot.EmployeeID;
attendance.ProjectID = recordAttendanceDot.ProjectID;
attendance.Date = DateTime.UtcNow;
//DateTime finalDateTime = GetDateFromTimeStamp(recordAttendanceDot, recordAttendanceDot.MarkTime);
attendance.InTime = finalDateTime;
attendance.OutTime = null;
attendance.Activity = ATTENDANCE_MARK_TYPE.CHECK_OUT;
_context.Attendes.Add(attendance);
}
await _context.SaveChangesAsync();
// Step 3: Always insert a new log entry
var attendanceLog = new AttendanceLog
{
AttendanceId = attendance.Id, // Use existing or new AttendanceId
Activity = attendance.Activity,
ActivityTime = finalDateTime,
//ActivityTime = recordAttendanceDot.Date,
Comment = recordAttendanceDot.Comment,
EmployeeID = recordAttendanceDot.EmployeeID,
Latitude = recordAttendanceDot.Latitude,
Longitude = recordAttendanceDot.Longitude,
TenantId = TenantId,
UpdatedBy = GetUserId(),
UpdatedOn = recordAttendanceDot.Date
//UpdatedOn = DateTime.UtcNow
};
//if (recordAttendanceDot.Image != null && recordAttendanceDot.Image.Count > 0)
//{
// attendanceLog.Photo = recordAttendanceDot.Image[0].Base64Data;
//}
_context.AttendanceLogs.Add(attendanceLog);
await _context.SaveChangesAsync();
await transaction.CommitAsync(); // Commit transaction
Employee employee = await _employeeHelper.GetEmployeeByID(recordAttendanceDot.EmployeeID);
EmployeeAttendanceVM vm = new EmployeeAttendanceVM()
{
CheckInTime = attendance.InTime,
CheckOutTime = attendance.OutTime,
EmployeeAvatar = null,
EmployeeId = recordAttendanceDot.EmployeeID,
FirstName = employee.FirstName,
LastName = employee.LastName,
Id = attendance.Id,
Activity = attendance.Activity
};
return Ok(ApiResponse<object>.SuccessResponse(vm, "Attendance marked successfully.", 200));
}
catch (Exception ex)
{
await transaction.RollbackAsync(); // Rollback on failure
return StatusCode(500, ApiResponse<object>.SuccessResponse(new object(), ex.Message, 500));// new { error = ex.Message });
}
return Ok(ApiResponse<object>.SuccessResponse("success", "Roles modified.", 200));
}
private static DateTime GetDateFromTimeStamp(RecordAttendanceDot recordAttendanceDot, string timeString)
{
DateTime date = recordAttendanceDot.Date;
// Parse time string to TimeSpan
DateTime parsedTime = DateTime.ParseExact(timeString, "hh:mm tt", CultureInfo.InvariantCulture);
// Combine date with time
DateTime finalDateTime = new DateTime(date.Year, date.Month, date.Day, parsedTime.Hour, parsedTime.Minute, 0);
return finalDateTime;
}
}
}