Resovled the mearge confilects
This commit is contained in:
commit
2c841b3bd0
11
Marco.Pms.Model/ViewModels/Projects/ProjectHisteryVM.cs
Normal file
11
Marco.Pms.Model/ViewModels/Projects/ProjectHisteryVM.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace Marco.Pms.Model.ViewModels.Projects
|
||||||
|
{
|
||||||
|
public class ProjectHisteryVM
|
||||||
|
{
|
||||||
|
public string? ProjectName { get; set; }
|
||||||
|
public string? ProjectShortName { get; set; }
|
||||||
|
public DateTime AssignedDate { get; set; }
|
||||||
|
public DateTime? RemovedDate { get; set; }
|
||||||
|
public string? Designation { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -195,24 +195,87 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return Ok(ApiResponse<object>.SuccessResponse(response, $"{response.Count} records of employees fetched successfully", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(response, $"{response.Count} records of employees fetched successfully", 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
/// <summary>
|
||||||
[Route("search/{name}/{projectid?}")]
|
/// Retrieves a paginated list of employees assigned to a specified project (if provided),
|
||||||
public async Task<IActionResult> SearchEmployee(string name, Guid? projectid)
|
/// with optional search functionality.
|
||||||
{
|
/// Ensures that the logged-in user has necessary permissions before accessing project employees.
|
||||||
if (!ModelState.IsValid)
|
/// </summary>
|
||||||
{
|
/// <param name="projectId">Optional project identifier to filter employees by project.</param>
|
||||||
var errors = ModelState.Values
|
/// <param name="searchString">Optional search string to filter employees by name.</param>
|
||||||
.SelectMany(v => v.Errors)
|
/// <param name="pageNumber">Page number for pagination (default = 1).</param>
|
||||||
.Select(e => e.ErrorMessage)
|
/// <returns>Paginated list of employees in BasicEmployeeVM format wrapped in ApiResponse.</returns>
|
||||||
.ToList();
|
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
|
||||||
|
|
||||||
}
|
[HttpGet("search")]
|
||||||
var result = await _employeeHelper.SearchEmployeeByProjectId(GetTenantId(), name.ToLower(), projectid);
|
public async Task<IActionResult> GetEmployeesByProjectBasic(Guid? projectId, [FromQuery] string? searchString,
|
||||||
|
[FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 10)
|
||||||
|
{
|
||||||
|
// Log API entry with context
|
||||||
|
_logger.LogInfo("Fetching employees. ProjectId: {ProjectId}, SearchString: {SearchString}, PageNumber: {PageNumber}",
|
||||||
|
projectId ?? Guid.Empty, searchString ?? "", pageNumber);
|
||||||
|
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(result, "Filter applied.", 200));
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
_logger.LogDebug("Logged-in EmployeeId: {EmployeeId}", loggedInEmployee.Id);
|
||||||
|
|
||||||
|
// Initialize query scoped by tenant
|
||||||
|
var employeeQuery = _context.Employees.Where(e => e.TenantId == tenantId);
|
||||||
|
|
||||||
|
// Filter by project if projectId is supplied
|
||||||
|
if (projectId.HasValue && projectId.Value != Guid.Empty)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Project filter applied. Checking permission for EmployeeId: {EmployeeId} on ProjectId: {ProjectId}",
|
||||||
|
loggedInEmployee.Id, projectId);
|
||||||
|
|
||||||
|
// Validate project access permission
|
||||||
|
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId.Value);
|
||||||
|
if (!hasProjectPermission)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} does not have permission for ProjectId: {ProjectId}",
|
||||||
|
loggedInEmployee.Id, projectId);
|
||||||
|
|
||||||
|
return StatusCode(403, ApiResponse<object>.ErrorResponse(
|
||||||
|
"Access denied",
|
||||||
|
"User does not have access to view employees for this project",
|
||||||
|
403));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Employees allocated to the project
|
||||||
|
var employeeIds = await _context.ProjectAllocations
|
||||||
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.TenantId == tenantId)
|
||||||
|
.Select(pa => pa.EmployeeId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_logger.LogDebug("Project employees retrieved. Total linked employees found: {Count}", employeeIds.Count);
|
||||||
|
|
||||||
|
// Apply project allocation filter
|
||||||
|
employeeQuery = employeeQuery.Where(e => employeeIds.Contains(e.Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply search filter if provided
|
||||||
|
if (!string.IsNullOrWhiteSpace(searchString))
|
||||||
|
{
|
||||||
|
var searchStringLower = searchString.ToLower();
|
||||||
|
_logger.LogDebug("Search filter applied. Search term: {SearchTerm}", searchStringLower);
|
||||||
|
|
||||||
|
employeeQuery = employeeQuery.Where(e =>
|
||||||
|
(e.FirstName + " " + e.LastName).ToLower().Contains(searchStringLower));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pagination and Projection (executed in DB)
|
||||||
|
var employees = await employeeQuery
|
||||||
|
.Skip((pageNumber - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.Select(e => _mapper.Map<BasicEmployeeVM>(e))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_logger.LogInfo("Employees fetched successfully. Records returned: {Count}", employees.Count);
|
||||||
|
|
||||||
|
return Ok(ApiResponse<object>.SuccessResponse(
|
||||||
|
employees,
|
||||||
|
$"{employees.Count} employee records fetched successfully",
|
||||||
|
200));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("profile/get/{employeeId}")]
|
[Route("profile/get/{employeeId}")]
|
||||||
public async Task<IActionResult> GetEmployeeProfileById(Guid employeeId)
|
public async Task<IActionResult> GetEmployeeProfileById(Guid employeeId)
|
||||||
@ -451,20 +514,21 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
public async Task<IActionResult> SuspendEmployee(Guid id)
|
public async Task<IActionResult> SuspendEmployee(Guid id, [FromQuery] bool active = false)
|
||||||
{
|
{
|
||||||
Guid tenantId = _userHelper.GetTenantId();
|
Guid tenantId = _userHelper.GetTenantId();
|
||||||
var LoggedEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var LoggedEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
Employee? employee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == id && e.IsActive && e.TenantId == tenantId);
|
Employee? employee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == id && e.TenantId == tenantId);
|
||||||
if (employee != null)
|
if (employee == null)
|
||||||
{
|
{
|
||||||
|
_logger.LogWarning("Employee with ID {EmploueeId} not found in database", id);
|
||||||
|
return NotFound(ApiResponse<object>.ErrorResponse("Employee Not found successfully", "Employee Not found successfully", 404));
|
||||||
|
}
|
||||||
if (employee.IsSystem)
|
if (employee.IsSystem)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Employee with ID {LoggedEmployeeId} tries to suspend system-defined employee with ID {EmployeeId}", LoggedEmployee.Id, employee.Id);
|
_logger.LogWarning("Employee with ID {LoggedEmployeeId} tries to suspend system-defined employee with ID {EmployeeId}", LoggedEmployee.Id, employee.Id);
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("System-defined employees cannot be suspended.", "System-defined employees cannot be suspended.", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("System-defined employees cannot be suspended.", "System-defined employees cannot be suspended.", 400));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
var assignedToTasks = await _context.TaskMembers.Where(t => t.EmployeeId == employee.Id).ToListAsync();
|
var assignedToTasks = await _context.TaskMembers.Where(t => t.EmployeeId == employee.Id).ToListAsync();
|
||||||
if (assignedToTasks.Count != 0)
|
if (assignedToTasks.Count != 0)
|
||||||
{
|
{
|
||||||
@ -487,6 +551,20 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_logger.LogWarning("Employee with ID {EmployeeId} have any pending check-out or regularization requests", employee.Id);
|
_logger.LogWarning("Employee with ID {EmployeeId} have any pending check-out or regularization requests", employee.Id);
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Employee have any pending check-out or regularization requests", "Employee have any pending check-out or regularization requests", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Employee have any pending check-out or regularization requests", "Employee have any pending check-out or regularization requests", 400));
|
||||||
}
|
}
|
||||||
|
if (active)
|
||||||
|
{
|
||||||
|
employee.IsActive = true;
|
||||||
|
var user = await _context.ApplicationUsers.FirstOrDefaultAsync(u => u.Id == employee.ApplicationUserId);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
user.IsActive = true;
|
||||||
|
_logger.LogInfo("The application user associated with employee ID {EmployeeId} has been actived.", employee.Id);
|
||||||
|
|
||||||
|
}
|
||||||
|
_logger.LogInfo("Employee with ID {EmployeId} Actived successfully", employee.Id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
employee.IsActive = false;
|
employee.IsActive = false;
|
||||||
var projectAllocations = await _context.ProjectAllocations.Where(a => a.EmployeeId == employee.Id).ToListAsync();
|
var projectAllocations = await _context.ProjectAllocations.Where(a => a.EmployeeId == employee.Id).ToListAsync();
|
||||||
if (projectAllocations.Count != 0)
|
if (projectAllocations.Count != 0)
|
||||||
@ -520,17 +598,20 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_context.EmployeeRoleMappings.RemoveRange(roleMapping);
|
_context.EmployeeRoleMappings.RemoveRange(roleMapping);
|
||||||
_logger.LogInfo("Application role mapping associated with employee ID {EmployeeId} has been removed.", employee.Id);
|
_logger.LogInfo("Application role mapping associated with employee ID {EmployeeId} has been removed.", employee.Id);
|
||||||
}
|
}
|
||||||
await _context.SaveChangesAsync();
|
|
||||||
_logger.LogInfo("Employee with ID {EmployeId} Deleted successfully", employee.Id);
|
_logger.LogInfo("Employee with ID {EmployeId} Deleted successfully", employee.Id);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch (DbUpdateException ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Exception Occured While activting/deactivting employee {EmployeeId}", employee.Id);
|
||||||
|
return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal Error Occured", "Error occured while saving the entity", 500));
|
||||||
|
}
|
||||||
var notification = new { LoggedInUserId = LoggedEmployee.Id, Keyword = "Employee", EmployeeId = employee.Id };
|
var notification = new { LoggedInUserId = LoggedEmployee.Id, Keyword = "Employee", EmployeeId = employee.Id };
|
||||||
|
|
||||||
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogWarning("Employee with ID {EmploueeId} not found in database", id);
|
|
||||||
}
|
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(new { }, "Employee Suspended successfully", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(new { }, "Employee Suspended successfully", 200));
|
||||||
}
|
}
|
||||||
private static Employee GetNewEmployeeModel(CreateUserDto model, Guid TenantId, string ApplicationUserId)
|
private static Employee GetNewEmployeeModel(CreateUserDto model, Guid TenantId, string ApplicationUserId)
|
||||||
|
@ -276,6 +276,23 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("allocation-histery/{employeeId}")]
|
||||||
|
public async Task<IActionResult> GetProjectByEmployeeBasic([FromRoute] Guid employeeId)
|
||||||
|
{
|
||||||
|
// --- Step 1: Input Validation ---
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
||||||
|
_logger.LogWarning("Get project list by employee Id called with invalid model state \n Errors: {Errors}", string.Join(", ", errors));
|
||||||
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid request data provided.", errors, 400));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Step 2: Prepare data without I/O ---
|
||||||
|
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
var response = await _projectServices.GetProjectByEmployeeBasicAsync(employeeId, tenantId, loggedInEmployee);
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("assign-projects/{employeeId}")]
|
[HttpPost("assign-projects/{employeeId}")]
|
||||||
public async Task<IActionResult> AssigneProjectsToEmployee([FromBody] List<ProjectsAllocationDto> projectAllocationDtos, [FromRoute] Guid employeeId)
|
public async Task<IActionResult> AssigneProjectsToEmployee([FromBody] List<ProjectsAllocationDto> projectAllocationDtos, [FromRoute] Guid employeeId)
|
||||||
{
|
{
|
||||||
@ -338,6 +355,25 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
var response = await _projectServices.GetWorkItemsAsync(workAreaId, tenantId, loggedInEmployee);
|
var response = await _projectServices.GetWorkItemsAsync(workAreaId, tenantId, loggedInEmployee);
|
||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
}
|
}
|
||||||
|
[HttpGet("tasks-employee/{employeeId}")]
|
||||||
|
public async Task<IActionResult> GetTasksByEmployee(Guid employeeId, [FromQuery] DateTime? fromDate, DateTime? toDate)
|
||||||
|
{
|
||||||
|
// --- Step 1: Input Validation ---
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
||||||
|
_logger.LogWarning("Get Work Items by employeeId called with invalid model state \n Errors: {Errors}", string.Join(", ", errors));
|
||||||
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid request data provided.", errors, 400));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!toDate.HasValue) toDate = DateTime.UtcNow;
|
||||||
|
if (!fromDate.HasValue) fromDate = toDate.Value.AddDays(-7);
|
||||||
|
|
||||||
|
// --- Step 2: Prepare data without I/O ---
|
||||||
|
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
var response = await _projectServices.GetTasksByEmployeeAsync(employeeId, fromDate.Value, toDate.Value, tenantId, loggedInEmployee);
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ namespace MarcoBMS.Services.Helpers
|
|||||||
public async Task<Employee> GetEmployeeByID(Guid EmployeeID)
|
public async Task<Employee> GetEmployeeByID(Guid EmployeeID)
|
||||||
{
|
{
|
||||||
|
|
||||||
return await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.Id == EmployeeID && e.IsActive == true) ?? new Employee { };
|
return await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.Id == EmployeeID) ?? new Employee { };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Employee> GetEmployeeByApplicationUserID(string ApplicationUserID)
|
public async Task<Employee> GetEmployeeByApplicationUserID(string ApplicationUserID)
|
||||||
|
@ -892,6 +892,73 @@ namespace Marco.Pms.Services.Service
|
|||||||
return ApiResponse<List<ProjectAllocationVM>>.SuccessResponse(resultVm, "Assignments managed successfully.", 200);
|
return ApiResponse<List<ProjectAllocationVM>>.SuccessResponse(resultVm, "Assignments managed successfully.", 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ApiResponse<object>> GetProjectByEmployeeBasicAsync(Guid employeeId, Guid tenantId, Employee loggedInEmployee)
|
||||||
|
{
|
||||||
|
// Log the start of the method execution with key input parameters
|
||||||
|
_logger.LogInfo("Fetching projects for EmployeeId: {EmployeeId}, TenantId: {TenantId} by User: {UserId}",
|
||||||
|
employeeId, tenantId, loggedInEmployee.Id);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Retrieve project allocations linked to the specified employee and tenant
|
||||||
|
var projectAllocation = await _context.ProjectAllocations
|
||||||
|
.AsNoTracking() // Optimization: no tracking since entities are not updated
|
||||||
|
.Include(pa => pa.Project) // Include related Project data
|
||||||
|
.Include(pa => pa.Employee).ThenInclude(e => e!.JobRole) // Include related Employee and their JobRole
|
||||||
|
.Where(pa => pa.EmployeeId == employeeId
|
||||||
|
&& pa.TenantId == tenantId
|
||||||
|
&& pa.Project != null
|
||||||
|
&& pa.Employee != null)
|
||||||
|
.Select(pa => new
|
||||||
|
{
|
||||||
|
ProjectName = pa.Project!.Name,
|
||||||
|
ProjectShortName = pa.Project.ShortName,
|
||||||
|
AssignedDate = pa.AllocationDate,
|
||||||
|
RemovedDate = pa.ReAllocationDate,
|
||||||
|
Designation = pa.Employee!.JobRole!.Name,
|
||||||
|
DesignationId = pa.JobRoleId
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var designationIds = projectAllocation.Select(pa => pa.DesignationId).ToList();
|
||||||
|
|
||||||
|
var designations = await _context.JobRoles.Where(jr => designationIds.Contains(jr.Id)).ToListAsync();
|
||||||
|
|
||||||
|
var response = projectAllocation.Select(pa =>
|
||||||
|
{
|
||||||
|
var designation = designations.FirstOrDefault(jr => jr.Id == pa.DesignationId);
|
||||||
|
return new ProjectHisteryVM
|
||||||
|
{
|
||||||
|
ProjectName = pa.ProjectName,
|
||||||
|
ProjectShortName = pa.ProjectShortName,
|
||||||
|
AssignedDate = pa.AssignedDate,
|
||||||
|
RemovedDate = pa.RemovedDate,
|
||||||
|
Designation = designation?.Name
|
||||||
|
};
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
// Log successful retrieval including count of records
|
||||||
|
_logger.LogInfo("Successfully fetched {Count} projects for EmployeeId: {EmployeeId}",
|
||||||
|
projectAllocation.Count, employeeId);
|
||||||
|
|
||||||
|
return ApiResponse<object>.SuccessResponse(
|
||||||
|
response,
|
||||||
|
$"{response.Count} project assignments fetched for employee.",
|
||||||
|
200);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Log the exception with stack trace for debugging
|
||||||
|
_logger.LogError(ex, "Error occurred while fetching projects for EmployeeId: {EmployeeId}, TenantId: {TenantId}",
|
||||||
|
employeeId, tenantId);
|
||||||
|
|
||||||
|
return ApiResponse<object>.ErrorResponse(
|
||||||
|
"An error occurred while fetching project assignments.",
|
||||||
|
500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Project InfraStructure Get APIs ===================================================================
|
#region =================================================================== Project InfraStructure Get APIs ===================================================================
|
||||||
@ -1022,6 +1089,83 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves tasks assigned to a specific employee within a date range for a tenant.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="employeeId">The ID of the employee to filter tasks.</param>
|
||||||
|
/// <param name="fromDate">The start date to filter task assignments.</param>
|
||||||
|
/// <param name="toDate">The end date to filter task assignments.</param>
|
||||||
|
/// <param name="tenantId">The tenant ID to filter tasks.</param>
|
||||||
|
/// <param name="loggedInEmployee">The employee requesting the data (for authorization/logging).</param>
|
||||||
|
/// <returns>An ApiResponse containing the task details.</returns>
|
||||||
|
public async Task<ApiResponse<object>> GetTasksByEmployeeAsync(Guid employeeId, DateTime fromDate, DateTime toDate, Guid tenantId, Employee loggedInEmployee)
|
||||||
|
{
|
||||||
|
_logger.LogInfo("Fetching tasks for EmployeeId: {EmployeeId} from {FromDate} to {ToDate} for TenantId: {TenantId}",
|
||||||
|
employeeId, fromDate, toDate, tenantId);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Query TaskMembers with related necessary fields in one projection to minimize DB calls and data size
|
||||||
|
var taskData = await _context.TaskMembers
|
||||||
|
.Where(tm => tm.EmployeeId == employeeId &&
|
||||||
|
tm.TenantId == tenantId &&
|
||||||
|
tm.TaskAllocation != null &&
|
||||||
|
tm.TaskAllocation.AssignmentDate.Date >= fromDate.Date &&
|
||||||
|
tm.TaskAllocation.AssignmentDate.Date <= toDate.Date)
|
||||||
|
.Select(tm => new
|
||||||
|
{
|
||||||
|
AssignmentDate = tm.TaskAllocation!.AssignmentDate,
|
||||||
|
PlannedTask = tm.TaskAllocation.PlannedTask,
|
||||||
|
CompletedTask = tm.TaskAllocation.CompletedTask,
|
||||||
|
ProjectId = tm.TaskAllocation.WorkItem!.WorkArea!.Floor!.Building!.ProjectId,
|
||||||
|
BuildingName = tm.TaskAllocation.WorkItem.WorkArea.Floor.Building!.Name,
|
||||||
|
FloorName = tm.TaskAllocation.WorkItem.WorkArea.Floor.FloorName,
|
||||||
|
AreaName = tm.TaskAllocation.WorkItem.WorkArea.AreaName,
|
||||||
|
ActivityName = tm.TaskAllocation.WorkItem.ActivityMaster!.ActivityName,
|
||||||
|
ActivityUnit = tm.TaskAllocation.WorkItem.ActivityMaster.UnitOfMeasurement
|
||||||
|
})
|
||||||
|
.OrderByDescending(t => t.AssignmentDate)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_logger.LogInfo("Retrieved {TaskCount} tasks for EmployeeId: {EmployeeId}", taskData.Count, employeeId);
|
||||||
|
|
||||||
|
// Extract distinct project IDs to fetch project details efficiently
|
||||||
|
var distinctProjectIds = taskData.Select(t => t.ProjectId).Distinct().ToList();
|
||||||
|
|
||||||
|
var projects = await _context.Projects
|
||||||
|
.Where(p => distinctProjectIds.Contains(p.Id))
|
||||||
|
.Select(p => new { p.Id, p.Name })
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Prepare the response
|
||||||
|
var response = taskData.Select(t =>
|
||||||
|
{
|
||||||
|
var project = projects.FirstOrDefault(p => p.Id == t.ProjectId);
|
||||||
|
|
||||||
|
return new
|
||||||
|
{
|
||||||
|
ProjectName = project?.Name ?? "Unknown Project",
|
||||||
|
t.AssignmentDate,
|
||||||
|
t.PlannedTask,
|
||||||
|
t.CompletedTask,
|
||||||
|
Location = $"{t.BuildingName} > {t.FloorName} > {t.AreaName}",
|
||||||
|
ActivityName = t.ActivityName,
|
||||||
|
ActivityUnit = t.ActivityUnit
|
||||||
|
};
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
_logger.LogInfo("Successfully prepared task response for EmployeeId: {EmployeeId}", employeeId);
|
||||||
|
|
||||||
|
return ApiResponse<object>.SuccessResponse(response, "Task fetched successfully", 200);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error while fetching tasks for EmployeeId: {EmployeeId}", employeeId);
|
||||||
|
return ApiResponse<object>.ErrorResponse("An error occurred while fetching the tasks.", 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Project Infrastructre Manage APIs ===================================================================
|
#region =================================================================== Project Infrastructre Manage APIs ===================================================================
|
||||||
|
@ -20,8 +20,11 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
Task<ApiResponse<List<ProjectAllocationVM>>> ManageAllocationAsync(List<ProjectAllocationDot> projectAllocationDots, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<List<ProjectAllocationVM>>> ManageAllocationAsync(List<ProjectAllocationDot> projectAllocationDots, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ApiResponse<object>> GetProjectsByEmployeeAsync(Guid employeeId, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<object>> GetProjectsByEmployeeAsync(Guid employeeId, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ApiResponse<List<ProjectAllocationVM>>> AssigneProjectsToEmployeeAsync(List<ProjectsAllocationDto> projectAllocationDtos, Guid employeeId, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<List<ProjectAllocationVM>>> AssigneProjectsToEmployeeAsync(List<ProjectsAllocationDto> projectAllocationDtos, Guid employeeId, Guid tenantId, Employee loggedInEmployee);
|
||||||
|
Task<ApiResponse<object>> GetProjectByEmployeeBasicAsync(Guid employeeId, Guid tenantId, Employee loggedInEmployee);
|
||||||
|
|
||||||
Task<ApiResponse<object>> GetInfraDetailsAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<object>> GetInfraDetailsAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ApiResponse<object>> GetWorkItemsAsync(Guid workAreaId, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<object>> GetWorkItemsAsync(Guid workAreaId, Guid tenantId, Employee loggedInEmployee);
|
||||||
|
Task<ApiResponse<object>> GetTasksByEmployeeAsync(Guid employeeId, DateTime fromDate, DateTime toDate, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ServiceResponse> ManageProjectInfraAsync(List<InfraDto> infraDtos, Guid tenantId, Employee loggedInEmployee);
|
Task<ServiceResponse> ManageProjectInfraAsync(List<InfraDto> infraDtos, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ApiResponse<List<WorkItemVM>>> CreateProjectTaskAsync(List<WorkItemDto> workItemDtos, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<List<WorkItemVM>>> CreateProjectTaskAsync(List<WorkItemDto> workItemDtos, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ServiceResponse> DeleteProjectTaskAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
Task<ServiceResponse> DeleteProjectTaskAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user