using Data.SeaHavenIndustries;
using FluentValidation;
using SeaHaven.DataServices.Interfaces;
using SeaHaven.Services.DTOs;
using SeaHaven.Services.Interfaces;
using SeaHaven.Services.Validation;
namespace SeaHaven.Services.Implementation
{
///
/// Employee service implementation
/// Contains business logic, validation, and orchestration for Employee operations
///
public class EmployeeService : IEmployeeService
{
private readonly IEmployeeDataService _employeeDataService;
private readonly ICreateEmployeeValidation _createValidator;
private readonly IUpdateEmployeeValidation _updateValidator;
public EmployeeService(
IEmployeeDataService employeeDataService,
ICreateEmployeeValidation createValidator,
IUpdateEmployeeValidation updateValidator)
{
_employeeDataService = employeeDataService;
_createValidator = createValidator;
_updateValidator = updateValidator;
}
// Query operations
public async Task GetEmployeeByIdAsync(int id)
{
var employee = await _employeeDataService.GetByIdAsync(id);
return employee == null ? null : MapToDTO(employee);
}
public async Task GetEmployeeByIdWithDetailsAsync(int id)
{
var employee = await _employeeDataService.GetByIdWithDetailsAsync(id);
return employee == null ? null : MapToDTO(employee);
}
public async Task> GetAllEmployeesAsync()
{
var employees = await _employeeDataService.GetAllAsync();
return employees.Select(MapToDTO);
}
public async Task> GetEmployeesPagedAsync(int page, int pageSize, string? search = null)
{
var (items, totalCount) = await _employeeDataService.GetPagedAsync(page, pageSize, search);
return new PagedResult
{
Items = items.Select(MapToDTO).ToList(),
TotalCount = totalCount,
Page = page,
PageSize = pageSize
};
}
public async Task CreateEmployeeAsync(CreateEmployeeDTO dto, string userId)
{
var validationResult = await _createValidator.ValidateAsync(dto);
if (!validationResult.IsValid)
{
throw new ValidationException(validationResult.Errors);
}
var employee = new Employee
{
FirstName = dto.FirstName,
LastName = dto.LastName,
DepartmentId = dto.DepartmentId,
JobTitleId = dto.JobTitleId,
RegionId = dto.RegionId,
CreatedDate = DateTime.UtcNow,
CreatedBy = userId
};
if (!string.IsNullOrWhiteSpace(dto.Email))
{
employee.Emails.Add(new EmployeeEmail
{
Address = dto.Email,
IsPrimary = true
});
}
if (!string.IsNullOrWhiteSpace(dto.Phone))
{
employee.Phones.Add(new EmployeePhone
{
Number = dto.Phone,
IsPrimary = true
});
}
var created = await _employeeDataService.AddAsync(employee);
return MapToDTO(created);
}
public async Task UpdateEmployeeAsync(int id, UpdateEmployeeDTO dto, string userId)
{
var validationResult = await _updateValidator.ValidateAsync(dto);
if (!validationResult.IsValid)
{
throw new ValidationException(validationResult.Errors);
}
var employee = await _employeeDataService.GetByIdAsync(id);
if (employee == null)
throw new InvalidOperationException($"Employee with ID {id} not found");
if (dto.FirstName != null) employee.FirstName = dto.FirstName;
if (dto.LastName != null) employee.LastName = dto.LastName;
if (dto.DepartmentId.HasValue) employee.DepartmentId = dto.DepartmentId;
if (dto.JobTitleId.HasValue) employee.JobTitleId = dto.JobTitleId;
if (dto.RegionId.HasValue) employee.RegionId = dto.RegionId;
employee.LastModificationTime = DateTime.UtcNow;
employee.LastModifierUserId = int.Parse(userId);
await _employeeDataService.UpdateAsync(employee);
return MapToDTO(employee);
}
public async Task DeleteEmployeeAsync(int id, string userId)
{
var employee = await _employeeDataService.GetByIdAsync(id);
if (employee == null)
throw new InvalidOperationException($"Employee with ID {id} not found");
employee.IsDeleted = true;
employee.CreatedBy = userId;
employee.LastModificationTime = DateTime.UtcNow;
await _employeeDataService.UpdateAsync(employee);
}
public async Task EmployeeExistsAsync(int id)
{
return await _employeeDataService.ExistsAsync(id);
}
public async Task GetTotalEmployeeCountAsync()
{
return await _employeeDataService.CountAsync();
}
// Private helper methods
private EmployeeDTO MapToDTO(Employee employee)
{
return new EmployeeDTO
{
Id = employee.Id,
FirstName = employee.FirstName,
LastName = employee.LastName,
Email = employee.Emails?.FirstOrDefault(e => e.IsPrimary == true)?.Address,
Phone = employee.Phones?.FirstOrDefault(p => p.IsPrimary == true)?.Number,
DepartmentId = employee.DepartmentId,
DepartmentName = employee.Department?.Name,
JobTitleId = employee.JobTitleId,
JobTitleName = employee.JobTitle?.Name,
RegionId = employee.RegionId,
RegionName = employee.Region?.Name,
CreatedDate = employee.CreatedDate
};
}
}
}