219 lines
12 KiB
C#

using System.Globalization;
using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Dtos.Attendance;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Roles;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Report;
using MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MongoDB.Driver;
namespace Marco.Pms.Services.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ReportController : ControllerBase
{
private readonly ApplicationDbContext _context;
private readonly IEmailSender _emailSender;
private readonly IConfiguration _configuration;
private readonly ILoggingService _logger;
private readonly UserHelper _userHelper;
public ReportController(ApplicationDbContext context, IEmailSender emailSender, IConfiguration configuration, ILoggingService logger, UserHelper userHelper)
{
_context = context;
_emailSender = emailSender;
_configuration = configuration;
_logger = logger;
_userHelper = userHelper;
}
[HttpGet("project-statistics/{id}")]
public async Task<IActionResult> GetProjectStatistics(Guid id, [FromQuery] string? date)
{
DateTime reportDate = DateTime.UtcNow;
if (date != null && DateTime.TryParse(date, out reportDate) == false)
{
_logger.LogError("User sent Invalid from Date while featching project report");
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Date", "Invalid Date", 400));
}
if (id == Guid.Empty)
{
_logger.LogError("Provided empty project ID while fetching project report");
return BadRequest(ApiResponse<object>.ErrorResponse("Provided empty ProjectID", "Provided empty ProjectID", 400));
}
Project? project = await _context.Projects.FirstOrDefaultAsync(p => p.Id == id);
if (project == null)
{
_logger.LogWarning("User attempted to fetch project progress of project ID {ProjectId} but not found in database", id);
return NotFound(ApiResponse<object>.ErrorResponse("Project not found", "Project not found", 404));
}
ProjectStatisticReport statisticReport = new ProjectStatisticReport
{
Date = reportDate,
ProjectName = project.Name ?? "",
TimeStamp = DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture)
};
var projectAllocations = await _context.ProjectAllocations.Include(p => p.Employee).Where(p => p.ProjectId == project.Id && p.IsActive).ToListAsync();
var assignedEmployeeIds = projectAllocations.Select(p => p.EmployeeId).ToList();
var attendances = await _context.Attendes.AsNoTracking().Where(a => a.ProjectID == project.Id && a.InTime != null && a.InTime.Value.Date == reportDate.Date).ToListAsync();
var checkedInEmployeeIds = attendances.Select(p => p.EmployeeID).Distinct().ToList();
var checkedOutPendingEmployeeIds = attendances.Where(a => a.ProjectID == project.Id && a.InTime != null && a.InTime.Value.Date == reportDate.Date && a.OutTime == null).Select(p => p.EmployeeID).Distinct().ToList();
var regularizationEmployeeIds = attendances.Where(a => a.ProjectID == project.Id && a.InTime != null && a.InTime.Value.Date == reportDate.Date && a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE).Select(p => p.EmployeeID).Distinct().ToList();
var buildings = await _context.Buildings.Where(b => b.ProjectId == project.Id).ToListAsync();
var buildingIds = buildings.Select(b => b.Id).Distinct().ToList();
var floors = await _context.Floor.Where(f => buildingIds.Contains(f.BuildingId)).ToListAsync();
var floorIds = floors.Select(f => f.Id).Distinct().ToList();
var areas = await _context.WorkAreas.Where(a => floorIds.Contains(a.FloorId)).ToListAsync();
var areaIds = areas.Select(a => a.Id).Distinct().ToList();
var workItems = await _context.WorkItems.Include(i => i.ActivityMaster).Where(i => areaIds.Contains(i.WorkAreaId)).ToListAsync();
var itemIds = workItems.Select(i => i.Id).Distinct().ToList();
var tasks = await _context.TaskAllocations.Where(t => itemIds.Contains(t.WorkItemId)).ToListAsync();
var taskIds = tasks.Select(t => t.Id).Distinct().ToList();
var taskMembers = await _context.TaskMembers.Include(m => m.Employee).Where(m => taskIds.Contains(m.TaskAllocationId)).ToListAsync();
double totalPlannedWork = 0;
double totalCompletedWork = 0;
foreach (var items in workItems)
{
totalPlannedWork += items.PlannedWork;
totalCompletedWork += items.CompletedWork;
}
var todayAssigned = tasks.Where(t => t.AssignmentDate.Date == reportDate.Date).ToList();
var reportPending = tasks.Where(t => t.ReportedDate == null).ToList();
double totalPlannedTask = 0;
double totalCompletedTask = 0;
foreach (var items in todayAssigned)
{
totalPlannedTask += items.PlannedTask;
totalCompletedTask += items.CompletedTask;
}
var jobRoles = await _context.JobRoles.Where(r => r.TenantId == project.TenantId).ToListAsync();
List<TeamOnSite> teamOnSite = new List<TeamOnSite>();
foreach (var role in jobRoles)
{
int numberOfEmployees = 0;
var roleassigned = projectAllocations.Where(p => p.JobRoleId == role.Id && checkedInEmployeeIds.Contains(p.EmployeeId)).ToList();
if (roleassigned.Count > 0)
{
numberOfEmployees = roleassigned.Count;
}
TeamOnSite team = new TeamOnSite
{
RoleName = role.Name,
NumberofEmployees = numberOfEmployees,
};
teamOnSite.Add(team);
}
List<PerformedTask> performedTasks = new List<PerformedTask>();
var todaysTask = tasks.Where(t => t.AssignmentDate.Date == reportDate.Date).ToList();
foreach (var task in todaysTask)
{
WorkItem workItem = workItems.FirstOrDefault(i => i.Id == task.WorkItemId) ?? new WorkItem();
string activityName = (workItem.ActivityMaster != null ? workItem.ActivityMaster.ActivityName : "") ?? "";
WorkArea workArea = areas.FirstOrDefault(a => a.Id == workItem.WorkAreaId) ?? new WorkArea();
string areaName = workArea.AreaName ?? "";
Floor floor = floors.FirstOrDefault(f => f.Id == workArea.FloorId) ?? new Floor();
string floorName = floor.FloorName ?? "";
Building building = buildings.FirstOrDefault(b => b.Id == floor.BuildingId) ?? new Building();
string buildingName = building.Name ?? "";
string location = $"{buildingName} > {floorName} </span><br/><span style=\"color: gray; font-size: small; padding-left: 10px;\"> {floorName}-{areaName}";
double pending = workItem.PlannedWork - workItem.CompletedWork;
PerformedTask performedTask = new PerformedTask
{
Activity = activityName,
Location = location,
AssignedToday = task.PlannedTask,
Pending = pending,
CompletedToday = task.CompletedTask,
Comment = task.Description
};
var taskTeams = taskMembers.Where(m => m.TaskAllocationId == task.Id).ToList();
List<TaskTeam> Team = new List<TaskTeam>();
foreach (var team in taskTeams)
{
string firstName = (team.Employee != null ? team.Employee.FirstName : "") ?? "";
string lastName = (team.Employee != null ? team.Employee.LastName : "") ?? "";
string name = $"{firstName} {lastName}";
JobRole role = jobRoles.FirstOrDefault(r => r.Id == (team.Employee != null ? team.Employee.JobRoleId : Guid.Empty)) ?? new JobRole();
string roleName = role.Name ?? "";
TaskTeam taskTeam = new TaskTeam
{
Name = name,
RoleName = roleName,
};
Team.Add(taskTeam);
}
performedTask.Team = Team;
performedTasks.Add(performedTask);
}
List<PerformedAttendance> performedAttendances = new List<PerformedAttendance>();
foreach (var attendance in attendances)
{
ProjectAllocation projectAllocation = projectAllocations.FirstOrDefault(p => p.EmployeeId == attendance.EmployeeID) ?? new ProjectAllocation();
JobRole role = jobRoles.FirstOrDefault(r => r.Id == projectAllocation.JobRoleId) ?? new JobRole();
string firstName = (projectAllocation.Employee != null ? projectAllocation.Employee.FirstName : "") ?? "";
string lastName = (projectAllocation.Employee != null ? projectAllocation.Employee.LastName : "") ?? "";
string name = $"{firstName} {lastName}";
PerformedAttendance performedAttendance = new PerformedAttendance
{
Name = name,
RoleName = role.Name ?? "",
InTime = attendance.InTime ?? DateTime.UtcNow,
OutTime = attendance.OutTime,
Comment = attendance.Comment
};
performedAttendances.Add(performedAttendance);
}
statisticReport.TodaysAttendances = checkedInEmployeeIds.Count;
statisticReport.TotalEmployees = assignedEmployeeIds.Count;
statisticReport.RegularizationPending = regularizationEmployeeIds.Count;
statisticReport.CheckoutPending = checkedOutPendingEmployeeIds.Count;
statisticReport.TotalPlannedWork = totalPlannedWork;
statisticReport.TotalCompletedWork = totalCompletedWork;
statisticReport.TotalPlannedTask = totalPlannedTask;
statisticReport.TotalCompletedTask = totalCompletedTask;
statisticReport.CompletionStatus = totalCompletedWork / totalPlannedWork;
statisticReport.TodaysAssignTasks = todayAssigned.Count;
statisticReport.ReportPending = reportPending.Count;
statisticReport.TeamOnSite = teamOnSite.OrderByDescending(c => c.NumberofEmployees).ToList();
statisticReport.PerformedTasks = performedTasks;
statisticReport.PerformedAttendance = performedAttendances;
string emails = _configuration["MailingList:ProjectStatisticsReceivers"] ?? "";
List<string> result = emails
.Split(';', StringSplitOptions.RemoveEmptyEntries)
.Select(item => item.Trim())
.ToList();
await _emailSender.SendProjectStatisticsEmail(result, statisticReport);
return Ok(ApiResponse<object>.SuccessResponse(new { }, "Email sent successfully", 200));
}
}
}