Added new API to get monthly attendance report

This commit is contained in:
ashutosh.nehete 2025-09-30 14:34:29 +05:30
parent 40ca680f45
commit d957c692f1

View File

@ -1,4 +1,5 @@
using Marco.Pms.DataAccess.Data; using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Dtos.Attendance;
using Marco.Pms.Model.Dtos.Mail; using Marco.Pms.Model.Dtos.Mail;
using Marco.Pms.Model.Mail; using Marco.Pms.Model.Mail;
using Marco.Pms.Model.MongoDBModels.Utility; using Marco.Pms.Model.MongoDBModels.Utility;
@ -10,7 +11,6 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using MongoDB.Driver;
using System.Data; using System.Data;
using System.Globalization; using System.Globalization;
using System.Net.Mail; using System.Net.Mail;
@ -22,27 +22,25 @@ namespace Marco.Pms.Services.Controllers
[Authorize] [Authorize]
public class ReportController : ControllerBase public class ReportController : ControllerBase
{ {
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly ApplicationDbContext _context; private readonly ApplicationDbContext _context;
private readonly IEmailSender _emailSender;
private readonly ILoggingService _logger; private readonly ILoggingService _logger;
private readonly UserHelper _userHelper; private readonly UserHelper _userHelper;
private readonly IWebHostEnvironment _env;
private readonly ReportHelper _reportHelper;
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private readonly CacheUpdateHelper _cache; public ReportController(IDbContextFactory<ApplicationDbContext> dbContextFactory,
private readonly IServiceScopeFactory _serviceScopeFactory; ApplicationDbContext context,
public ReportController(ApplicationDbContext context, IEmailSender emailSender, ILoggingService logger, UserHelper userHelper, ILoggingService logger,
IWebHostEnvironment env, ReportHelper reportHelper, IConfiguration configuration, CacheUpdateHelper cache, IServiceScopeFactory serviceScopeFactory) UserHelper userHelper,
IConfiguration configuration,
IServiceScopeFactory serviceScopeFactory)
{ {
_context = context; _dbContextFactory = dbContextFactory ?? throw new ArgumentNullException(nameof(dbContextFactory));
_emailSender = emailSender; _serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory));
_logger = logger; _context = context ?? throw new ArgumentNullException(nameof(context));
_userHelper = userHelper; _logger = logger ?? throw new ArgumentNullException(nameof(logger));
_env = env; _userHelper = userHelper ?? throw new ArgumentNullException(nameof(userHelper));
_reportHelper = reportHelper; _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
_configuration = configuration;
_cache = cache;
_serviceScopeFactory = serviceScopeFactory;
} }
/// <summary> /// <summary>
@ -435,10 +433,12 @@ namespace Marco.Pms.Services.Controllers
200)); 200));
} }
[HttpGet("report-mail")] [HttpGet("report-mail")]
public async Task<IActionResult> GetProjectStatisticsFromCache() public async Task<IActionResult> GetProjectStatisticsFromCache()
{ {
using var scope = _serviceScopeFactory.CreateScope();
var _cache = scope.ServiceProvider.GetRequiredService<CacheUpdateHelper>();
var mailList = await _cache.GetProjectReportMail(false); var mailList = await _cache.GetProjectReportMail(false);
if (mailList == null) if (mailList == null)
{ {
@ -447,5 +447,65 @@ namespace Marco.Pms.Services.Controllers
return Ok(ApiResponse<object>.SuccessResponse(mailList, "Fetched list of mail body successfully", 200)); return Ok(ApiResponse<object>.SuccessResponse(mailList, "Fetched list of mail body successfully", 200));
} }
[HttpGet("report-attendance")]
public async Task<IActionResult> GetAttendanceReportAsync()
{
Guid tenantId = _userHelper.GetTenantId();
using var scope = _serviceScopeFactory.CreateScope();
DateTime today = DateTime.Today;
DateTime firstDayOfMonth = new DateTime(today.Year, today.Month, 1);
DateTime firstDayOfNextMonth = firstDayOfMonth.AddMonths(1);
// Generate list of all dates in the month
var allDates = Enumerable.Range(0, (firstDayOfNextMonth - firstDayOfMonth).Days)
.Select(offset => firstDayOfMonth.AddDays(offset))
.ToList();
var attendances = await _context.Attendes
.Include(a => a.Employee)
.Where(a => a.AttendanceDate >= firstDayOfMonth && a.AttendanceDate < firstDayOfNextMonth && a.Employee != null && a.TenantId == tenantId)
.GroupBy(a => a.ProjectID)
.ToListAsync();
var result = attendances.Select(g =>
{
return new
{
ProjectName = _context.Projects.Where(p => p.Id == g.Key && p.TenantId == tenantId).Select(p => p.Name).FirstOrDefault(),
ProjectAttendance = g.GroupBy(a => a.Employee).Select(gp =>
{
var attendanceDate = gp.Select(a => a.AttendanceDate.Date).ToList();
return new
{
FirstName = gp.Key!.FirstName,
LastName = gp.Key.LastName,
Attendances = allDates.Select(d =>
{
var attendance = gp.FirstOrDefault(a => a.AttendanceDate.Date == d);
return new
{
AttendanceDate = d,
CheckIn = attendance?.InTime,
CheckOut = attendance?.OutTime,
Activity = attendance?.Activity,
IsApproved = attendance?.ApprovedById.HasValue,
};
}).ToList(),
CheckInCheckOutDone = gp.Where(a => a.InTime.HasValue && a.OutTime.HasValue && a.Activity == ATTENDANCE_MARK_TYPE.REGULARIZE).Count(),
CheckInDone = gp.Where(a => a.InTime.HasValue).Count(),
CheckOutPending = gp.Where(a => a.InTime.HasValue && !a.OutTime.HasValue).Count(),
RejectedRegularize = gp.Where(a => a.Activity == ATTENDANCE_MARK_TYPE.REGULARIZE_REJECT).Count(),
AbsentAttendance = allDates.Where(d => !attendanceDate.Contains(d) && d.DayOfWeek != DayOfWeek.Sunday).Count()
};
}).OrderBy(ar => ar.FirstName).ThenBy(ar => ar.LastName).ToList()
};
}).ToList();
var response = result.OrderBy(r => r.ProjectName).ToList();
return Ok(ApiResponse<object>.SuccessResponse(response, "Attendance Report fetched successfully", 200));
}
} }
} }