Checking the client and status when creating service projects

This commit is contained in:
ashutosh.nehete 2025-11-11 17:53:39 +05:30
parent 4825f24694
commit 8be9b05695
6 changed files with 100 additions and 84 deletions

View File

@ -1,22 +1,20 @@
using Marco.Pms.Model.Master;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
using Marco.Pms.Model.ViewModels.Master;
namespace Marco.Pms.Model.Dtos.ServiceProject
{
public class ServiceProjectDto
{
public string Name { get; set; } = string.Empty;
public string ShortName { get; set; } = string.Empty;
public Guid ClientId { get; set; }
public required List<Guid> ServiceIds { get; set; }
public string Address { get; set; } = string.Empty;
public DateTime AssignedDate { get; set; }
public Guid StatusId { get; set; }
public required string Name { get; set; }
public required string ShortName { get; set; }
public required Guid ClientId { get; set; }
public required List<BasicServiceMasterDto> Services { get; set; }
public required string Address { get; set; }
public required DateTime AssignedDate { get; set; }
public required Guid StatusId { get; set; }
public string ContactName { get; set; } = string.Empty;
public string ContactPhone { get; set; } = string.Empty;
public string ContactEmail { get; set; } = string.Empty;
public required string ContactName { get; set; }
public required string ContactPhone { get; set; }
public required string ContactEmail { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace Marco.Pms.Model.ViewModels.Master
{
public class BasicServiceMasterDto
{
public Guid ServiceId { get; set; }
public bool IsActive { get; set; }
}
}

View File

@ -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; }
}
}

View File

@ -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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Marco.Pms.Model.ViewModels.Organization;
namespace Marco.Pms.Model.ViewModels.ServiceProject
{
public class ServiceProjectVm
public class ServiceProjectVM
{
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 StatusMaster? Status { get; set; }
public BasicOrganizationVm? Client { get; set; }
public List<ServiceMasterVM>? Services { get; set; }
public BasicEmployeeVM? CreatedBy { get; set; }
public BasicEmployeeVM? UpdatedBy { get; set; }

View File

@ -194,8 +194,7 @@ namespace Marco.Pms.Services.MappingProfiles
CreateMap<ServiceProjectDto, ServiceProject>();
CreateMap<ServiceProject,ServiceProjectVm>();
CreateMap<ServiceProject, ServiceProjectList>();
CreateMap<ServiceProject, ServiceProjectVM>();
#endregion
#region ======================================================= Employee =======================================================

View File

@ -2,13 +2,11 @@
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.Organization;
using Marco.Pms.Model.ViewModels.ServiceProject;
using Marco.Pms.Services.Helpers;
using Marco.Pms.Services.Service.ServiceInterfaces;
@ -27,7 +25,12 @@ namespace Marco.Pms.Services.Service
private readonly CacheUpdateHelper _cache;
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;
_context = context;
@ -40,16 +43,36 @@ namespace Marco.Pms.Services.Service
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)
var serviceIds = model.Services.Where(s => s.IsActive).Select(s => s.ServiceId).ToList();
var clientTask = Task.Run(async () =>
{
_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);
await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.Organizations.FirstOrDefaultAsync(o => o.Id == model.ClientId && o.IsActive);
});
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);
@ -59,12 +82,12 @@ namespace Marco.Pms.Services.Service
serviceProject.TenantId = tenantId;
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,
TenantId = tenantId
});
}).ToList();
try
{
_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}.",
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();
var serviceProjectVM = _mapper.Map<ServiceProjectVM>(serviceProject);
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;
return ApiResponse<object>.SuccessResponse(serviceProjectVm, "An Successfullly occurred while saving the project.", 201);
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)
@ -97,10 +120,29 @@ namespace Marco.Pms.Services.Service
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);
var serviceProjects = await _context.ServiceProjects
.Include(sp => sp.Client)
.Include(sp => sp.Status)
.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)
@ -141,7 +183,7 @@ namespace Marco.Pms.Services.Service
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);