Added the deassiged service from project API

This commit is contained in:
ashutosh.nehete 2025-09-18 17:23:50 +05:30
parent aed6949187
commit 1e66dd2017
7 changed files with 219 additions and 6 deletions

View File

@ -4,5 +4,7 @@
{ {
public required Guid ProjectId { get; set; } public required Guid ProjectId { get; set; }
public required List<Guid> ServiceIds { get; set; } public required List<Guid> ServiceIds { get; set; }
public DateTime PlannedStartDate { get; set; }
public DateTime PlannedEndDate { get; set; }
} }
} }

View File

@ -0,0 +1,8 @@
namespace Marco.Pms.Model.Dtos.Projects
{
public class DeassignServiceDto
{
public required Guid ProjectId { get; set; }
public required List<Guid> ServiceIds { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using Marco.Pms.Model.ViewModels.Master;
namespace Marco.Pms.Model.ViewModels.Projects
{
public class ProjectServiceVM
{
public BasicProjectVM? Project { get; set; }
public ServiceMasterVM? Service { get; set; }
public DateTime PlannedStartDate { get; set; }
public DateTime PlannedEndDate { get; set; }
public DateTime ActualStartDate { get; set; }
public DateTime? ActualEndDate { get; set; }
}
}

View File

@ -253,8 +253,7 @@ namespace Marco.Pms.Services.Controllers
{ {
await using var context = await _dbContextFactory.CreateDbContextAsync(); await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.ProjectServiceMappings return await context.ProjectServiceMappings
.Where(sp => model.ServiceIds.Contains(sp.ServiceId) && sp.ProjectId == model.ProjectId && sp.PlannedEndDate.Date <= todaysDate .Where(sp => model.ServiceIds.Contains(sp.ServiceId) && sp.ProjectId == model.ProjectId && sp.IsActive).ToListAsync();
&& sp.PlannedStartDate.Date >= todaysDate && sp.ActualStartDate.Date >= todaysDate).ToListAsync();
}); });
var serviceTask = Task.Run(async () => var serviceTask = Task.Run(async () =>
@ -361,7 +360,8 @@ namespace Marco.Pms.Services.Controllers
TenantId = project.TenantId, TenantId = project.TenantId,
PlannedStartDate = project.StartDate ?? DateTime.UtcNow, PlannedStartDate = project.StartDate ?? DateTime.UtcNow,
PlannedEndDate = project.EndDate ?? DateTime.UtcNow, PlannedEndDate = project.EndDate ?? DateTime.UtcNow,
ActualStartDate = DateTime.UtcNow ActualStartDate = DateTime.UtcNow,
IsActive = true
}; };
_context.ProjectServiceMappings.Add(projectService); _context.ProjectServiceMappings.Add(projectService);
} }
@ -380,6 +380,7 @@ namespace Marco.Pms.Services.Controllers
_context.ProjectOrgMappings.AddRange(projectOrgMappings); _context.ProjectOrgMappings.AddRange(projectOrgMappings);
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
await transaction.CommitAsync();
var organizationVm = _mapper.Map<BasicOrganizationVm>(organization); var organizationVm = _mapper.Map<BasicOrganizationVm>(organization);
var parentorganizationVm = _mapper.Map<BasicOrganizationVm>(parentorganization); var parentorganizationVm = _mapper.Map<BasicOrganizationVm>(parentorganization);
@ -400,12 +401,12 @@ namespace Marco.Pms.Services.Controllers
{ {
await transaction.RollbackAsync(); await transaction.RollbackAsync();
_logger.LogError(dbEx, "Database Exception has been occured"); _logger.LogError(dbEx, "Database Exception has been occured, While assigning the organization to project");
return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal error", "An database exception has been occured", 500)); return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal error", "An database exception has been occured", 500));
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Exception has been occured"); _logger.LogError(ex, "Exception has been occured, While assigned the organizatio to project");
return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal error", "An internal exception has been occured", 500)); return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal error", "An internal exception has been occured", 500));
} }
} }

