Checking the client and status when creating service projects
This commit is contained in:
parent
4825f24694
commit
8be9b05695
@ -1,22 +1,20 @@
|
|||||||
using Marco.Pms.Model.Master;
|
using Marco.Pms.Model.ViewModels.Master;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Marco.Pms.Model.Dtos.ServiceProject
|
namespace Marco.Pms.Model.Dtos.ServiceProject
|
||||||
{
|
{
|
||||||
public class ServiceProjectDto
|
public class ServiceProjectDto
|
||||||
{
|
{
|
||||||
public string Name { get; set; } = string.Empty;
|
public required string Name { get; set; }
|
||||||
public string ShortName { get; set; } = string.Empty;
|
public required string ShortName { get; set; }
|
||||||
public Guid ClientId { get; set; }
|
public required Guid ClientId { get; set; }
|
||||||
public required List<Guid> ServiceIds { get; set; }
|
public required List<BasicServiceMasterDto> Services { get; set; }
|
||||||
public string Address { get; set; } = string.Empty;
|
public required string Address { get; set; }
|
||||||
public DateTime AssignedDate { get; set; }
|
public required DateTime AssignedDate { get; set; }
|
||||||
public Guid StatusId { get; set; }
|
public required Guid StatusId { get; set; }
|
||||||
|
|
||||||
public string ContactName { get; set; } = string.Empty;
|
public required string ContactName { get; set; }
|
||||||
public string ContactPhone { get; set; } = string.Empty;
|
public required string ContactPhone { get; set; }
|
||||||
public string ContactEmail { get; set; } = string.Empty;
|
public required string ContactEmail { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
namespace Marco.Pms.Model.ViewModels.Master
|
||||||
|
{
|
||||||
|
public class BasicServiceMasterDto
|
||||||
|
{
|
||||||
|
public Guid ServiceId { get; set; }
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,28 +0,0 @@
|
|||||||
using Marco.Pms.Model.ViewModels.Activities;
|
|
||||||
using Marco.Pms.Model.ViewModels.Master;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Marco.Pms.Model.ViewModels.ServiceProject
|
|
||||||
{
|
|
||||||
public class ServiceProjectList
|
|
||||||
{
|
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
public string Name { get; set; } = string.Empty;
|
|
||||||
public string ShortName { get; set; } = string.Empty;
|
|
||||||
public string Address { get; set; } = string.Empty;
|
|
||||||
public DateTime AssignedDate { get; set; }
|
|
||||||
public Guid StatusId { get; set; }
|
|
||||||
|
|
||||||
public BasicEmployeeVM? CreatedBy { get; set; }
|
|
||||||
public BasicEmployeeVM? UpdatedBy { get; set; }
|
|
||||||
public DateTime? UpdatedAt { get; set; }
|
|
||||||
|
|
||||||
public DateTime CreatedAt { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,22 +1,19 @@
|
|||||||
using Marco.Pms.Model.ViewModels.Activities;
|
using Marco.Pms.Model.Master;
|
||||||
|
using Marco.Pms.Model.ViewModels.Activities;
|
||||||
using Marco.Pms.Model.ViewModels.Master;
|
using Marco.Pms.Model.ViewModels.Master;
|
||||||
using System;
|
using Marco.Pms.Model.ViewModels.Organization;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Marco.Pms.Model.ViewModels.ServiceProject
|
namespace Marco.Pms.Model.ViewModels.ServiceProject
|
||||||
{
|
{
|
||||||
public class ServiceProjectVm
|
public class ServiceProjectVM
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
public string ShortName { get; set; } = string.Empty;
|
public string ShortName { get; set; } = string.Empty;
|
||||||
public string Address { get; set; } = string.Empty;
|
public string Address { get; set; } = string.Empty;
|
||||||
public DateTime AssignedDate { get; set; }
|
public DateTime AssignedDate { get; set; }
|
||||||
public Guid StatusId { get; set; }
|
public StatusMaster? Status { get; set; }
|
||||||
|
public BasicOrganizationVm? Client { get; set; }
|
||||||
public List<ServiceMasterVM>? Services { get; set; }
|
public List<ServiceMasterVM>? Services { get; set; }
|
||||||
public BasicEmployeeVM? CreatedBy { get; set; }
|
public BasicEmployeeVM? CreatedBy { get; set; }
|
||||||
public BasicEmployeeVM? UpdatedBy { get; set; }
|
public BasicEmployeeVM? UpdatedBy { get; set; }
|
||||||
|
|||||||
@ -194,8 +194,7 @@ namespace Marco.Pms.Services.MappingProfiles
|
|||||||
|
|
||||||
|
|
||||||
CreateMap<ServiceProjectDto, ServiceProject>();
|
CreateMap<ServiceProjectDto, ServiceProject>();
|
||||||
CreateMap<ServiceProject,ServiceProjectVm>();
|
CreateMap<ServiceProject, ServiceProjectVM>();
|
||||||
CreateMap<ServiceProject, ServiceProjectList>();
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ======================================================= Employee =======================================================
|
#region ======================================================= Employee =======================================================
|
||||||
|
|||||||
@ -2,13 +2,11 @@
|
|||||||
using Marco.Pms.DataAccess.Data;
|
using Marco.Pms.DataAccess.Data;
|
||||||
using Marco.Pms.Model.Dtos.ServiceProject;
|
using Marco.Pms.Model.Dtos.ServiceProject;
|
||||||
using Marco.Pms.Model.Employees;
|
using Marco.Pms.Model.Employees;
|
||||||
using Marco.Pms.Model.Entitlements;
|
|
||||||
using Marco.Pms.Model.ServiceProject;
|
using Marco.Pms.Model.ServiceProject;
|
||||||
using Marco.Pms.Model.Utilities;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.ViewModels.Activities;
|
using Marco.Pms.Model.ViewModels.Activities;
|
||||||
using Marco.Pms.Model.ViewModels.Expanses;
|
|
||||||
using Marco.Pms.Model.ViewModels.Master;
|
using Marco.Pms.Model.ViewModels.Master;
|
||||||
using Marco.Pms.Model.ViewModels.Projects;
|
using Marco.Pms.Model.ViewModels.Organization;
|
||||||
using Marco.Pms.Model.ViewModels.ServiceProject;
|
using Marco.Pms.Model.ViewModels.ServiceProject;
|
||||||
using Marco.Pms.Services.Helpers;
|
using Marco.Pms.Services.Helpers;
|
||||||
using Marco.Pms.Services.Service.ServiceInterfaces;
|
using Marco.Pms.Services.Service.ServiceInterfaces;
|
||||||
@ -27,7 +25,12 @@ namespace Marco.Pms.Services.Service
|
|||||||
private readonly CacheUpdateHelper _cache;
|
private readonly CacheUpdateHelper _cache;
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
public ServiceProjectService(IDbContextFactory<ApplicationDbContext> dbContextFactory,IServiceScopeFactory serviceScopeFactory, ApplicationDbContext context, ILoggingService logger, CacheUpdateHelper cache, IMapper mapper)
|
public ServiceProjectService(IDbContextFactory<ApplicationDbContext> dbContextFactory,
|
||||||
|
IServiceScopeFactory serviceScopeFactory,
|
||||||
|
ApplicationDbContext context,
|
||||||
|
ILoggingService logger,
|
||||||
|
CacheUpdateHelper cache,
|
||||||
|
IMapper mapper)
|
||||||
{
|
{
|
||||||
_serviceScopeFactory = serviceScopeFactory;
|
_serviceScopeFactory = serviceScopeFactory;
|
||||||
_context = context;
|
_context = context;
|
||||||
@ -40,16 +43,36 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
public async Task<ApiResponse<object>> CreateServiceProject(ServiceProjectDto model, Guid tenantId, Employee loggedInEmployee)
|
public async Task<ApiResponse<object>> CreateServiceProject(ServiceProjectDto model, Guid tenantId, Employee loggedInEmployee)
|
||||||
{
|
{
|
||||||
using var scope = _serviceScopeFactory.CreateScope();
|
var serviceIds = model.Services.Where(s => s.IsActive).Select(s => s.ServiceId).ToList();
|
||||||
var _firebase = scope.ServiceProvider.GetService<IFirebaseService>();
|
var clientTask = Task.Run(async () =>
|
||||||
|
|
||||||
var tenant = await _context.Tenants.FirstOrDefaultAsync(t => t.Id == tenantId && t.OrganizationId == loggedInEmployee.OrganizationId);
|
|
||||||
|
|
||||||
if (tenant == null)
|
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access DENIED (OrgId:{OrgId}) by Employee {EmployeeId} for tenantId={TenantId}.",
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
loggedInEmployee.OrganizationId, loggedInEmployee.Id, tenantId);
|
return await context.Organizations.FirstOrDefaultAsync(o => o.Id == model.ClientId && o.IsActive);
|
||||||
return ApiResponse<object>.ErrorResponse("Access Denied", "You do not have permission to create a service project for this tenant.", 403);
|
});
|
||||||
|
var serviceTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
return await context.ServiceMasters.Where(s => serviceIds.Contains(s.Id) && s.TenantId == tenantId && s.IsActive).ToListAsync();
|
||||||
|
});
|
||||||
|
var statusTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
return await context.StatusMasters.FirstOrDefaultAsync(s => s.Id == model.StatusId);
|
||||||
|
});
|
||||||
|
|
||||||
|
await Task.WhenAll(clientTask, serviceTask, statusTask);
|
||||||
|
|
||||||
|
var client = clientTask.Result;
|
||||||
|
var services = serviceTask.Result;
|
||||||
|
var status = statusTask.Result;
|
||||||
|
|
||||||
|
if (client == null)
|
||||||
|
{
|
||||||
|
return ApiResponse<object>.ErrorResponse("Client not found", "Client not found", 404);
|
||||||
|
}
|
||||||
|
if (status == null)
|
||||||
|
{
|
||||||
|
return ApiResponse<object>.ErrorResponse("Project Status not found", "Project Status not found", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
var serviceProject = _mapper.Map<ServiceProject>(model);
|
var serviceProject = _mapper.Map<ServiceProject>(model);
|
||||||
@ -59,12 +82,12 @@ namespace Marco.Pms.Services.Service
|
|||||||
serviceProject.TenantId = tenantId;
|
serviceProject.TenantId = tenantId;
|
||||||
serviceProject.IsActive = true;
|
serviceProject.IsActive = true;
|
||||||
|
|
||||||
var projectServiceMapping = model.ServiceIds.Select(serviceId => new ServiceProjectServiceMapping
|
var projectServiceMapping = model.Services.Where(sdto => services.Any(s => s.Id == sdto.ServiceId)).Select(sdto => new ServiceProjectServiceMapping
|
||||||
{
|
{
|
||||||
ServiceId = serviceId,
|
ServiceId = sdto.ServiceId,
|
||||||
ProjectId = serviceProject.Id,
|
ProjectId = serviceProject.Id,
|
||||||
TenantId = tenantId
|
TenantId = tenantId
|
||||||
});
|
}).ToList();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_context.ServiceProjects.Add(serviceProject);
|
_context.ServiceProjects.Add(serviceProject);
|
||||||
@ -73,14 +96,14 @@ namespace Marco.Pms.Services.Service
|
|||||||
_logger.LogInfo("Service Project {ProjectId} created successfully for TenantId={TenantId}, by Employee {EmployeeId}.",
|
_logger.LogInfo("Service Project {ProjectId} created successfully for TenantId={TenantId}, by Employee {EmployeeId}.",
|
||||||
serviceProject.Id, tenantId, loggedInEmployee);
|
serviceProject.Id, tenantId, loggedInEmployee);
|
||||||
|
|
||||||
var serviceProjectVm = _mapper.Map<ServiceProjectVm>(serviceProject);
|
var serviceProjectVM = _mapper.Map<ServiceProjectVM>(serviceProject);
|
||||||
var services = await _context.ServiceMasters.Where(t => model.ServiceIds.Contains(t.Id) && t.TenantId == tenantId && t.IsActive).ToListAsync();
|
serviceProjectVM.Client = _mapper.Map<BasicOrganizationVm>(client);
|
||||||
|
serviceProjectVM.Status = status;
|
||||||
|
serviceProjectVM.Services = services.Where(s => serviceIds.Contains(s.Id)).Select(s => _mapper.Map<ServiceMasterVM>(s)).ToList();
|
||||||
|
|
||||||
serviceProjectVm.Services = _mapper.Map<List<ServiceMasterVM>>(services);
|
serviceProjectVM.CreatedBy = _mapper.Map<BasicEmployeeVM>(loggedInEmployee);
|
||||||
|
serviceProjectVM.CreatedAt = DateTime.UtcNow;
|
||||||
serviceProjectVm.CreatedBy = _mapper.Map<BasicEmployeeVM>(loggedInEmployee);
|
return ApiResponse<object>.SuccessResponse(serviceProjectVM, "An Successfullly occurred while saving the project.", 201);
|
||||||
serviceProjectVm.CreatedAt = DateTime.UtcNow;
|
|
||||||
return ApiResponse<object>.SuccessResponse(serviceProjectVm, "An Successfullly occurred while saving the project.", 201);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -97,10 +120,29 @@ namespace Marco.Pms.Services.Service
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
var serviceProjects = await _context.ServiceProjects.Include(sp=>sp.CreatedBy).Where(sp=>sp.TenantId == tenantId && sp.IsActive).ToListAsync();
|
var serviceProjects = await _context.ServiceProjects
|
||||||
List<ServiceProjectList> serviceProjectLists = _mapper.Map<List<ServiceProjectList>>(serviceProjects);
|
.Include(sp => sp.Client)
|
||||||
_logger.LogInfo("Successfully retrieved a total of {ProjectCount} projects.", serviceProjectLists.Count);
|
.Include(sp => sp.Status)
|
||||||
return ApiResponse<object>.SuccessResponse(serviceProjectLists, "Projects retrieved successfully.", 200);
|
.Include(sp => sp.CreatedBy).ThenInclude(e => e!.JobRole)
|
||||||
|
.Include(sp => sp.UpdatedBy).ThenInclude(e => e!.JobRole)
|
||||||
|
.Where(sp => sp.TenantId == tenantId && sp.IsActive).ToListAsync();
|
||||||
|
|
||||||
|
var serviceProjectIds = serviceProjects.Select(sp => sp.Id).ToList();
|
||||||
|
var serviceProjectServiceMappings = await _context.ServiceProjectServiceMapping
|
||||||
|
.Include(sps => sps.Service)
|
||||||
|
.Where(sps => serviceProjectIds.Contains(sps.Id) && sps.Service != null && sps.TenantId == tenantId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var serviceProjectVMs = serviceProjects.Select(sp =>
|
||||||
|
{
|
||||||
|
var services = serviceProjectServiceMappings.Where(sps => sps.ProjectId == sp.Id).Select(sps => sps.Service!).ToList();
|
||||||
|
var result = _mapper.Map<ServiceProjectVM>(sp);
|
||||||
|
result.Services = _mapper.Map<List<ServiceMasterVM>>(services);
|
||||||
|
return result;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
_logger.LogInfo("Successfully retrieved a total of {ProjectCount} projects.", serviceProjectVMs.Count);
|
||||||
|
return ApiResponse<object>.SuccessResponse(serviceProjectVMs, "Projects retrieved successfully.", 200);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -118,9 +160,9 @@ namespace Marco.Pms.Services.Service
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
var serviceProject = await _context.ServiceProjects.Where(sp => sp.Id == id && sp.TenantId == tenantId).FirstOrDefaultAsync();
|
var serviceProject = await _context.ServiceProjects.Where(sp => sp.Id == id && sp.TenantId == tenantId).FirstOrDefaultAsync();
|
||||||
|
|
||||||
if(serviceProject == null)
|
if (serviceProject == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Attempt to update non-existent Service project with ID {ProjectId} by user {UserId}.", id, loggedInEmployee.Id);
|
_logger.LogWarning("Attempt to update non-existent Service project with ID {ProjectId} by user {UserId}.", id, loggedInEmployee.Id);
|
||||||
return ApiResponse<object>.ErrorResponse("Project not found.", $"No project found with ID {id}.", 404);
|
return ApiResponse<object>.ErrorResponse("Project not found.", $"No project found with ID {id}.", 404);
|
||||||
@ -135,13 +177,13 @@ namespace Marco.Pms.Services.Service
|
|||||||
serviceProject.UpdatedById = loggedInEmployee.Id;
|
serviceProject.UpdatedById = loggedInEmployee.Id;
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
|
||||||
serviceProject = await _context.ServiceProjects.Include(sp => sp.UpdatedBy).Where(sp => sp.Id == id && sp.TenantId == tenantId).FirstOrDefaultAsync();
|
serviceProject = await _context.ServiceProjects.Include(sp => sp.UpdatedBy).Where(sp => sp.Id == id && sp.TenantId == tenantId).FirstOrDefaultAsync();
|
||||||
|
|
||||||
var services = await _context.ServiceProjectServiceMapping.Include(t => t.Service).Where(t => t.ProjectId == serviceProject!.Id && t.Service != null && t.TenantId == tenantId).Select(t => t.Service!).ToListAsync();
|
var services = await _context.ServiceProjectServiceMapping.Include(t => t.Service).Where(t => t.ProjectId == serviceProject!.Id && t.Service != null && t.TenantId == tenantId).Select(t => t.Service!).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
ServiceProjectVm serviceProjectVm = _mapper.Map<ServiceProjectVm>(serviceProject);
|
ServiceProjectVM serviceProjectVm = _mapper.Map<ServiceProjectVM>(serviceProject);
|
||||||
|
|
||||||
serviceProjectVm.Services = _mapper.Map<List<ServiceMasterVM>>(services);
|
serviceProjectVm.Services = _mapper.Map<List<ServiceMasterVM>>(services);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user