@page "/admin/tax-profiles" @using TaxBaik.Web.Services.AdminClients @inject ITaxProfileBrowserClient TaxProfileClient @inject IClientBrowserClient ClientClient @inject ISnackbar Snackbar @inject IDialogService DialogService @attribute [Authorize] 세무 프로필
CRM & 세무관리 세무 프로필 고객별 세무 프로필, 신고 일정, 위험도 추적
새 프로필 추가
@if (profiles == null) { } else if (profiles.Count == 0) { 세무 프로필이 없습니다. } else { @if (clientMap.TryGetValue(context.Item.ClientId, out var clientName)) { @clientName } @context.Item.TaxRiskLevel @if (context.Item.NextFilingDueDate.HasValue) { @context.Item.NextFilingDueDate.Value.ToString("yyyy-MM-dd") } } @(isEditMode ? "세무 프로필 수정" : "새 세무 프로필 추가") @foreach (var client in clients) { @GetClientDisplayName(client) } 일반제조업 도소매업 서비스업 정보통신업 부동산업 건설업 음식점업 프리랜서 기타 낮음 보통 높음 취소 저장 @code { [CascadingParameter] private Task? AuthStateTask { get; set; } private List? profiles; private List clients = []; private Dictionary clientMap = new(); private MudForm? form; private bool isDialogOpen; private bool isEditMode; private TaxProfile? editingProfile; private TaxProfileForm profileForm = new(); protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { if (AuthStateTask != null) { var authState = await AuthStateTask; if (authState.User.Identity?.IsAuthenticated == true) { await LoadData(); StateHasChanged(); } } } } private async Task LoadData() { try { profiles = await TaxProfileClient.GetAllAsync(); var (clientItems, _) = await ClientClient.GetPagedAsync(pageSize: 1000); clients = clientItems.ToList(); clientMap = clients.ToDictionary(c => c.Id, GetClientDisplayName); } catch (Exception ex) { Snackbar.Add($"데이터 로드 실패: {ex.Message}", Severity.Error); } } private void OpenCreateDialog() { isEditMode = false; editingProfile = null; profileForm = new TaxProfileForm { ClientId = clients.FirstOrDefault()?.Id, TaxRiskLevel = "normal", NextFilingDueDate = DateTime.Today.AddMonths(1) }; isDialogOpen = true; } private async Task OpenEditDialog(TaxProfile profile) { isEditMode = true; editingProfile = profile; profileForm = new TaxProfileForm { ClientId = profile.ClientId, BusinessType = profile.BusinessType ?? "", TaxRiskLevel = profile.TaxRiskLevel, NextFilingDueDate = profile.NextFilingDueDate, SpecialNotes = profile.SpecialNotes }; isDialogOpen = true; } private async Task SaveProfile() { if (form != null) { await form.Validate(); if (!form.IsValid) { Snackbar.Add("고객을 선택하세요.", Severity.Warning); return; } } try { if (isEditMode && editingProfile != null) { await TaxProfileClient.UpdateAsync(editingProfile.Id, profileForm.BusinessType, null, profileForm.NextFilingDueDate, profileForm.TaxRiskLevel); Snackbar.Add("세무 프로필이 수정되었습니다.", Severity.Success); } else { if (!profileForm.ClientId.HasValue) { Snackbar.Add("고객을 선택하세요.", Severity.Warning); return; } var newId = await TaxProfileClient.CreateAsync( profileForm.ClientId.Value, profileForm.BusinessType); if (newId > 0) { // 생성 후 상태 업데이트 처리 await TaxProfileClient.UpdateAsync( newId, profileForm.BusinessType, null, profileForm.NextFilingDueDate, profileForm.TaxRiskLevel); Snackbar.Add("세무 프로필이 추가되었습니다.", Severity.Success); } } CloseDialog(); await LoadData(); } catch (Exception ex) { Snackbar.Add($"저장 실패: {ex.Message}", Severity.Error); } } private async Task DeleteProfile(int id) { var parameters = new DialogParameters(); parameters.Add("Title", "삭제 확인"); parameters.Add("Message", "이 세무 프로필을 삭제하시겠습니까?"); var dialog = await DialogService.ShowAsync("", parameters); var result = await dialog.Result; if (result?.Canceled ?? true) return; try { await TaxProfileClient.DeleteAsync(id); Snackbar.Add("세무 프로필이 삭제되었습니다.", Severity.Success); await LoadData(); } catch (Exception ex) { Snackbar.Add($"삭제 실패: {ex.Message}", Severity.Error); } } private void CloseDialog() { isDialogOpen = false; isEditMode = false; editingProfile = null; profileForm = new(); } private Color GetRiskColor(string riskLevel) => riskLevel switch { "high" => Color.Error, "normal" => Color.Warning, "low" => Color.Success, _ => Color.Default }; private static string GetClientDisplayName(Client client) => !string.IsNullOrWhiteSpace(client.CompanyName) ? client.CompanyName : !string.IsNullOrWhiteSpace(client.Name) ? client.Name : $"Client #{client.Id}"; private class TaxProfileForm { public int? ClientId { get; set; } public string BusinessType { get; set; } = ""; public string TaxRiskLevel { get; set; } = "normal"; public DateTime? NextFilingDueDate { get; set; } public string? SpecialNotes { get; set; } } }