View File

@ -1,4 +1,5 @@
using Marco.Pms.Model.Dtos.Project; using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Dtos.Projects;
using Marco.Pms.Model.Dtos.Util; using Marco.Pms.Model.Dtos.Util;
using Marco.Pms.Model.Employees; using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Utilities; using Marco.Pms.Model.Utilities;
@ -455,14 +456,16 @@ namespace MarcoBMS.Services.Controllers
#endregion #endregion
[HttpPost("assign/project-level-permission")] #region =================================================================== Project-Level Permission APIs ===================================================================
[HttpPost("assign/project-level-permission")]
public async Task<IActionResult> ManageProjectLevelPermission([FromBody] ProjctLevelPermissionDto model) public async Task<IActionResult> ManageProjectLevelPermission([FromBody] ProjctLevelPermissionDto model)
{ {
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.ManageProjectLevelPermissionAsync(model, tenantId, loggedInEmployee); var response = await _projectServices.ManageProjectLevelPermissionAsync(model, tenantId, loggedInEmployee);
return StatusCode(response.StatusCode, response); return StatusCode(response.StatusCode, response);
} }
[HttpGet("get/project-level-permission/employee/{employeeId}/project/{projectId}")] [HttpGet("get/project-level-permission/employee/{employeeId}/project/{projectId}")]
public async Task<IActionResult> GetAssignedProjectLevelPermission(Guid employeeId, Guid projectId) public async Task<IActionResult> GetAssignedProjectLevelPermission(Guid employeeId, Guid projectId)
{ {
@ -470,6 +473,7 @@ namespace MarcoBMS.Services.Controllers
var response = await _projectServices.GetAssignedProjectLevelPermissionAsync(employeeId, projectId, tenantId, loggedInEmployee); var response = await _projectServices.GetAssignedProjectLevelPermissionAsync(employeeId, projectId, tenantId, loggedInEmployee);
return StatusCode(response.StatusCode, response); return StatusCode(response.StatusCode, response);
} }
[HttpGet("get/all/project-level-permission/{projectId}")] [HttpGet("get/all/project-level-permission/{projectId}")]
public async Task<IActionResult> GetAllPermissionFroProject(Guid projectId) public async Task<IActionResult> GetAllPermissionFroProject(Guid projectId)
{ {
@ -477,6 +481,7 @@ namespace MarcoBMS.Services.Controllers
var response = await _projectServices.GetAllPermissionFroProjectAsync(projectId, loggedInEmployee, tenantId); var response = await _projectServices.GetAllPermissionFroProjectAsync(projectId, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response); return StatusCode(response.StatusCode, response);
} }
[HttpGet("get/proejct-level/modules")] [HttpGet("get/proejct-level/modules")]
public async Task<IActionResult> AssignProjectLevelModules() public async Task<IActionResult> AssignProjectLevelModules()
{ {
@ -484,6 +489,7 @@ namespace MarcoBMS.Services.Controllers
var response = await _projectServices.AssignProjectLevelModulesAsync(tenantId, loggedInEmployee); var response = await _projectServices.AssignProjectLevelModulesAsync(tenantId, loggedInEmployee);
return StatusCode(response.StatusCode, response); return StatusCode(response.StatusCode, response);
} }
[HttpGet("get/proejct-level/employees/{projectId}")] [HttpGet("get/proejct-level/employees/{projectId}")]
public async Task<IActionResult> GetEmployeeToWhomProjectLevelAssigned(Guid projectId) public async Task<IActionResult> GetEmployeeToWhomProjectLevelAssigned(Guid projectId)
{ {
@ -492,5 +498,39 @@ namespace MarcoBMS.Services.Controllers
return StatusCode(response.StatusCode, response); return StatusCode(response.StatusCode, response);
} }
#endregion
#region =================================================================== Assign Service APIs ===================================================================
[HttpPost("assign/service")]
public async Task<IActionResult> AssignServiceToProject([FromBody] AssignServiceDto model)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.AssignServiceToProjectAsync(model, tenantId, loggedInEmployee);
if (response.Success)
{
string message = response.Message;
var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Assigned_Services", data = response.Data, Message = message };
await _signalR.SendNotificationAsync(notification);
}
return StatusCode(response.StatusCode, response);
}
[HttpPost("deassign/service")]
public async Task<IActionResult> DeassignServiceToProject([FromBody] DeassignServiceDto model)
{
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _projectServices.DeassignServiceToProjectAsync(model, tenantId, loggedInEmployee);
if (response.Success)
{
string message = response.Message;
var notification = new { LoggedInUserId = loggedInEmployee.Id, Keyword = "Deassigned_Services", data = response.Data, Message = message };
await _signalR.SendNotificationAsync(notification);
}
return StatusCode(response.StatusCode, response);
}
#endregion
} }
}; };

