KoogleApp/src/Koogle.Application/Services/BookingCategoryService.cs

138 lines
4.9 KiB
C#

using AutoMapper;
using Koogle.Application.DTOs;
using Koogle.Application.Interfaces;
using Koogle.Domain.Entities;
using Koogle.Domain.Enums;
using Koogle.Domain.Interfaces;
namespace Koogle.Application.Services;
/// <summary>
/// Service for managing booking category operations within the current club context.
/// </summary>
public class BookingCategoryService : IBookingCategoryService
{
private readonly IBookingCategoryRepository _repository;
private readonly ICurrentClubContext _clubContext;
private readonly IMapper _mapper;
/// <summary>
/// Initializes a new instance of the <see cref="BookingCategoryService"/> class.
/// </summary>
public BookingCategoryService(
IBookingCategoryRepository repository,
ICurrentClubContext clubContext,
IMapper mapper)
{
_repository = repository;
_clubContext = clubContext;
_mapper = mapper;
}
/// <inheritdoc />
public async Task<List<BookingCategoryDto>> GetAllAsync(bool includeInactive = false, CancellationToken ct = default)
{
var categories = await _repository.GetByClubIdAsync(_clubContext.ClubId, includeInactive, ct);
return _mapper.Map<List<BookingCategoryDto>>(categories);
}
/// <inheritdoc />
public async Task<BookingCategoryDto?> GetByIdAsync(Guid id, CancellationToken ct = default)
{
var category = await _repository.GetByIdAsync(id, ct);
if (category is null || category.ClubId != _clubContext.ClubId)
return null;
return _mapper.Map<BookingCategoryDto>(category);
}
/// <inheritdoc />
public async Task<BookingCategoryDto> CreateAsync(CreateBookingCategoryDto dto, CancellationToken ct = default)
{
var entity = new BookingCategory
{
Id = Guid.NewGuid(),
ClubId = _clubContext.ClubId,
Name = dto.Name,
Description = dto.Description,
CategoryType = dto.CategoryType,
IsSystemCategory = false,
Color = dto.Color,
Icon = dto.Icon,
IsActive = true,
CreatedAt = DateTime.UtcNow
};
var created = await _repository.AddAsync(entity, ct);
return _mapper.Map<BookingCategoryDto>(created);
}
/// <inheritdoc />
public async Task<BookingCategoryDto> UpdateAsync(UpdateBookingCategoryDto dto, CancellationToken ct = default)
{
var existing = await _repository.GetByIdAsync(dto.Id, ct)
?? throw new InvalidOperationException($"Category with id {dto.Id} not found.");
if (existing.ClubId != _clubContext.ClubId)
throw new InvalidOperationException("Category does not belong to current club.");
existing.Name = dto.Name;
existing.Description = dto.Description;
existing.Color = dto.Color;
existing.Icon = dto.Icon;
existing.IsActive = dto.IsActive;
existing.ModifiedAt = DateTime.UtcNow;
var updated = await _repository.UpdateAsync(existing, ct);
return _mapper.Map<BookingCategoryDto>(updated);
}
/// <inheritdoc />
public async Task<bool> DeleteAsync(Guid id, CancellationToken ct = default)
{
var existing = await _repository.GetByIdAsync(id, ct);
if (existing is null || existing.ClubId != _clubContext.ClubId)
return false;
if (existing.IsSystemCategory)
throw new InvalidOperationException("System categories cannot be deleted.");
existing.IsDeleted = true;
existing.ModifiedAt = DateTime.UtcNow;
await _repository.UpdateAsync(existing, ct);
return true;
}
/// <inheritdoc />
public async Task EnsureSystemCategoriesAsync(CancellationToken ct = default)
{
var systemCategories = new[]
{
new { Name = "Spielstrafe", Type = BookingCategoryType.Income, Color = "#4CAF50", Icon = "Gavel" },
new { Name = "Mitgliedsbeitrag", Type = BookingCategoryType.Income, Color = "#2196F3", Icon = "CardMembership" },
new { Name = "Korrekturbuchung", Type = BookingCategoryType.Income, Color = "#FF9800", Icon = "Build" },
new { Name = "Saldoanpassung", Type = BookingCategoryType.Income, Color = "#9E9E9E", Icon = "Balance" }
};
foreach (var cat in systemCategories)
{
var existing = await _repository.GetSystemCategoryAsync(_clubContext.ClubId, cat.Name, ct);
if (existing is null)
{
await _repository.AddAsync(new BookingCategory
{
Id = Guid.NewGuid(),
ClubId = _clubContext.ClubId,
Name = cat.Name,
CategoryType = cat.Type,
IsSystemCategory = true,
Color = cat.Color,
Icon = cat.Icon,
IsActive = true,
CreatedAt = DateTime.UtcNow
}, ct);
}
}
}
}