165 lines
7.4 KiB
C#
165 lines
7.4 KiB
C#
using AutoMapper;
|
|
using Marco.Pms.DataAccess.Data;
|
|
using Marco.Pms.Model.Dtos.ServiceProject;
|
|
using Marco.Pms.Model.Employees;
|
|
using Marco.Pms.Model.Entitlements;
|
|
using Marco.Pms.Model.ServiceProject;
|
|
using Marco.Pms.Model.Utilities;
|
|
using Marco.Pms.Model.ViewModels.Activities;
|
|
using Marco.Pms.Model.ViewModels.Expanses;
|
|
using Marco.Pms.Model.ViewModels.Master;
|
|
using Marco.Pms.Model.ViewModels.Projects;
|
|
using Marco.Pms.Model.ViewModels.ServiceProject;
|
|
using Marco.Pms.Services.Helpers;
|
|
using Marco.Pms.Services.Service.ServiceInterfaces;
|
|
using MarcoBMS.Services.Service;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Marco.Pms.Services.Service
|
|
{
|
|
public class ServiceProjectService : IServiceProject
|
|
{
|
|
|
|
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
|
|
private readonly IServiceScopeFactory _serviceScopeFactory;
|
|
private readonly ApplicationDbContext _context; // Keeping this for direct scoped context use where appropriate
|
|
private readonly ILoggingService _logger;
|
|
private readonly CacheUpdateHelper _cache;
|
|
private readonly IMapper _mapper;
|
|
|
|
public ServiceProjectService(IDbContextFactory<ApplicationDbContext> dbContextFactory,IServiceScopeFactory serviceScopeFactory, ApplicationDbContext context, ILoggingService logger, CacheUpdateHelper cache, IMapper mapper)
|
|
{
|
|
_serviceScopeFactory = serviceScopeFactory;
|
|
_context = context;
|
|
_logger = logger;
|
|
_cache = cache;
|
|
_mapper = mapper;
|
|
_dbContextFactory = dbContextFactory;
|
|
}
|
|
|
|
|
|
public async Task<ApiResponse<object>> CreateServiceProject(ServiceProjectDto model, Guid tenantId, Employee loggedInEmployee)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _firebase = scope.ServiceProvider.GetService<IFirebaseService>();
|
|
|
|
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}.",
|
|
loggedInEmployee.OrganizationId, loggedInEmployee.Id, tenantId);
|
|
return ApiResponse<object>.ErrorResponse("Access Denied", "You do not have permission to create a service project for this tenant.", 403);
|
|
}
|
|
|
|
var serviceProject = _mapper.Map<ServiceProject>(model);
|
|
serviceProject.Id = Guid.NewGuid();
|
|
serviceProject.CreatedById = loggedInEmployee.Id;
|
|
serviceProject.CreatedAt = DateTime.UtcNow;
|
|
serviceProject.TenantId = tenantId;
|
|
serviceProject.IsActive = true;
|
|
|
|
var projectServiceMapping = model.ServiceIds.Select(serviceId => new ServiceProjectServiceMapping
|
|
{
|
|
ServiceId = serviceId,
|
|
ProjectId = serviceProject.Id,
|
|
TenantId = tenantId
|
|
});
|
|
try
|
|
{
|
|
_context.ServiceProjects.Add(serviceProject);
|
|
_context.ServiceProjectServiceMapping.AddRange(projectServiceMapping);
|
|
await _context.SaveChangesAsync();
|
|
_logger.LogInfo("Service Project {ProjectId} created successfully for TenantId={TenantId}, by Employee {EmployeeId}.",
|
|
serviceProject.Id, tenantId, loggedInEmployee);
|
|
|
|
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.Services = _mapper.Map<List<ServiceMasterVM>>(services);
|
|
|
|
serviceProjectVm.CreatedBy = _mapper.Map<BasicEmployeeVM>(loggedInEmployee);
|
|
serviceProjectVm.CreatedAt = DateTime.UtcNow;
|
|
return ApiResponse<object>.SuccessResponse(serviceProjectVm, "An Successfullly occurred while saving the project.", 201);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "DB Failure: Service Project creation failed for TenantId={TenantId}. Rolling back.", tenantId);
|
|
return ApiResponse<object>.ErrorResponse("An error occurred while saving the project.", ex.Message, 500);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
public async Task<ApiResponse<object>> GetServiceProjectList(Guid tenantId, Employee loggedInEmployee)
|
|
{
|
|
try
|
|
{
|
|
|
|
var serviceProjects = await _context.ServiceProjects.Include(sp=>sp.CreatedBy).Where(sp=>sp.TenantId == tenantId && sp.IsActive).ToListAsync();
|
|
List<ServiceProjectList> serviceProjectLists = _mapper.Map<List<ServiceProjectList>>(serviceProjects);
|
|
_logger.LogInfo("Successfully retrieved a total of {ProjectCount} projects.", serviceProjectLists.Count);
|
|
return ApiResponse<object>.SuccessResponse(serviceProjectLists, "Projects retrieved successfully.", 200);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// --- Step 5: Graceful Error Handling ---
|
|
_logger.LogError(ex, "An unexpected error occurred in GetAllProjects for tenant {TenantId}.", tenantId);
|
|
return ApiResponse<object>.ErrorResponse("An internal server error occurred. Please try again later.", null, 500);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
public async Task<ApiResponse<object>> UpdateServiceProject(Guid id, ServiceProjectDto model, Guid tenantId, Employee loggedInEmployee)
|
|
{
|
|
try
|
|
{
|
|
|
|
var serviceProject = await _context.ServiceProjects.Where(sp => sp.Id == id && sp.TenantId == tenantId).FirstOrDefaultAsync();
|
|
|
|
if(serviceProject == null)
|
|
{
|
|
_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);
|
|
}
|
|
|
|
|
|
|
|
_mapper.Map(model, serviceProject);
|
|
|
|
|
|
serviceProject.UpdatedAt = DateTime.UtcNow;
|
|
serviceProject.UpdatedById = loggedInEmployee.Id;
|
|
await _context.SaveChangesAsync();
|
|
|
|
|
|
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();
|
|
|
|
|
|
ServiceProjectVm serviceProjectVm = _mapper.Map<ServiceProjectVm>(serviceProject);
|
|
|
|
serviceProjectVm.Services = _mapper.Map<List<ServiceMasterVM>>(services);
|
|
|
|
return ApiResponse<object>.SuccessResponse(serviceProjectVm, "Service Project updated successfully.", 200);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "An unexpected error occurred in Updating Service Project for tenant {TenantId}.", tenantId);
|
|
return ApiResponse<object>.ErrorResponse("An internal server error occurred. Please try again later.", null, 500);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|