namespace TaxBaik.Application.Services; using TaxBaik.Domain.Entities; using TaxBaik.Domain.Interfaces; public class CompanyService(ICompanyRepository repository) { public async Task CreateAsync(string companyCode, string companyName, string? contactPerson = null, string? phone = null, string? email = null, string? memo = null, CancellationToken ct = default) { if (string.IsNullOrWhiteSpace(companyCode)) throw new ValidationException("회사 코드를 입력하세요."); if (string.IsNullOrWhiteSpace(companyName)) throw new ValidationException("회사명을 입력하세요."); var existing = await repository.GetByCodeAsync(companyCode.Trim(), ct); if (existing != null) throw new ValidationException("이미 존재하는 회사 코드입니다."); var company = new Company { CompanyCode = companyCode.Trim(), CompanyName = companyName.Trim(), ContactPerson = string.IsNullOrWhiteSpace(contactPerson) ? null : contactPerson.Trim(), Phone = string.IsNullOrWhiteSpace(phone) ? null : phone.Trim(), Email = string.IsNullOrWhiteSpace(email) ? null : email.Trim(), Memo = string.IsNullOrWhiteSpace(memo) ? null : memo.Trim(), IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; return await repository.CreateAsync(company, ct); } public async Task GetByIdAsync(int id, CancellationToken ct = default) => await repository.GetByIdAsync(id, ct); public async Task GetByCodeAsync(string code, CancellationToken ct = default) => await repository.GetByCodeAsync(code, ct); public async Task> GetAllActiveAsync(CancellationToken ct = default) => await repository.GetAllActiveAsync(ct); public async Task<(IEnumerable, int)> GetPagedAsync(int page, int pageSize, CancellationToken ct = default) { var (items, total) = await repository.GetPagedAsync(NormalizePage(page), NormalizePageSize(pageSize), ct); return (items, total); } public async Task UpdateAsync(int id, string companyCode, string companyName, string? contactPerson = null, string? phone = null, string? email = null, string? memo = null, bool isActive = true, CancellationToken ct = default) { if (string.IsNullOrWhiteSpace(companyCode)) throw new ValidationException("회사 코드를 입력하세요."); if (string.IsNullOrWhiteSpace(companyName)) throw new ValidationException("회사명을 입력하세요."); var company = await repository.GetByIdAsync(id, ct); if (company == null) throw new ValidationException("회사를 찾을 수 없습니다."); var existing = await repository.GetByCodeAsync(companyCode.Trim(), ct); if (existing != null && existing.Id != id) throw new ValidationException("이미 존재하는 회사 코드입니다."); company.CompanyCode = companyCode.Trim(); company.CompanyName = companyName.Trim(); company.ContactPerson = string.IsNullOrWhiteSpace(contactPerson) ? null : contactPerson.Trim(); company.Phone = string.IsNullOrWhiteSpace(phone) ? null : phone.Trim(); company.Email = string.IsNullOrWhiteSpace(email) ? null : email.Trim(); company.Memo = string.IsNullOrWhiteSpace(memo) ? null : memo.Trim(); company.IsActive = isActive; company.UpdatedAt = DateTime.UtcNow; await repository.UpdateAsync(company, ct); } public async Task DeleteAsync(int id, CancellationToken ct = default) { var company = await repository.GetByIdAsync(id, ct); if (company == null) throw new ValidationException("회사를 찾을 수 없습니다."); if (company.CompanyCode == "DEFAULT") throw new ValidationException("기본 회사는 삭제할 수 없습니다."); await repository.DeleteAsync(id, ct); } private static int NormalizePage(int page) => Math.Max(1, page); private static int NormalizePageSize(int pageSize) => Math.Clamp(pageSize, 1, 100); }