79492184d0
- WBS-CRM-02: 상담 이력 (consultations 테이블 V008, ClientDetail.razor) - WBS-CRM-03: 문의→고객 전환 (V009 client_id FK, InquiryDetail 고객등록 버튼) - WBS-CRM-04: 신고 일정 캘린더 (tax_filings 테이블 V010, TaxFilingList.razor) - WBS-CRM-05: 문의 상태 5단계 확장 (V011, InquiryStatus enum, InquiryList 탭) - WBS-MKT-04: 시즌 시뮬레이터 어드민 페이지 (SeasonSimulator.razor) - WBS-UX-04: 개인정보처리방침 /taxbaik/privacy, 이용약관 /taxbaik/terms - Dashboard.razor 마감 임박 신고 위젯 추가 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
83 lines
3.1 KiB
C#
83 lines
3.1 KiB
C#
namespace TaxBaik.Application.Services;
|
|
|
|
using TaxBaik.Application.DTOs;
|
|
using TaxBaik.Domain.Entities;
|
|
using TaxBaik.Domain.Interfaces;
|
|
|
|
public class ClientService(IClientRepository repository)
|
|
{
|
|
public static readonly string[] ServiceTypes =
|
|
["기장", "부동산", "증여·상속", "종합소득세", "법인세", "부가가치세", "기타"];
|
|
|
|
public static readonly string[] TaxTypes =
|
|
["개인사업자", "법인사업자", "면세사업자", "근로소득자", "기타"];
|
|
|
|
public static readonly string[] Sources =
|
|
["홈페이지 문의", "소개", "직접 방문", "카카오 채널", "블로그", "기타"];
|
|
|
|
public async Task<(IEnumerable<Client> Items, int Total)> GetPagedAsync(
|
|
int page, int pageSize, string? status = null, string? search = null, CancellationToken ct = default) =>
|
|
await repository.GetPagedAsync(Math.Max(1, page), Math.Clamp(pageSize, 1, 100), status, search, ct);
|
|
|
|
public async Task<Client?> GetByIdAsync(int id, CancellationToken ct = default) =>
|
|
await repository.GetByIdAsync(id, ct);
|
|
|
|
public async Task<int> CreateAsync(CreateClientDto dto, CancellationToken ct = default)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(dto.Name))
|
|
throw new ValidationException("고객명을 입력하세요.");
|
|
|
|
var client = new Client
|
|
{
|
|
Name = dto.Name.Trim(),
|
|
CompanyName = dto.CompanyName?.Trim(),
|
|
Phone = dto.Phone?.Trim(),
|
|
Email = dto.Email?.Trim(),
|
|
ServiceType = dto.ServiceType,
|
|
TaxType = dto.TaxType,
|
|
Status = dto.Status,
|
|
Source = dto.Source,
|
|
Memo = dto.Memo?.Trim()
|
|
};
|
|
|
|
return await repository.CreateAsync(client, ct);
|
|
}
|
|
|
|
public async Task UpdateAsync(int id, CreateClientDto dto, CancellationToken ct = default)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(dto.Name))
|
|
throw new ValidationException("고객명을 입력하세요.");
|
|
|
|
var client = await repository.GetByIdAsync(id, ct)
|
|
?? throw new KeyNotFoundException($"고객 ID {id}를 찾을 수 없습니다.");
|
|
|
|
client.Name = dto.Name.Trim();
|
|
client.CompanyName = dto.CompanyName?.Trim();
|
|
client.Phone = dto.Phone?.Trim();
|
|
client.Email = dto.Email?.Trim();
|
|
client.ServiceType = dto.ServiceType;
|
|
client.TaxType = dto.TaxType;
|
|
client.Status = dto.Status;
|
|
client.Source = dto.Source;
|
|
client.Memo = dto.Memo?.Trim();
|
|
|
|
await repository.UpdateAsync(client, ct);
|
|
}
|
|
|
|
public async Task<int> CreateFromInquiryAsync(string name, string? phone, string? serviceType, CancellationToken ct = default)
|
|
{
|
|
var client = new Client
|
|
{
|
|
Name = name.Trim(),
|
|
Phone = phone?.Trim(),
|
|
ServiceType = serviceType,
|
|
Status = "active",
|
|
Source = "홈페이지 문의"
|
|
};
|
|
return await repository.CreateAsync(client, ct);
|
|
}
|
|
|
|
public async Task DeleteAsync(int id, CancellationToken ct = default) =>
|
|
await repository.DeleteAsync(id, ct);
|
|
}
|