namespace TaxBaik.Application.Services; using TaxBaik.Domain.Entities; using TaxBaik.Domain.Interfaces; public class ContractService(IContractRepository repository) { public async Task CreateAsync(int clientId, string contractNumber, string serviceType, DateTime startDate, decimal? monthlyFee = null, decimal? totalAmount = null, CancellationToken ct = default) { if (clientId <= 0) throw new ValidationException("유효한 고객을 선택하세요."); if (string.IsNullOrWhiteSpace(contractNumber)) throw new ValidationException("계약 번호를 입력하세요."); if (string.IsNullOrWhiteSpace(serviceType)) throw new ValidationException("서비스 유형을 입력하세요."); var contract = new Contract { ClientId = clientId, ContractNumber = contractNumber.Trim(), ServiceType = serviceType.Trim(), ContractDate = DateTime.Today, StartDate = startDate, MonthlyFee = monthlyFee, TotalAmount = totalAmount, Status = "active", PaymentStatus = "pending", CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; return await repository.CreateAsync(contract, ct); } public async Task GetByIdAsync(int id, CancellationToken ct = default) => await repository.GetByIdAsync(id, ct); public async Task> GetByClientIdAsync(int clientId, CancellationToken ct = default) => await repository.GetByClientIdAsync(clientId, ct); public async Task> GetActiveContractsAsync(CancellationToken ct = default) => await repository.GetActiveContractsAsync(ct); public async Task> GetExpiringContractsAsync(int daysAhead = 30, CancellationToken ct = default) => await repository.GetExpiringContractsAsync(daysAhead, ct); public async Task GetMonthlyRecurringRevenueAsync(CancellationToken ct = default) => await repository.GetMonthlyRecurringRevenueAsync(ct); }