Added the service project details API and pagination in list of infra projects
This commit is contained in:
parent
bfe9c03147
commit
a32515fc84
@ -209,8 +209,12 @@ namespace Marco.Pms.DataAccess.Data
|
|||||||
#region ======================================================= Service Project =======================================================
|
#region ======================================================= Service Project =======================================================
|
||||||
public DbSet<ServiceProject> ServiceProjects { get; set; }
|
public DbSet<ServiceProject> ServiceProjects { get; set; }
|
||||||
public DbSet<ServiceProjectServiceMapping> ServiceProjectServiceMapping { get; set; }
|
public DbSet<ServiceProjectServiceMapping> ServiceProjectServiceMapping { get; set; }
|
||||||
#region ======================================================= Job =======================================================
|
|
||||||
#endregion
|
//#region ======================================================= Job =======================================================
|
||||||
|
//public DbSet<JobTicket> JobTickets { get; set; }
|
||||||
|
//public DbSet<JobStatus> JobStatus { get; set; }
|
||||||
|
|
||||||
|
//#endregion
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@ -1266,6 +1270,26 @@ namespace Marco.Pms.DataAccess.Data
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//modelBuilder.Entity<JobStatus>().HasData(
|
||||||
|
// new JobStatus
|
||||||
|
// {
|
||||||
|
// Id = Guid.Parse(""),
|
||||||
|
// Name = "",
|
||||||
|
// DisplayName = ""
|
||||||
|
// },
|
||||||
|
// new JobStatus
|
||||||
|
// {
|
||||||
|
// Id = Guid.Parse(""),
|
||||||
|
// Name = "",
|
||||||
|
// DisplayName = ""
|
||||||
|
// },
|
||||||
|
// new JobStatus
|
||||||
|
// {
|
||||||
|
// Id = Guid.Parse(""),
|
||||||
|
// Name = "",
|
||||||
|
// DisplayName = ""
|
||||||
|
// });
|
||||||
|
|
||||||
modelBuilder.Entity<Module>().HasData(
|
modelBuilder.Entity<Module>().HasData(
|
||||||
new Module
|
new Module
|
||||||
{
|
{
|
||||||
|
|||||||
9
Marco.Pms.Model/ServiceProject/JobStatus.cs
Normal file
9
Marco.Pms.Model/ServiceProject/JobStatus.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace Marco.Pms.Model.ServiceProject
|
||||||
|
{
|
||||||
|
public class JobStatus
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
public string DisplayName { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
39
Marco.Pms.Model/ServiceProject/JobTicket.cs
Normal file
39
Marco.Pms.Model/ServiceProject/JobTicket.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using Marco.Pms.Model.Employees;
|
||||||
|
using Marco.Pms.Model.Utilities;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Marco.Pms.Model.ServiceProject
|
||||||
|
{
|
||||||
|
public class JobTicket : TenantRelation
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Title { get; set; } = string.Empty;
|
||||||
|
public string Description { get; set; } = string.Empty;
|
||||||
|
public Guid ProjectId { get; set; }
|
||||||
|
|
||||||
|
[ValidateNever]
|
||||||
|
[ForeignKey("ProjectId")]
|
||||||
|
public ServiceProject? Project { get; set; }
|
||||||
|
public Guid StatusId { get; set; }
|
||||||
|
|
||||||
|
[ValidateNever]
|
||||||
|
[ForeignKey("StatusId")]
|
||||||
|
public JobStatus? Status { get; set; }
|
||||||
|
public DateTime StartDate { get; set; }
|
||||||
|
public DateTime DueDate { get; set; }
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
public DateTime CreatedAt { get; set; }
|
||||||
|
public Guid CreatedById { get; set; }
|
||||||
|
|
||||||
|
[ValidateNever]
|
||||||
|
[ForeignKey("CreatedById")]
|
||||||
|
public Employee? CreatedBy { get; set; }
|
||||||
|
public DateTime? UpdatedAt { get; set; }
|
||||||
|
public Guid? UpdatedById { get; set; }
|
||||||
|
|
||||||
|
[ValidateNever]
|
||||||
|
[ForeignKey("UpdatedById")]
|
||||||
|
public Employee? UpdatedBy { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
using Marco.Pms.Model.Master;
|
||||||
|
using Marco.Pms.Model.ViewModels.Activities;
|
||||||
|
using Marco.Pms.Model.ViewModels.Master;
|
||||||
|
using Marco.Pms.Model.ViewModels.Organization;
|
||||||
|
|
||||||
|
namespace Marco.Pms.Model.ViewModels.ServiceProject
|
||||||
|
{
|
||||||
|
public class ServiceProjectDetailsVM
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public string? ShortName { get; set; }
|
||||||
|
public string? Address { get; set; }
|
||||||
|
public DateTime AssignedDate { get; set; }
|
||||||
|
public StatusMaster? Status { get; set; }
|
||||||
|
public BasicOrganizationVm? Client { get; set; }
|
||||||
|
public List<ServiceMasterVM>? Services { get; set; }
|
||||||
|
public int NumberOfJobs { get; set; }
|
||||||
|
public string? ContactName { get; set; }
|
||||||
|
public string? ContactPhone { get; set; }
|
||||||
|
public string? ContactEmail { get; set; }
|
||||||
|
public DateTime CreatedAt { get; set; }
|
||||||
|
public BasicEmployeeVM? CreatedBy { get; set; }
|
||||||
|
public DateTime? UpdatedAt { get; set; }
|
||||||
|
public BasicEmployeeVM? UpdatedBy { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -57,7 +57,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
/// <returns>An ApiResponse containing a list of projects or an error.</returns>
|
/// <returns>An ApiResponse containing a list of projects or an error.</returns>
|
||||||
|
|
||||||
[HttpGet("list")]
|
[HttpGet("list")]
|
||||||
public async Task<IActionResult> GetAllProjects()
|
public async Task<IActionResult> GetAllProjects([FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20)
|
||||||
{
|
{
|
||||||
// --- Input Validation and Initial Setup ---
|
// --- Input Validation and Initial Setup ---
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
@ -70,7 +70,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid request data provided.", errors, 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid request data provided.", errors, 400));
|
||||||
}
|
}
|
||||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _projectServices.GetAllProjectsAsync(tenantId, loggedInEmployee);
|
var response = await _projectServices.GetAllProjectsAsync(pageNumber, pageSize, tenantId, loggedInEmployee);
|
||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,19 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
var response = await _serviceProject.GetServiceProjectListAsync(pageNumber, pageSize, loggedInEmploee, tenantId);
|
var response = await _serviceProject.GetServiceProjectListAsync(pageNumber, pageSize, loggedInEmploee, tenantId);
|
||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("details/{id}")]
|
||||||
|
public async Task<IActionResult> GetServiceProjectDetails(Guid id)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();
|
||||||
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
||||||
|
}
|
||||||
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
var response = await _serviceProject.GetServiceProjectDetailsAsync(id, loggedInEmploee, tenantId);
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -195,6 +195,7 @@ namespace Marco.Pms.Services.MappingProfiles
|
|||||||
|
|
||||||
CreateMap<ServiceProjectDto, ServiceProject>();
|
CreateMap<ServiceProjectDto, ServiceProject>();
|
||||||
CreateMap<ServiceProject, ServiceProjectVM>();
|
CreateMap<ServiceProject, ServiceProjectVM>();
|
||||||
|
CreateMap<ServiceProject, ServiceProjectDetailsVM>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ======================================================= Employee =======================================================
|
#region ======================================================= Employee =======================================================
|
||||||
|
|||||||
@ -97,7 +97,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
return ApiResponse<object>.ErrorResponse("An internal server error occurred. Please try again later.", null, 500);
|
return ApiResponse<object>.ErrorResponse("An internal server error occurred. Please try again later.", null, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async Task<ApiResponse<object>> GetAllProjectsAsync(Guid tenantId, Employee loggedInEmployee)
|
public async Task<ApiResponse<object>> GetAllProjectsAsync(int pageNumber, int pageSize, Guid tenantId, Employee loggedInEmployee)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -144,9 +144,25 @@ namespace Marco.Pms.Services.Service
|
|||||||
_logger.LogInfo("Cache HIT. All {ProjectCount} projects found in cache.", projectIds.Count);
|
_logger.LogInfo("Cache HIT. All {ProjectCount} projects found in cache.", projectIds.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var totalEntites = responseVms.Count;
|
||||||
|
var totalPages = (int)Math.Ceiling((double)totalEntites / pageSize);
|
||||||
|
|
||||||
|
responseVms = responseVms
|
||||||
|
.OrderBy(p => p.Name)
|
||||||
|
.Skip((pageNumber - 1) * pageSize)
|
||||||
|
.Take(pageSize).ToList();
|
||||||
|
|
||||||
// --- Step 4: Return the combined result ---
|
// --- Step 4: Return the combined result ---
|
||||||
|
|
||||||
|
var response = new
|
||||||
|
{
|
||||||
|
CurrentPage = pageNumber,
|
||||||
|
TotalPages = totalPages,
|
||||||
|
TotalEntites = totalEntites,
|
||||||
|
Data = responseVms,
|
||||||
|
};
|
||||||
_logger.LogInfo("Successfully retrieved a total of {ProjectCount} projects.", responseVms.Count);
|
_logger.LogInfo("Successfully retrieved a total of {ProjectCount} projects.", responseVms.Count);
|
||||||
return ApiResponse<object>.SuccessResponse(responseVms, "Projects retrieved successfully.", 200);
|
return ApiResponse<object>.SuccessResponse(response, "Projects retrieved successfully.", 200);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
public interface IProjectServices
|
public interface IProjectServices
|
||||||
{
|
{
|
||||||
Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ApiResponse<object>> GetAllProjectsAsync(Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<object>> GetAllProjectsAsync(int pageNumber, int pageSize, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ApiResponse<object>> GetProjectAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<object>> GetProjectAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ApiResponse<object>> GetProjectDetailsAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<object>> GetProjectDetailsAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
||||||
Task<ApiResponse<object>> GetProjectDetailsOldAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
Task<ApiResponse<object>> GetProjectDetailsOldAsync(Guid id, Guid tenantId, Employee loggedInEmployee);
|
||||||
|
|||||||
@ -6,9 +6,9 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
{
|
{
|
||||||
public interface IServiceProject
|
public interface IServiceProject
|
||||||
{
|
{
|
||||||
|
|
||||||
Task<ApiResponse<object>> CreateServiceProjectAsync(ServiceProjectDto serviceProject, Employee loggedInEmployee, Guid TenantId);
|
|
||||||
Task<ApiResponse<object>> GetServiceProjectListAsync(int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetServiceProjectListAsync(int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId);
|
||||||
|
Task<ApiResponse<object>> GetServiceProjectDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
|
||||||
|
Task<ApiResponse<object>> CreateServiceProjectAsync(ServiceProjectDto serviceProject, Employee loggedInEmployee, Guid TenantId);
|
||||||
Task<ApiResponse<object>> UpdateServiceProjectAsync(Guid id, ServiceProjectDto serviceProject, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> UpdateServiceProjectAsync(Guid id, ServiceProjectDto serviceProject, Employee loggedInEmployee, Guid tenantId);
|
||||||
Task<ApiResponse<object>> DeActivateServiceProjectAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> DeActivateServiceProjectAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,90 @@ namespace Marco.Pms.Services.Service
|
|||||||
_dbContextFactory = dbContextFactory;
|
_dbContextFactory = dbContextFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region =================================================================== Service Project Functions ===================================================================
|
||||||
|
public async Task<ApiResponse<object>> GetServiceProjectListAsync(int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
var serviceProjectQuery = _context.ServiceProjects
|
||||||
|
.Include(sp => sp.Client)
|
||||||
|
.Include(sp => sp.Status)
|
||||||
|
.Include(sp => sp.CreatedBy).ThenInclude(e => e!.JobRole)
|
||||||
|
.Where(sp => sp.TenantId == tenantId && sp.IsActive);
|
||||||
|
|
||||||
|
var totalEntites = await serviceProjectQuery.CountAsync();
|
||||||
|
var totalPages = (int)Math.Ceiling((double)totalEntites / pageSize);
|
||||||
|
|
||||||
|
var serviceProjects = await serviceProjectQuery
|
||||||
|
.OrderByDescending(e => e.CreatedAt)
|
||||||
|
.Skip((pageNumber - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var serviceProjectIds = serviceProjects.Select(sp => sp.Id).ToList();
|
||||||
|
var serviceProjectServiceMappings = await _context.ServiceProjectServiceMapping
|
||||||
|
.Include(sps => sps.Service)
|
||||||
|
.Where(sps => serviceProjectIds.Contains(sps.ProjectId) &&
|
||||||
|
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();
|
||||||
|
|
||||||
|
var response = new
|
||||||
|
{
|
||||||
|
CurrentPage = pageNumber,
|
||||||
|
TotalPages = totalPages,
|
||||||
|
TotalEntites = totalEntites,
|
||||||
|
Data = serviceProjectVMs,
|
||||||
|
};
|
||||||
|
|
||||||
|
_logger.LogInfo("Successfully retrieved a total of {ProjectCount} projects.", serviceProjectVMs.Count);
|
||||||
|
return ApiResponse<object>.SuccessResponse(serviceProjectVMs, "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>> GetServiceProjectDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId)
|
||||||
|
{
|
||||||
|
var serviceProject = 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)
|
||||||
|
.FirstOrDefaultAsync(sp => sp.Id == id && sp.TenantId == tenantId);
|
||||||
|
if (serviceProject == null)
|
||||||
|
{
|
||||||
|
return ApiResponse<object>.ErrorResponse("Service Project not found", "Service Project not found", 404);
|
||||||
|
}
|
||||||
|
var services = await _context.ServiceProjectServiceMapping
|
||||||
|
.Include(sps => sps.Service)
|
||||||
|
.Where(sps => sps.ProjectId == serviceProject.Id &&
|
||||||
|
sps.Service != null &&
|
||||||
|
sps.TenantId == tenantId)
|
||||||
|
.Select(sps => sps.Service!)
|
||||||
|
.ToListAsync();
|
||||||
|
//var numberOfJobs = await _context.JobTickets.Where(jt => jt.ProjectId == serviceProject.Id && jt.TenantId == tenantId).CountAsync();
|
||||||
|
|
||||||
|
var response = _mapper.Map<ServiceProjectDetailsVM>(serviceProject);
|
||||||
|
response.Services = _mapper.Map<List<ServiceMasterVM>>(services);
|
||||||
|
//response.NumberOfJobs = numberOfJobs;
|
||||||
|
response.NumberOfJobs = 0;
|
||||||
|
return ApiResponse<object>.SuccessResponse(response, "Service Project Details fetched successfully", 200);
|
||||||
|
}
|
||||||
public async Task<ApiResponse<object>> CreateServiceProjectAsync(ServiceProjectDto model, Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> CreateServiceProjectAsync(ServiceProjectDto model, Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
var serviceIds = model.Services.Where(s => s.IsActive).Select(s => s.ServiceId).ToList();
|
var serviceIds = model.Services.Where(s => s.IsActive).Select(s => s.ServiceId).ToList();
|
||||||
@ -116,51 +199,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
public async Task<ApiResponse<object>> GetServiceProjectListAsync(int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
var serviceProjectQuery = _context.ServiceProjects
|
|
||||||
.Include(sp => sp.Client)
|
|
||||||
.Include(sp => sp.Status)
|
|
||||||
.Include(sp => sp.CreatedBy).ThenInclude(e => e!.JobRole)
|
|
||||||
.Where(sp => sp.TenantId == tenantId && sp.IsActive);
|
|
||||||
|
|
||||||
var serviceProjects = await serviceProjectQuery
|
|
||||||
.OrderByDescending(e => e.CreatedAt)
|
|
||||||
.Skip((pageNumber - 1) * pageSize)
|
|
||||||
.Take(pageSize)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
var serviceProjectIds = serviceProjects.Select(sp => sp.Id).ToList();
|
|
||||||
var serviceProjectServiceMappings = await _context.ServiceProjectServiceMapping
|
|
||||||
.Include(sps => sps.Service)
|
|
||||||
.Where(sps => serviceProjectIds.Contains(sps.ProjectId) &&
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
// --- 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>> UpdateServiceProjectAsync(Guid id, ServiceProjectDto model, Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> UpdateServiceProjectAsync(Guid id, ServiceProjectDto model, Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
@ -314,5 +352,12 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region =================================================================== Expense Functions ===================================================================
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region =================================================================== Expense Functions ===================================================================
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,13 +18,6 @@
|
|||||||
"SenderEmail": "marcoioitsoft@gmail.com",
|
"SenderEmail": "marcoioitsoft@gmail.com",
|
||||||
"Password": "qrtq wfuj hwpp fhqr"
|
"Password": "qrtq wfuj hwpp fhqr"
|
||||||
},
|
},
|
||||||
//"SmtpSettings": {
|
|
||||||
// "SmtpServer": "mail.marcoaiot.com",
|
|
||||||
// "Port": 587,
|
|
||||||
// "SenderName": "MarcoAIOT",
|
|
||||||
// "SenderEmail": "ashutosh.nehete@marcoaiot.com",
|
|
||||||
// "Password": "Reset@123"
|
|
||||||
//},
|
|
||||||
"AppSettings": {
|
"AppSettings": {
|
||||||
"WebFrontendUrl": "http://localhost:5173",
|
"WebFrontendUrl": "http://localhost:5173",
|
||||||
"ImagesBaseUrl": "http://localhost:5173"
|
"ImagesBaseUrl": "http://localhost:5173"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user