shoc-backend/SeaHaven.Services/Implementation/WorkOrderService.cs
2026-05-14 11:00:12 -05:00

168 lines
No EOL
6.4 KiB
C#

using Data.SeaHavenIndustries;
using Data.SeaHavenIndustries.Enums;
using FluentValidation;
using SeaHaven.DataServices.Interfaces;
using SeaHaven.Services.DTOs;
using SeaHaven.Services.Interfaces;
using SeaHaven.Services.Validation;
namespace SeaHaven.Services.Implementation
{
public class WorkOrderService : IWorkOrderService
{
private readonly IWorkOrderDataService _workOrderDataService;
private readonly ICreateWorkOrderValidation _createValidator;
private readonly IUpdateWorkOrderValidation _updateValidator;
public WorkOrderService(
IWorkOrderDataService workOrderDataService,
ICreateWorkOrderValidation createValidator,
IUpdateWorkOrderValidation updateValidator)
{
_workOrderDataService = workOrderDataService;
_createValidator = createValidator;
_updateValidator = updateValidator;
}
public async Task<WorkOrderDTO?> GetWorkOrderByIdAsync(int id)
{
var workOrder = await _workOrderDataService.GetByIdAsync(id);
return workOrder == null ? null : WorkOrderDTO.MapToModel(workOrder);
}
public async Task<WorkOrderDTO?> GetWorkOrderByIdWithDetailsAsync(int id)
{
var workOrder = await _workOrderDataService.GetByIdWithDetailsAsync(id);
return workOrder == null ? null : WorkOrderDTO.MapToModel(workOrder);
}
public async Task<IEnumerable<WorkOrderDTO>> GetAllWorkOrdersAsync()
{
var workOrders = await _workOrderDataService.GetAllAsync();
return workOrders.Select(WorkOrderDTO.MapToModel);
}
public async Task<PagedResult<WorkOrderDTO>> GetWorkOrdersPagedAsync(int page, int pageSize, string? search = null, string? status = null, string? priority = null)
{
var (items, totalCount) = await _workOrderDataService.GetPagedAsync(page, pageSize, search, status, priority);
return new PagedResult<WorkOrderDTO>
{
Items = items.Select(WorkOrderDTO.MapToModel),
TotalCount = totalCount,
Page = page,
PageSize = pageSize
};
}
public async Task<int> CreateWorkOrderAsync(CreateWorkOrderDTO dto, string userId)
{
var validationResult = await _createValidator.ValidateAsync(dto);
if (!validationResult.IsValid)
{
throw new ValidationException(validationResult.Errors);
}
var workOrder = CreateWorkOrderDTO.MapToEntity(dto);
workOrder.createdby = userId;
workOrder.CreatedDate = DateTime.UtcNow;
workOrder.InternalWONumber = await _workOrderDataService.GenerateNextInternalWONumberAsync();
var saved = await _workOrderDataService.AddAsync(workOrder);
await LogAuditAsync(saved.Id, userId, AuditAction.Create, "Work order created");
return saved.Id;
}
public async Task<bool> UpdateWorkOrderAsync(int id, UpdateWorkOrderDTO dto, string userId)
{
var validationResult = await _updateValidator.ValidateAsync(dto);
if (!validationResult.IsValid)
{
throw new ValidationException(validationResult.Errors);
}
var existingWorkOrder = await _workOrderDataService.GetByIdAsync(id);
if (existingWorkOrder == null)
return false;
var changes = new List<string>();
changes.AddRange(TrackChanges(existingWorkOrder, dto));
UpdateWorkOrderDTO.UpdateEntity(dto, existingWorkOrder);
await _workOrderDataService.UpdateAsync(existingWorkOrder);
if (changes.Any())
{
await LogAuditAsync(id, userId, AuditAction.Edit, string.Join(", ", changes));
}
return true;
}
public async Task<bool> DeleteWorkOrderAsync(int id, string userId)
{
if (!await _workOrderDataService.ExistsAsync(id))
return false;
await _workOrderDataService.DeleteWorkOrderAttachmentsAsync(id);
await _workOrderDataService.DeleteWorkOrderContactsAsync(id);
await _workOrderDataService.DeleteWorkOrderCategoriesAsync(id);
await _workOrderDataService.DeleteAsync(id);
await LogAuditAsync(id, userId, AuditAction.Delete, "Work order deleted");
return true;
}
public async Task<bool> WorkOrderExistsAsync(int id)
{
return await _workOrderDataService.ExistsAsync(id);
}
public async Task<string> GenerateNextInternalWONumberAsync()
{
return await _workOrderDataService.GenerateNextInternalWONumberAsync();
}
public async Task<int> GetTotalWorkOrderCountAsync()
{
return await _workOrderDataService.CountAsync();
}
private List<string> TrackChanges(WorkOrder existing, UpdateWorkOrderDTO dto)
{
var changes = new List<string>();
if (dto.WorkerOrderTitle != null && dto.WorkerOrderTitle != existing.WorkerOrderTitle)
changes.Add($"Title: {existing.WorkerOrderTitle} → {dto.WorkerOrderTitle}");
if (dto.Status.HasValue && dto.Status.ToString() != existing.Status)
changes.Add($"Status: {existing.Status} → {dto.Status}");
if (dto.Priority.HasValue && dto.Priority.ToString() != existing.Priority)
changes.Add($"Priority: {existing.Priority} → {dto.Priority}");
if (dto.AssignTo != null && dto.AssignTo != existing.AssignTo)
changes.Add($"Assigned To: {existing.AssignTo} → {dto.AssignTo}");
if (dto.DueDate.HasValue && dto.DueDate != existing.DueDate)
changes.Add($"Due Date: {existing.DueDate:yyyy-MM-dd} → {dto.DueDate:yyyy-MM-dd}");
return changes;
}
private async Task LogAuditAsync(int workOrderId, string userId, AuditAction action, string description)
{
var auditLog = new WorkOrderAuditLog
{
WorkOrderId = workOrderId,
Action = action.ToString(),
FieldName = description,
UserId = userId,
CreatedAt = DateTime.UtcNow
};
await _workOrderDataService.AddAuditLogAsync(auditLog);
}
}
}