Added an API to allocate employee to service project
This commit is contained in:
parent
fbb8a2261b
commit
62031046a1
@ -0,0 +1,10 @@
|
|||||||
|
namespace Marco.Pms.Model.Dtos.ServiceProject
|
||||||
|
{
|
||||||
|
public class ServiceProjectAllocationDto
|
||||||
|
{
|
||||||
|
public Guid ProjectId { get; set; }
|
||||||
|
public Guid EmployeeId { get; set; }
|
||||||
|
public Guid TeamRoleId { get; set; }
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
using Marco.Pms.Model.ServiceProject;
|
||||||
|
using Marco.Pms.Model.ViewModels.Activities;
|
||||||
|
|
||||||
|
namespace Marco.Pms.Model.ViewModels.ServiceProject
|
||||||
|
{
|
||||||
|
public class ServiceProjectAllocationVM
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public BasicServiceProjectVM? Project { get; set; }
|
||||||
|
public BasicEmployeeVM? Employee { get; set; }
|
||||||
|
public TeamRoleMaster? TeamRole { get; set; }
|
||||||
|
public bool IsActive { get; set; } = true;
|
||||||
|
public DateTime AssignedAt { get; set; }
|
||||||
|
public BasicEmployeeVM? AssignedBy { get; set; }
|
||||||
|
public DateTime? ReAssignedAt { get; set; }
|
||||||
|
public BasicEmployeeVM? ReAssignedBy { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -327,7 +327,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("basic")]
|
[HttpGet("basic")]
|
||||||
public async Task<IActionResult> GetEmployeesByProjectBasic(Guid? projectId, [FromQuery] string? searchString, [FromQuery] bool allEmployee)
|
public async Task<IActionResult> GetEmployeesByProjectBasic(Guid? projectId, [FromQuery] Guid? employeeId, [FromQuery] string? searchString, [FromQuery] bool allEmployee)
|
||||||
{
|
{
|
||||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var employeeQuery = _context.Employees.Where(e => e.IsActive);
|
var employeeQuery = _context.Employees.Where(e => e.IsActive);
|
||||||
@ -352,6 +352,11 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
employeeQuery = employeeQuery.Where(e => (e.FirstName + " " + e.LastName).ToLower().Contains(searchStringLower));
|
employeeQuery = employeeQuery.Where(e => (e.FirstName + " " + e.LastName).ToLower().Contains(searchStringLower));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (employeeId.HasValue)
|
||||||
|
{
|
||||||
|
employeeQuery = employeeQuery.Where(e => e.Id == employeeId.Value);
|
||||||
|
}
|
||||||
|
|
||||||
var query = employeeQuery.OrderBy(e => e.FirstName);
|
var query = employeeQuery.OrderBy(e => e.FirstName);
|
||||||
|
|
||||||
if (!allEmployee)
|
if (!allEmployee)
|
||||||
|
|||||||
@ -96,6 +96,29 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region =================================================================== Service Project Allocation Functions ===================================================================
|
||||||
|
|
||||||
|
[HttpPost("get/allocation/list")]
|
||||||
|
public async Task<IActionResult> GetServiceProjectAllocationList([FromQuery] Guid? projectId, [FromQuery] Guid? employeeId)
|
||||||
|
{
|
||||||
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
var response = await _serviceProject.GetServiceProjectAllocationListAsync(projectId, employeeId, loggedInEmploee, tenantId);
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("manage/allocation")]
|
||||||
|
public async Task<IActionResult> ManageServiceProjectAllocation([FromBody] List<ServiceProjectAllocationDto> model)
|
||||||
|
{
|
||||||
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
var response = await _serviceProject.ManageServiceProjectAllocationAsync(model, loggedInEmploee, tenantId);
|
||||||
|
if (response.Success)
|
||||||
|
{
|
||||||
|
var notification = new { LoggedInUserId = loggedInEmploee.Id, Keyword = "Service_Project_Allocation", Response = response.Data };
|
||||||
|
await _signalR.SendNotificationAsync(notification);
|
||||||
|
}
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
#region =================================================================== Job Tickets Functions ===================================================================
|
#region =================================================================== Job Tickets Functions ===================================================================
|
||||||
|
|
||||||
[HttpGet("job/list")]
|
[HttpGet("job/list")]
|
||||||
@ -116,15 +139,6 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("job/comment/list")]
|
|
||||||
public async Task<IActionResult> GetCommentListByJobTicket([FromQuery] Guid? jobTicketId, [FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20)
|
|
||||||
{
|
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
|
||||||
var response = await _serviceProject.GetCommentListByJobTicketAsync(jobTicketId, pageNumber, pageSize, loggedInEmploee, tenantId);
|
|
||||||
|
|
||||||
return StatusCode(response.StatusCode, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("job/tag/list")]
|
[HttpGet("job/tag/list")]
|
||||||
public async Task<IActionResult> GetJobTagList()
|
public async Task<IActionResult> GetJobTagList()
|
||||||
{
|
{
|
||||||
@ -135,7 +149,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("job/create")]
|
[HttpPost("job/create")]
|
||||||
public async Task<IActionResult> CreateJobTicket(CreateJobTicketDto model)
|
public async Task<IActionResult> CreateJobTicket([FromBody] CreateJobTicketDto model)
|
||||||
{
|
{
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _serviceProject.CreateJobTicketAsync(model, loggedInEmploee, tenantId);
|
var response = await _serviceProject.CreateJobTicketAsync(model, loggedInEmploee, tenantId);
|
||||||
@ -148,7 +162,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("job/status-change")]
|
[HttpPost("job/status-change")]
|
||||||
public async Task<IActionResult> ChangeJobsStatus(ChangeJobStatusDto model)
|
public async Task<IActionResult> ChangeJobsStatus([FromBody] ChangeJobStatusDto model)
|
||||||
{
|
{
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _serviceProject.ChangeJobsStatusAsync(model, loggedInEmploee, tenantId);
|
var response = await _serviceProject.ChangeJobsStatusAsync(model, loggedInEmploee, tenantId);
|
||||||
@ -161,7 +175,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPatch("job/edit/{id}")]
|
[HttpPatch("job/edit/{id}")]
|
||||||
public async Task<IActionResult> UpdateJobTicket(Guid id, JsonPatchDocument<UpdateJobTicketDto> patchDoc)
|
public async Task<IActionResult> UpdateJobTicket(Guid id, [FromBody] JsonPatchDocument<UpdateJobTicketDto> patchDoc)
|
||||||
{
|
{
|
||||||
// Validate incoming patch document
|
// Validate incoming patch document
|
||||||
if (patchDoc == null)
|
if (patchDoc == null)
|
||||||
@ -204,9 +218,21 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region =================================================================== Job Comments Functions ===================================================================
|
||||||
|
|
||||||
|
[HttpGet("job/comment/list")]
|
||||||
|
public async Task<IActionResult> GetCommentListByJobTicket([FromQuery] Guid? jobTicketId, [FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 20)
|
||||||
|
{
|
||||||
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
var response = await _serviceProject.GetCommentListByJobTicketAsync(jobTicketId, pageNumber, pageSize, loggedInEmploee, tenantId);
|
||||||
|
|
||||||
|
return StatusCode(response.StatusCode, response);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("job/add/comment")]
|
[HttpPost("job/add/comment")]
|
||||||
public async Task<IActionResult> AddCommentToJobTicket(JobCommentDto model)
|
public async Task<IActionResult> AddCommentToJobTicket([FromBody] JobCommentDto model)
|
||||||
{
|
{
|
||||||
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee loggedInEmploee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var response = await _serviceProject.AddCommentToJobTicketAsync(model, loggedInEmploee, tenantId);
|
var response = await _serviceProject.AddCommentToJobTicketAsync(model, loggedInEmploee, tenantId);
|
||||||
@ -217,6 +243,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
return StatusCode(response.StatusCode, response);
|
return StatusCode(response.StatusCode, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -198,6 +198,7 @@ namespace Marco.Pms.Services.MappingProfiles
|
|||||||
CreateMap<ServiceProject, ServiceProjectVM>();
|
CreateMap<ServiceProject, ServiceProjectVM>();
|
||||||
CreateMap<ServiceProject, BasicServiceProjectVM>();
|
CreateMap<ServiceProject, BasicServiceProjectVM>();
|
||||||
CreateMap<ServiceProject, ServiceProjectDetailsVM>();
|
CreateMap<ServiceProject, ServiceProjectDetailsVM>();
|
||||||
|
CreateMap<ServiceProjectAllocation, ServiceProjectAllocationVM>();
|
||||||
|
|
||||||
#region ======================================================= Job Ticket =======================================================
|
#region ======================================================= Job Ticket =======================================================
|
||||||
CreateMap<CreateJobTicketDto, JobTicket>();
|
CreateMap<CreateJobTicketDto, JobTicket>();
|
||||||
|
|||||||
@ -15,6 +15,10 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
Task<ApiResponse<object>> DeActivateServiceProjectAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> DeActivateServiceProjectAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region =================================================================== Service Project Allocation Functions ===================================================================
|
||||||
|
Task<ApiResponse<object>> GetServiceProjectAllocationListAsync(Guid? projectId, Guid? employeeId, Employee loggedInEmployee, Guid tenantId);
|
||||||
|
Task<ApiResponse<object>> ManageServiceProjectAllocationAsync(List<ServiceProjectAllocationDto> model, Employee loggedInEmployee, Guid tenantId);
|
||||||
|
#endregion
|
||||||
#region =================================================================== Job Tickets Functions ===================================================================
|
#region =================================================================== Job Tickets Functions ===================================================================
|
||||||
Task<ApiResponse<object>> GetJobTicketsListAsync(Guid? projectId, int pageNumber, int pageSize, bool isActive, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetJobTicketsListAsync(Guid? projectId, int pageNumber, int pageSize, bool isActive, Employee loggedInEmployee, Guid tenantId);
|
||||||
Task<ApiResponse<object>> GetJobTicketDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetJobTicketDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
|
||||||
@ -24,6 +28,10 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
Task<ApiResponse<object>> ChangeJobsStatusAsync(ChangeJobStatusDto model, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> ChangeJobsStatusAsync(ChangeJobStatusDto model, Employee loggedInEmployee, Guid tenantId);
|
||||||
Task<ApiResponse<object>> UpdateJobTicketAsync(Guid id, JobTicket jobTicket, UpdateJobTicketDto model, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> UpdateJobTicketAsync(Guid id, JobTicket jobTicket, UpdateJobTicketDto model, Employee loggedInEmployee, Guid tenantId);
|
||||||
Task<ApiResponse<object>> AddCommentToJobTicketAsync(JobCommentDto model, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> AddCommentToJobTicketAsync(JobCommentDto model, Employee loggedInEmployee, Guid tenantId);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
#region =================================================================== Job Comments Functions ===================================================================
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Pubic Helper Functions ===================================================================
|
#region =================================================================== Pubic Helper Functions ===================================================================
|
||||||
|
|||||||
@ -362,7 +362,145 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Expense Functions ===================================================================
|
#region =================================================================== Service Project Allocation Functions ===================================================================
|
||||||
|
public async Task<ApiResponse<object>> GetServiceProjectAllocationListAsync(Guid? projectId, Guid? employeeId, Employee loggedInEmployee, Guid tenantId)
|
||||||
|
{
|
||||||
|
return ApiResponse<object>.SuccessResponse(projectId, "Service project allocation fetched successfully", 200);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Manages service project allocations by adding new active allocations and removing inactive ones.
|
||||||
|
/// Validates projects, employees, and team roles exist before applying changes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">List of allocation DTOs specifying project, employee, team role, and active status.</param>
|
||||||
|
/// <param name="loggedInEmployee">Employee performing the allocation management (for audit).</param>
|
||||||
|
/// <param name="tenantId">Tenant identifier for multi-tenant data isolation.</param>
|
||||||
|
/// <returns>ApiResponse containing the updated list of active allocations or error details.</returns>
|
||||||
|
public async Task<ApiResponse<object>> ManageServiceProjectAllocationAsync(List<ServiceProjectAllocationDto> model, Employee loggedInEmployee, Guid tenantId)
|
||||||
|
{
|
||||||
|
if (tenantId == Guid.Empty)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("ManageServiceProjectAllocationAsync called with invalid tenant context by employee {EmployeeId}", loggedInEmployee.Id);
|
||||||
|
return ApiResponse<object>.ErrorResponse("Access Denied", "Invalid tenant context.", 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model == null || !model.Any())
|
||||||
|
{
|
||||||
|
_logger.LogInfo("Empty allocation model provided by employee {EmployeeId}", loggedInEmployee.Id);
|
||||||
|
return ApiResponse<object>.ErrorResponse("Bad Request", "No allocation data provided.", 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Extract distinct IDs from input for efficient bulk queries
|
||||||
|
var projectIds = model.Select(spa => spa.ProjectId).Distinct().ToList();
|
||||||
|
var employeeIds = model.Select(spa => spa.EmployeeId).Distinct().ToList();
|
||||||
|
var teamRoleIds = model.Select(spa => spa.TeamRoleId).Distinct().ToList();
|
||||||
|
|
||||||
|
// Load required reference data concurrently using separate DbContexts
|
||||||
|
var projectTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
return await context.ServiceProjects.Where(sp => projectIds.Contains(sp.Id) && sp.TenantId == tenantId && sp.IsActive).ToListAsync();
|
||||||
|
});
|
||||||
|
var employeeTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
return await context.Employees.Where(e => employeeIds.Contains(e.Id) && e.IsActive).ToListAsync();
|
||||||
|
});
|
||||||
|
var teamRoleTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
return await context.TeamRoleMasters.Where(trm => teamRoleIds.Contains(trm.Id)).ToListAsync();
|
||||||
|
});
|
||||||
|
var allocationTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
return await context.ServiceProjectAllocations.Where(spa => projectIds.Contains(spa.ProjectId) && spa.TenantId == tenantId && spa.IsActive).ToListAsync();
|
||||||
|
});
|
||||||
|
|
||||||
|
await Task.WhenAll(projectTask, employeeTask, teamRoleTask, allocationTask);
|
||||||
|
|
||||||
|
var projects = projectTask.Result;
|
||||||
|
var employees = employeeTask.Result;
|
||||||
|
var teamRoles = teamRoleTask.Result;
|
||||||
|
var allocations = allocationTask.Result;
|
||||||
|
|
||||||
|
var newAllocations = new List<ServiceProjectAllocation>();
|
||||||
|
var allocationsToRemove = new List<ServiceProjectAllocation>();
|
||||||
|
|
||||||
|
// Process each input allocation DTO
|
||||||
|
foreach (var dto in model)
|
||||||
|
{
|
||||||
|
// Validate referenced entities exist
|
||||||
|
var project = projects.FirstOrDefault(sp => sp.Id == dto.ProjectId);
|
||||||
|
var employee = employees.FirstOrDefault(e => e.Id == dto.EmployeeId);
|
||||||
|
var teamRole = teamRoles.FirstOrDefault(tr => tr.Id == dto.TeamRoleId);
|
||||||
|
|
||||||
|
if (project == null || employee == null || teamRole == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Skipping allocation with invalid references: ProjectId={ProjectId}, EmployeeId={EmployeeId}, TeamRoleId={TeamRoleId}", dto.ProjectId, dto.EmployeeId, dto.TeamRoleId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingAllocation = allocations.FirstOrDefault(spa =>
|
||||||
|
spa.ProjectId == dto.ProjectId &&
|
||||||
|
spa.EmployeeId == dto.EmployeeId &&
|
||||||
|
spa.TeamRoleId == dto.TeamRoleId);
|
||||||
|
|
||||||
|
if (dto.IsActive && existingAllocation == null)
|
||||||
|
{
|
||||||
|
newAllocations.Add(new ServiceProjectAllocation
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
|
ProjectId = dto.ProjectId,
|
||||||
|
EmployeeId = dto.EmployeeId,
|
||||||
|
TeamRoleId = dto.TeamRoleId,
|
||||||
|
AssignedAt = DateTime.UtcNow,
|
||||||
|
AssignedById = loggedInEmployee.Id,
|
||||||
|
IsActive = true,
|
||||||
|
TenantId = tenantId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (!dto.IsActive && existingAllocation != null)
|
||||||
|
{
|
||||||
|
allocationsToRemove.Add(existingAllocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Batch changes for efficiency
|
||||||
|
if (newAllocations.Any()) _context.ServiceProjectAllocations.AddRange(newAllocations);
|
||||||
|
if (allocationsToRemove.Any()) _context.ServiceProjectAllocations.RemoveRange(allocationsToRemove);
|
||||||
|
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
// Reload current active allocations for response with relevant navigation properties
|
||||||
|
var updatedAllocations = await _context.ServiceProjectAllocations
|
||||||
|
.Include(spa => spa.Project)
|
||||||
|
.Include(spa => spa.TeamRole)
|
||||||
|
.Include(spa => spa.Employee).ThenInclude(e => e!.JobRole)
|
||||||
|
.Include(spa => spa.AssignedBy).ThenInclude(e => e!.JobRole)
|
||||||
|
.Where(spa =>
|
||||||
|
projectIds.Contains(spa.ProjectId) &&
|
||||||
|
employeeIds.Contains(spa.EmployeeId) &&
|
||||||
|
teamRoleIds.Contains(spa.TeamRoleId) &&
|
||||||
|
spa.IsActive &&
|
||||||
|
spa.TenantId == tenantId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var response = _mapper.Map<List<ServiceProjectAllocationVM>>(updatedAllocations);
|
||||||
|
|
||||||
|
_logger.LogInfo("Service project allocations managed successfully by employee {EmployeeId} for tenant {TenantId}. Added {AddedCount}, Removed {RemovedCount}",
|
||||||
|
loggedInEmployee.Id, tenantId, newAllocations.Count, allocationsToRemove.Count);
|
||||||
|
|
||||||
|
return ApiResponse<object>.SuccessResponse(response, "Service project allocations managed successfully", 200);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error managing service project allocations by employee {EmployeeId} in tenant {TenantId}", loggedInEmployee.Id, tenantId);
|
||||||
|
return ApiResponse<object>.ErrorResponse("Internal Server Error", "An error occurred while managing service project allocations. Please try again later.", 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region =================================================================== Job Tickets Functions ===================================================================
|
#region =================================================================== Job Tickets Functions ===================================================================
|
||||||
@ -924,12 +1062,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
/// <param name="loggedInEmployee">Employee performing the update (used for audit and authorization).</param>
|
/// <param name="loggedInEmployee">Employee performing the update (used for audit and authorization).</param>
|
||||||
/// <param name="tenantId">Tenant identifier for data isolation.</param>
|
/// <param name="tenantId">Tenant identifier for data isolation.</param>
|
||||||
/// <returns>ApiResponse containing updated job ticket data or error details.</returns>
|
/// <returns>ApiResponse containing updated job ticket data or error details.</returns>
|
||||||
public async Task<ApiResponse<object>> UpdateJobTicketAsync(
|
public async Task<ApiResponse<object>> UpdateJobTicketAsync(Guid id, JobTicket jobTicket, UpdateJobTicketDto model, Employee loggedInEmployee, Guid tenantId)
|
||||||
Guid id,
|
|
||||||
JobTicket jobTicket,
|
|
||||||
UpdateJobTicketDto model,
|
|
||||||
Employee loggedInEmployee,
|
|
||||||
Guid tenantId)
|
|
||||||
{
|
{
|
||||||
// Validate tenant context early
|
// Validate tenant context early
|
||||||
if (tenantId == Guid.Empty)
|
if (tenantId == Guid.Empty)
|
||||||
@ -1166,7 +1299,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
#region =================================================================== Job Comments Functions ===================================================================
|
#region =================================================================== Job Comments Functions ===================================================================
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user