View File

@ -3,10 +3,12 @@ using AutoMapper.QueryableExtensions;
using Marco.Pms.DataAccess.Data; using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Activities; using Marco.Pms.Model.Activities;
using Marco.Pms.Model.Dtos.Project; using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Dtos.Projects;
using Marco.Pms.Model.Dtos.Util; using Marco.Pms.Model.Dtos.Util;
using Marco.Pms.Model.Employees; using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.MongoDBModels.Project; using Marco.Pms.Model.MongoDBModels.Project;
using Marco.Pms.Model.OrganizationModel;
using Marco.Pms.Model.Projects; using Marco.Pms.Model.Projects;
using Marco.Pms.Model.TenantModels; using Marco.Pms.Model.TenantModels;
using Marco.Pms.Model.Utilities; using Marco.Pms.Model.Utilities;
@ -1830,6 +1832,148 @@ namespace Marco.Pms.Services.Service
} }
#endregion #endregion
#region =================================================================== Assign Service APIs ===================================================================
public async Task<ApiResponse<object>> AssignServiceToProjectAsync(AssignServiceDto model, Guid tenantId, Employee loggedInEmployee)
{
await using var transaction = await _context.Database.BeginTransactionAsync();
try
{
var project = await _context.Projects.FirstOrDefaultAsync(p => p.Id == model.ProjectId && p.TenantId == tenantId);
if (project == null)
{
return ApiResponse<object>.ErrorResponse("Project not found", "Project not found in database", 404);
}
var todaysDate = DateTime.UtcNow.Date;
var projectServicesTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.ProjectServiceMappings
.Where(sp => model.ServiceIds.Contains(sp.ServiceId) && sp.ProjectId == model.ProjectId && sp.IsActive).ToListAsync();
});
var serviceTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.ServiceMasters.Where(s => model.ServiceIds.Contains(s.Id) && s.TenantId == tenantId).ToListAsync();
});
await Task.WhenAll(projectServicesTask, serviceTask);
var projectServices = projectServicesTask.Result;
var services = serviceTask.Result;
foreach (var serviceId in model.ServiceIds)
{
var projectService = projectServices.FirstOrDefault(ps => ps.ServiceId == serviceId);
if (projectService == null)
{
projectService = new ProjectServiceMapping
{
ProjectId = project.Id,
ServiceId = serviceId,
TenantId = project.TenantId,
PlannedStartDate = model.PlannedStartDate,
PlannedEndDate = model.PlannedEndDate,
ActualStartDate = DateTime.UtcNow,
IsActive = true
};
_context.ProjectServiceMappings.Add(projectService);
}
}
await _context.SaveChangesAsync();
await transaction.CommitAsync();
var response = services.Select(s => new ProjectServiceVM
{
Project = _mapper.Map<BasicProjectVM>(project),
Service = _mapper.Map<ServiceMasterVM>(s),
PlannedStartDate = model.PlannedStartDate,
PlannedEndDate = model.PlannedEndDate,
ActualStartDate = DateTime.UtcNow
});
return ApiResponse<object>.SuccessResponse(response, "Services has been assigned to the project", 200);
}
catch (DbUpdateException dbEx)
{
await transaction.RollbackAsync();
_logger.LogError(dbEx, "Database Exception has been occured, While assigning the sevice to the project");
return ApiResponse<object>.ErrorResponse("Internal error", "An database exception has been occured", 500);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception has been occured, While assigning the sevice to the project");
return ApiResponse<object>.ErrorResponse("Internal error", "An internal exception has been occured", 500);
}
}
public async Task<ApiResponse<object>> DeassignServiceToProjectAsync(DeassignServiceDto model, Guid tenantId, Employee loggedInEmployee)
{
await using var transaction = await _context.Database.BeginTransactionAsync();
try
{
var project = await _context.Projects.FirstOrDefaultAsync(p => p.Id == model.ProjectId && p.TenantId == tenantId);
if (project == null)
{
return ApiResponse<object>.ErrorResponse("Project not found", "Project not found in database", 404);
}
var todaysDate = DateTime.UtcNow.Date;
var projectServicesTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.ProjectServiceMappings
.AsNoTracking()
.Where(sp => model.ServiceIds.Contains(sp.ServiceId) && sp.ProjectId == model.ProjectId && sp.IsActive).ToListAsync();
});
var serviceTask = Task.Run(async () =>
{
await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.ServiceMasters.Where(s => model.ServiceIds.Contains(s.Id) && s.TenantId == tenantId).ToListAsync();
});
await Task.WhenAll(projectServicesTask, serviceTask);
var projectServices = projectServicesTask.Result;
var services = serviceTask.Result;
if (!projectServices.Any())
{
return ApiResponse<object>.ErrorResponse("Project Service mapping not found", "Project Service mapping not found in database", 404);
}
projectServices = projectServices.Select(ps =>
{
ps.IsActive = false;
return ps;
}).ToList();
_context.ProjectServiceMappings.UpdateRange(projectServices);
await _context.SaveChangesAsync();
await transaction.CommitAsync();
return ApiResponse<object>.SuccessResponse(new { }, "Services has been deassigned to the project", 200);
}
catch (DbUpdateException dbEx)
{
await transaction.RollbackAsync();
_logger.LogError(dbEx, "Database Exception has been occured, While deassigning the sevice to the project");
return ApiResponse<object>.ErrorResponse("Internal error", "An database exception has been occured", 500);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception has been occured, While deassigning the sevice to the project");
return ApiResponse<object>.ErrorResponse("Internal error", "An internal exception has been occured", 500);
}
}
#endregion
#region =================================================================== Helper Functions =================================================================== #region =================================================================== Helper Functions ===================================================================
public async Task<List<Project>> GetAllProjectByTanentID(Guid tanentId) public async Task<List<Project>> GetAllProjectByTanentID(Guid tanentId)

View File

@ -1,4 +1,5 @@
using Marco.Pms.Model.Dtos.Project; using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Dtos.Projects;
using Marco.Pms.Model.Dtos.Util; using Marco.Pms.Model.Dtos.Util;
using Marco.Pms.Model.Employees; using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Projects; using Marco.Pms.Model.Projects;
@ -42,5 +43,8 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
Task<ApiResponse<object>> GetEmployeeToWhomProjectLevelAssignedAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee); Task<ApiResponse<object>> GetEmployeeToWhomProjectLevelAssignedAsync(Guid projectId, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetAllPermissionFroProjectAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId); Task<ApiResponse<object>> GetAllPermissionFroProjectAsync(Guid projectId, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> AssignServiceToProjectAsync(AssignServiceDto model, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> DeassignServiceToProjectAsync(DeassignServiceDto model, Guid tenantId, Employee loggedInEmployee);
} }
} }