Optimized the Update project API
This commit is contained in:
parent
ca34b01ab0
commit
36eb7aef7f
@ -70,7 +70,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_logger.LogInfo("Basic project list requested by EmployeeId {EmployeeId}", loggedInEmployee.Id);
|
_logger.LogInfo("Basic project list requested by EmployeeId {EmployeeId}", loggedInEmployee.Id);
|
||||||
|
|
||||||
// Step 2: Get the list of project IDs the user has access to
|
// Step 2: Get the list of project IDs the user has access to
|
||||||
Guid tenantId = _userHelper.GetTenantId(); // Assuming this is still needed by the helper
|
|
||||||
List<Guid> accessibleProjectIds = await _projectsHelper.GetMyProjects(tenantId, loggedInEmployee);
|
List<Guid> accessibleProjectIds = await _projectsHelper.GetMyProjects(tenantId, loggedInEmployee);
|
||||||
|
|
||||||
if (accessibleProjectIds == null || !accessibleProjectIds.Any())
|
if (accessibleProjectIds == null || !accessibleProjectIds.Any())
|
||||||
@ -316,7 +315,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var project = await _context.Projects.Where(c => c.TenantId == _userHelper.GetTenantId() && c.Id == id).Include(c => c.ProjectStatus).SingleOrDefaultAsync(); // includeProperties: "ProjectStatus,Tenant"); //_context.Stock.FindAsync(id);
|
var project = await _context.Projects.Where(c => c.TenantId == tenantId && c.Id == id).Include(c => c.ProjectStatus).SingleOrDefaultAsync(); // includeProperties: "ProjectStatus,Tenant"); //_context.Stock.FindAsync(id);
|
||||||
|
|
||||||
if (project == null)
|
if (project == null)
|
||||||
{
|
{
|
||||||
@ -420,7 +419,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. Prepare data without I/O
|
// 2. Prepare data without I/O
|
||||||
Guid tenantId = _userHelper.GetTenantId(); // Assuming this is fast and from claims
|
|
||||||
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var loggedInUserId = loggedInEmployee.Id;
|
var loggedInUserId = loggedInEmployee.Id;
|
||||||
var project = projectDto.ToProjectFromCreateProjectDto(tenantId);
|
var project = projectDto.ToProjectFromCreateProjectDto(tenantId);
|
||||||
@ -465,7 +463,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
[Route("update/{id}")]
|
[Route("update1/{id}")]
|
||||||
public async Task<IActionResult> Update([FromRoute] Guid id, [FromBody] UpdateProjectDto updateProjectDto)
|
public async Task<IActionResult> Update([FromRoute] Guid id, [FromBody] UpdateProjectDto updateProjectDto)
|
||||||
{
|
{
|
||||||
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
@ -480,9 +478,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Guid TenantId = GetTenantId();
|
Project project = updateProjectDto.ToProjectFromUpdateProjectDto(tenantId, id);
|
||||||
|
|
||||||
Project project = updateProjectDto.ToProjectFromUpdateProjectDto(TenantId, id);
|
|
||||||
_context.Projects.Update(project);
|
_context.Projects.Update(project);
|
||||||
|
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
@ -507,6 +503,97 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates an existing project's details.
|
||||||
|
/// This endpoint is secure, handles concurrency, and performs non-essential tasks in the background.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of the project to update.</param>
|
||||||
|
/// <param name="updateProjectDto">The data to update the project with.</param>
|
||||||
|
/// <returns>An ApiResponse confirming the update or an appropriate error.</returns>
|
||||||
|
|
||||||
|
[HttpPut("update/{id}")]
|
||||||
|
public async Task<IActionResult> UpdateProject([FromRoute] Guid id, [FromBody] UpdateProjectDto updateProjectDto)
|
||||||
|
{
|
||||||
|
// --- Step 1: Input Validation ---
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
||||||
|
_logger.LogWarning("Update project called with invalid model state for ID {ProjectId}. Errors: {Errors}", id, string.Join(", ", errors));
|
||||||
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid request data provided.", errors, 400));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
// --- Step 2: Fetch the Existing Entity from the Database ---
|
||||||
|
// This is crucial to avoid the data loss bug. We only want to modify an existing record.
|
||||||
|
var existingProject = await _context.Projects
|
||||||
|
.Where(p => p.Id == id && p.TenantId == tenantId)
|
||||||
|
.SingleOrDefaultAsync();
|
||||||
|
|
||||||
|
// 2a. Existence Check
|
||||||
|
if (existingProject == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Attempt to update non-existent project with ID {ProjectId} by user {UserId}.", id, loggedInEmployee.Id);
|
||||||
|
return NotFound(ApiResponse<object>.ErrorResponse("Project not found.", $"No project found with ID {id}.", 404));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2b. Security Check
|
||||||
|
var hasPermission = await _permission.HasProjectPermission(loggedInEmployee, id);
|
||||||
|
if (!hasPermission)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Access DENIED for user {UserId} attempting to update project {ProjectId}.", loggedInEmployee.Id, id);
|
||||||
|
return StatusCode(403, (ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to modify this project.", 403)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Step 3: Apply Changes and Save ---
|
||||||
|
// Map the changes from the DTO onto the entity we just fetched from the database.
|
||||||
|
// This only modifies the properties defined in the mapping, preventing data loss.
|
||||||
|
_mapper.Map(updateProjectDto, existingProject);
|
||||||
|
|
||||||
|
// Mark the entity as modified (if your mapping doesn't do it automatically).
|
||||||
|
_context.Entry(existingProject).State = EntityState.Modified;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
_logger.LogInfo("Successfully updated project {ProjectId} by user {UserId}.", id, loggedInEmployee.Id);
|
||||||
|
}
|
||||||
|
catch (DbUpdateConcurrencyException ex)
|
||||||
|
{
|
||||||
|
// --- Step 4: Handle Concurrency Conflicts ---
|
||||||
|
// This happens if another user modified the project after we fetched it.
|
||||||
|
_logger.LogWarning("Concurrency conflict while updating project {ProjectId} \n {Error}", id, ex.Message);
|
||||||
|
return Conflict(ApiResponse<object>.ErrorResponse("Conflict occurred.", "This project has been modified by someone else. Please refresh and try again.", 409));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Step 5: Perform Side-Effects in the Background (Fire and Forget) ---
|
||||||
|
// The core database operation is done. Now, we perform non-blocking cache and notification updates.
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
// Create a DTO of the updated project to pass to background tasks.
|
||||||
|
var projectDto = _mapper.Map<ProjectDto>(existingProject);
|
||||||
|
|
||||||
|
// 5a. Update Cache
|
||||||
|
await UpdateCacheInBackground(existingProject);
|
||||||
|
|
||||||
|
// 5b. Send Targeted SignalR Notification
|
||||||
|
var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Update_Project", Response = projectDto };
|
||||||
|
await SendNotificationInBackground(notification, projectDto.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- Step 6: Return Success Response Immediately ---
|
||||||
|
// The client gets a fast response without waiting for caching or SignalR.
|
||||||
|
return Ok(ApiResponse<ProjectDto>.SuccessResponse(_mapper.Map<ProjectDto>(existingProject), "Project updated successfully.", 200));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// --- Step 7: Graceful Error Handling for Unexpected Errors ---
|
||||||
|
_logger.LogError("An unexpected error occurred while updating project {ProjectId} \n {Error}", id, ex.Message);
|
||||||
|
return StatusCode(500, ApiResponse<object>.ErrorResponse("An internal server error occurred.", null, 500));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Project Allocation APIs ===================================================================
|
#region =================================================================== Project Allocation APIs ===================================================================
|
||||||
@ -524,7 +611,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
||||||
|
|
||||||
}
|
}
|
||||||
Guid TenantId = GetTenantId();
|
|
||||||
|
|
||||||
if (projectid != null)
|
if (projectid != null)
|
||||||
{
|
{
|
||||||
@ -535,14 +621,14 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
|
|
||||||
result = await (from rpm in _context.Employees.Include(c => c.JobRole)
|
result = await (from rpm in _context.Employees.Include(c => c.JobRole)
|
||||||
join fp in _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectid)
|
join fp in _context.ProjectAllocations.Where(c => c.TenantId == tenantId && c.ProjectId == projectid)
|
||||||
on rpm.Id equals fp.EmployeeId
|
on rpm.Id equals fp.EmployeeId
|
||||||
select rpm).ToListAsync();
|
select rpm).ToListAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = await (from rpm in _context.Employees.Include(c => c.JobRole)
|
result = await (from rpm in _context.Employees.Include(c => c.JobRole)
|
||||||
join fp in _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectid && c.IsActive == true)
|
join fp in _context.ProjectAllocations.Where(c => c.TenantId == tenantId && c.ProjectId == projectid && c.IsActive)
|
||||||
on rpm.Id equals fp.EmployeeId
|
on rpm.Id equals fp.EmployeeId
|
||||||
select rpm).ToListAsync();
|
select rpm).ToListAsync();
|
||||||
}
|
}
|
||||||
@ -577,11 +663,9 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
||||||
|
|
||||||
}
|
}
|
||||||
Guid TenantId = GetTenantId();
|
|
||||||
|
|
||||||
|
|
||||||
var employees = await _context.ProjectAllocations
|
var employees = await _context.ProjectAllocations
|
||||||
.Where(c => c.TenantId == TenantId && c.ProjectId == projectId && c.Employee != null)
|
.Where(c => c.TenantId == tenantId && c.ProjectId == projectId && c.Employee != null)
|
||||||
.Include(e => e.Employee)
|
.Include(e => e.Employee)
|
||||||
.Select(e => new
|
.Select(e => new
|
||||||
{
|
{
|
||||||
@ -605,7 +689,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
if (projectAllocationDot != null)
|
if (projectAllocationDot != null)
|
||||||
{
|
{
|
||||||
Guid TenentID = GetTenantId();
|
|
||||||
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
|
||||||
List<object>? result = new List<object>();
|
List<object>? result = new List<object>();
|
||||||
@ -616,11 +699,11 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ProjectAllocation projectAllocation = item.ToProjectAllocationFromProjectAllocationDto(TenentID);
|
ProjectAllocation projectAllocation = item.ToProjectAllocationFromProjectAllocationDto(tenantId);
|
||||||
ProjectAllocation? projectAllocationFromDb = await _context.ProjectAllocations.Where(c => c.EmployeeId == projectAllocation.EmployeeId
|
ProjectAllocation? projectAllocationFromDb = await _context.ProjectAllocations.Where(c => c.EmployeeId == projectAllocation.EmployeeId
|
||||||
&& c.ProjectId == projectAllocation.ProjectId
|
&& c.ProjectId == projectAllocation.ProjectId
|
||||||
&& c.ReAllocationDate == null
|
&& c.ReAllocationDate == null
|
||||||
&& c.TenantId == TenentID).SingleOrDefaultAsync();
|
&& c.TenantId == tenantId).SingleOrDefaultAsync();
|
||||||
|
|
||||||
if (projectAllocationFromDb != null)
|
if (projectAllocationFromDb != null)
|
||||||
{
|
{
|
||||||
@ -688,8 +771,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
[HttpGet("assigned-projects/{employeeId}")]
|
[HttpGet("assigned-projects/{employeeId}")]
|
||||||
public async Task<IActionResult> GetProjectsByEmployee([FromRoute] Guid employeeId)
|
public async Task<IActionResult> GetProjectsByEmployee([FromRoute] Guid employeeId)
|
||||||
{
|
{
|
||||||
|
|
||||||
Guid tenantId = _userHelper.GetTenantId();
|
|
||||||
if (employeeId == Guid.Empty)
|
if (employeeId == Guid.Empty)
|
||||||
{
|
{
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid details.", "Employee id not valid.", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid details.", "Employee id not valid.", 400));
|
||||||
@ -729,7 +810,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
if (projectAllocationDtos != null && employeeId != Guid.Empty)
|
if (projectAllocationDtos != null && employeeId != Guid.Empty)
|
||||||
{
|
{
|
||||||
Guid TenentID = GetTenantId();
|
|
||||||
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
List<object>? result = new List<object>();
|
List<object>? result = new List<object>();
|
||||||
List<Guid> projectIds = new List<Guid>();
|
List<Guid> projectIds = new List<Guid>();
|
||||||
@ -738,8 +818,8 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ProjectAllocation projectAllocation = projectAllocationDto.ToProjectAllocationFromProjectsAllocationDto(TenentID, employeeId);
|
ProjectAllocation projectAllocation = projectAllocationDto.ToProjectAllocationFromProjectsAllocationDto(tenantId, employeeId);
|
||||||
ProjectAllocation? projectAllocationFromDb = await _context.ProjectAllocations.Where(c => c.EmployeeId == employeeId && c.ProjectId == projectAllocationDto.ProjectId && c.ReAllocationDate == null && c.TenantId == TenentID).SingleOrDefaultAsync();
|
ProjectAllocation? projectAllocationFromDb = await _context.ProjectAllocations.Where(c => c.EmployeeId == employeeId && c.ProjectId == projectAllocationDto.ProjectId && c.ReAllocationDate == null && c.TenantId == tenantId).SingleOrDefaultAsync();
|
||||||
|
|
||||||
if (projectAllocationFromDb != null)
|
if (projectAllocationFromDb != null)
|
||||||
{
|
{
|
||||||
@ -1017,7 +1097,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid details.", "Work Item details are not valid.", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid details.", "Work Item details are not valid.", 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
Guid tenantId = GetTenantId();
|
|
||||||
var workItemsToCreate = new List<WorkItem>();
|
var workItemsToCreate = new List<WorkItem>();
|
||||||
var workItemsToUpdate = new List<WorkItem>();
|
var workItemsToUpdate = new List<WorkItem>();
|
||||||
var responseList = new List<WorkItemVM>();
|
var responseList = new List<WorkItemVM>();
|
||||||
@ -1113,7 +1192,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
[HttpDelete("task/{id}")]
|
[HttpDelete("task/{id}")]
|
||||||
public async Task<IActionResult> DeleteProjectTask(Guid id)
|
public async Task<IActionResult> DeleteProjectTask(Guid id)
|
||||||
{
|
{
|
||||||
Guid tenantId = _userHelper.GetTenantId();
|
|
||||||
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
List<Guid> workAreaIds = new List<Guid>();
|
List<Guid> workAreaIds = new List<Guid>();
|
||||||
WorkItem? task = await _context.WorkItems.AsNoTracking().Include(t => t.WorkArea).FirstOrDefaultAsync(t => t.Id == id && t.TenantId == tenantId);
|
WorkItem? task = await _context.WorkItems.AsNoTracking().Include(t => t.WorkArea).FirstOrDefaultAsync(t => t.Id == id && t.TenantId == tenantId);
|
||||||
@ -1162,7 +1240,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
[HttpPost("manage-infra")]
|
[HttpPost("manage-infra")]
|
||||||
public async Task<IActionResult> ManageProjectInfra(List<InfraDot> infraDots)
|
public async Task<IActionResult> ManageProjectInfra(List<InfraDot> infraDots)
|
||||||
{
|
{
|
||||||
Guid tenantId = GetTenantId();
|
|
||||||
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
|
||||||
var responseData = new InfraVM { };
|
var responseData = new InfraVM { };
|
||||||
@ -1177,7 +1254,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
|
|
||||||
Building building = item.Building.ToBuildingFromBuildingDto(tenantId);
|
Building building = item.Building.ToBuildingFromBuildingDto(tenantId);
|
||||||
building.TenantId = GetTenantId();
|
building.TenantId = tenantId;
|
||||||
|
|
||||||
if (item.Building.Id == null)
|
if (item.Building.Id == null)
|
||||||
{
|
{
|
||||||
@ -1204,7 +1281,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
if (item.Floor != null)
|
if (item.Floor != null)
|
||||||
{
|
{
|
||||||
Floor floor = item.Floor.ToFloorFromFloorDto(tenantId);
|
Floor floor = item.Floor.ToFloorFromFloorDto(tenantId);
|
||||||
floor.TenantId = GetTenantId();
|
floor.TenantId = tenantId;
|
||||||
bool isCreated = false;
|
bool isCreated = false;
|
||||||
|
|
||||||
if (item.Floor.Id == null)
|
if (item.Floor.Id == null)
|
||||||
@ -1242,7 +1319,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
if (item.WorkArea != null)
|
if (item.WorkArea != null)
|
||||||
{
|
{
|
||||||
WorkArea workArea = item.WorkArea.ToWorkAreaFromWorkAreaDto(tenantId);
|
WorkArea workArea = item.WorkArea.ToWorkAreaFromWorkAreaDto(tenantId);
|
||||||
workArea.TenantId = GetTenantId();
|
workArea.TenantId = tenantId;
|
||||||
bool isCreated = false;
|
bool isCreated = false;
|
||||||
|
|
||||||
if (item.WorkArea.Id == null)
|
if (item.WorkArea.Id == null)
|
||||||
@ -1343,11 +1420,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return finalViewModels;
|
return finalViewModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Guid GetTenantId()
|
|
||||||
{
|
|
||||||
return _userHelper.GetTenantId();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<ProjectDetailsVM> GetProjectViewModel(Guid? id, Project project)
|
private async Task<ProjectDetailsVM> GetProjectViewModel(Guid? id, Project project)
|
||||||
{
|
{
|
||||||
ProjectDetailsVM vm = new ProjectDetailsVM();
|
ProjectDetailsVM vm = new ProjectDetailsVM();
|
||||||
@ -1498,6 +1570,38 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return dbProject;
|
return dbProject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method for background cache update
|
||||||
|
private async Task UpdateCacheInBackground(Project project)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// This logic can be more complex, but the idea is to update or add.
|
||||||
|
if (!await _cache.UpdateProjectDetailsOnly(project))
|
||||||
|
{
|
||||||
|
await _cache.AddProjectDetails(project);
|
||||||
|
}
|
||||||
|
_logger.LogInfo("Background cache update succeeded for project {ProjectId}.", project.Id);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError("Background cache update failed for project {ProjectId} \n {Error}", project.Id, ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method for background notification
|
||||||
|
private async Task SendNotificationInBackground(object notification, Guid projectId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
|
_logger.LogInfo("Background SignalR notification sent for project {ProjectId}.", projectId);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError("Background SignalR notification failed for project {ProjectId} \n {Error}", projectId, ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -67,11 +67,11 @@ namespace MarcoBMS.Services.Helpers
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var allocation = await GetProjectByEmployeeID(LoggedInEmployee.Id);
|
var allocation = await GetProjectByEmployeeID(LoggedInEmployee.Id);
|
||||||
if (allocation.Any())
|
if (!allocation.Any())
|
||||||
{
|
{
|
||||||
projectIds = allocation.Select(c => c.ProjectId).Distinct().ToList();
|
return new List<Guid>();
|
||||||
}
|
}
|
||||||
return new List<Guid>();
|
projectIds = allocation.Select(c => c.ProjectId).Distinct().ToList();
|
||||||
}
|
}
|
||||||
await _cache.AddProjects(LoggedInEmployee.Id, projectIds);
|
await _cache.AddProjects(LoggedInEmployee.Id, projectIds);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
using Marco.Pms.Model.Dtos.Project;
|
||||||
using Marco.Pms.Model.Master;
|
using Marco.Pms.Model.Master;
|
||||||
using Marco.Pms.Model.MongoDBModels;
|
using Marco.Pms.Model.MongoDBModels;
|
||||||
using Marco.Pms.Model.Projects;
|
using Marco.Pms.Model.Projects;
|
||||||
@ -14,7 +15,9 @@ namespace Marco.Pms.Services.MappingProfiles
|
|||||||
CreateMap<Project, ProjectVM>();
|
CreateMap<Project, ProjectVM>();
|
||||||
CreateMap<Project, ProjectInfoVM>();
|
CreateMap<Project, ProjectInfoVM>();
|
||||||
CreateMap<ProjectMongoDB, ProjectInfoVM>();
|
CreateMap<ProjectMongoDB, ProjectInfoVM>();
|
||||||
|
CreateMap<UpdateProjectDto, Project>();
|
||||||
CreateMap<Project, ProjectListVM>();
|
CreateMap<Project, ProjectListVM>();
|
||||||
|
CreateMap<Project, ProjectDto>();
|
||||||
CreateMap<ProjectMongoDB, ProjectListVM>();
|
CreateMap<ProjectMongoDB, ProjectListVM>();
|
||||||
CreateMap<ProjectMongoDB, ProjectVM>()
|
CreateMap<ProjectMongoDB, ProjectVM>()
|
||||||
.ForMember(
|
.ForMember(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user