shoc-backend/SeaHaven.Services/Implementation/WorkOrderService.cs

168 lines
6.4 KiB
C#
Raw Normal View History

2026-04-28 18:55:14 -05:00
using Data.SeaHavenIndustries;
2026-05-14 11:00:12 -05:00
using Data.SeaHavenIndustries.Enums;
using FluentValidation;
2026-04-28 18:55:14 -05:00
using SeaHaven.DataServices.Interfaces;
using SeaHaven.Services.DTOs;
using SeaHaven.Services.Interfaces;
2026-05-14 11:00:12 -05:00
using SeaHaven.Services.Validation;
2026-04-28 18:55:14 -05:00
namespace SeaHaven.Services.Implementation
{
public class WorkOrderService : IWorkOrderService
{
private readonly IWorkOrderDataService _workOrderDataService;
2026-05-14 11:00:12 -05:00
private readonly ICreateWorkOrderValidation _createValidator;
private readonly IUpdateWorkOrderValidation _updateValidator;
2026-04-28 18:55:14 -05:00
2026-05-14 11:00:12 -05:00
public WorkOrderService(
IWorkOrderDataService workOrderDataService,
ICreateWorkOrderValidation createValidator,
IUpdateWorkOrderValidation updateValidator)
2026-04-28 18:55:14 -05:00
{
_workOrderDataService = workOrderDataService;
2026-05-14 11:00:12 -05:00
_createValidator = createValidator;
_updateValidator = updateValidator;
2026-04-28 18:55:14 -05:00
}
public async Task<WorkOrderDTO?> GetWorkOrderByIdAsync(int id)
{
var workOrder = await _workOrderDataService.GetByIdAsync(id);
2026-05-14 11:00:12 -05:00
return workOrder == null ? null : WorkOrderDTO.MapToModel(workOrder);
2026-04-28 18:55:14 -05:00
}
public async Task<WorkOrderDTO?> GetWorkOrderByIdWithDetailsAsync(int id)
{
var workOrder = await _workOrderDataService.GetByIdWithDetailsAsync(id);
2026-05-14 11:00:12 -05:00
return workOrder == null ? null : WorkOrderDTO.MapToModel(workOrder);
2026-04-28 18:55:14 -05:00
}
public async Task<IEnumerable<WorkOrderDTO>> GetAllWorkOrdersAsync()
{
var workOrders = await _workOrderDataService.GetAllAsync();
2026-05-14 11:00:12 -05:00
return workOrders.Select(WorkOrderDTO.MapToModel);
2026-04-28 18:55:14 -05:00
}
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>
{
2026-05-14 11:00:12 -05:00
Items = items.Select(WorkOrderDTO.MapToModel),
2026-04-28 18:55:14 -05:00
TotalCount = totalCount,
Page = page,
PageSize = pageSize
};
}
2026-05-14 11:00:12 -05:00
public async Task<int> CreateWorkOrderAsync(CreateWorkOrderDTO dto, string userId)
2026-04-28 18:55:14 -05:00
{
2026-05-14 11:00:12 -05:00
var validationResult = await _createValidator.ValidateAsync(dto);
if (!validationResult.IsValid)
2026-04-28 18:55:14 -05:00
{
2026-05-14 11:00:12 -05:00
throw new ValidationException(validationResult.Errors);
}
2026-04-28 18:55:14 -05:00
2026-05-14 11:00:12 -05:00
var workOrder = CreateWorkOrderDTO.MapToEntity(dto);
workOrder.createdby = userId;
workOrder.CreatedDate = DateTime.UtcNow;
2026-04-28 18:55:14 -05:00
workOrder.InternalWONumber = await _workOrderDataService.GenerateNextInternalWONumberAsync();
2026-05-14 11:00:12 -05:00
var saved = await _workOrderDataService.AddAsync(workOrder);
await LogAuditAsync(saved.Id, userId, AuditAction.Create, "Work order created");
return saved.Id;
2026-04-28 18:55:14 -05:00
}
2026-05-14 11:00:12 -05:00
public async Task<bool> UpdateWorkOrderAsync(int id, UpdateWorkOrderDTO dto, string userId)
2026-04-28 18:55:14 -05:00
{
2026-05-14 11:00:12 -05:00
var validationResult = await _updateValidator.ValidateAsync(dto);
if (!validationResult.IsValid)
{
throw new ValidationException(validationResult.Errors);
}
2026-04-28 18:55:14 -05:00
var existingWorkOrder = await _workOrderDataService.GetByIdAsync(id);
if (existingWorkOrder == null)
2026-05-14 11:00:12 -05:00
return false;
2026-04-28 18:55:14 -05:00
2026-05-14 11:00:12 -05:00
var changes = new List<string>();
changes.AddRange(TrackChanges(existingWorkOrder, dto));
UpdateWorkOrderDTO.UpdateEntity(dto, existingWorkOrder);
2026-04-28 18:55:14 -05:00
await _workOrderDataService.UpdateAsync(existingWorkOrder);
2026-05-14 11:00:12 -05:00
if (changes.Any())
{
await LogAuditAsync(id, userId, AuditAction.Edit, string.Join(", ", changes));
}
return true;
2026-04-28 18:55:14 -05:00
}
2026-05-14 11:00:12 -05:00
public async Task<bool> DeleteWorkOrderAsync(int id, string userId)
2026-04-28 18:55:14 -05:00
{
if (!await _workOrderDataService.ExistsAsync(id))
2026-05-14 11:00:12 -05:00
return false;
await _workOrderDataService.DeleteWorkOrderAttachmentsAsync(id);
await _workOrderDataService.DeleteWorkOrderContactsAsync(id);
await _workOrderDataService.DeleteWorkOrderCategoriesAsync(id);
2026-04-28 18:55:14 -05:00
await _workOrderDataService.DeleteAsync(id);
2026-05-14 11:00:12 -05:00
await LogAuditAsync(id, userId, AuditAction.Delete, "Work order deleted");
return true;
2026-04-28 18:55:14 -05:00
}
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();
}
2026-05-14 11:00:12 -05:00
private List<string> TrackChanges(WorkOrder existing, UpdateWorkOrderDTO dto)
2026-04-28 18:55:14 -05:00
{
2026-05-14 11:00:12 -05:00
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
2026-04-28 18:55:14 -05:00
{
2026-05-14 11:00:12 -05:00
WorkOrderId = workOrderId,
Action = action.ToString(),
FieldName = description,
UserId = userId,
CreatedAt = DateTime.UtcNow
2026-04-28 18:55:14 -05:00
};
2026-05-14 11:00:12 -05:00
await _workOrderDataService.AddAuditLogAsync(auditLog);
2026-04-28 18:55:14 -05:00
}
}
2026-05-14 11:00:12 -05:00
}