@page "/admin/tax-profiles" @using TaxBaik.Web.Services.AdminClients @using TaxBaik.Web.Components.Admin.Shared @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 ? "세무 프로필 수정" : "새 세무 프로필 추가") @if (isEditMode) { 새로 작성 } @foreach (var client in clients) { @GetClientDisplayName(client) } @if (isEditMode) { 삭제 } 저장 } @code { [CascadingParameter] private Task? AuthStateTask { get; set; } private List? profiles; private List clients = []; private Dictionary clientMap = new(); private List riskLevels = []; private MudForm? form; private bool isEditMode; private TaxProfile? selectedProfile; private TaxProfileForm profileForm = new(); protected override async Task OnInitializedAsync() { if (AuthStateTask != null) { var authState = await AuthStateTask; if (authState.User.Identity?.IsAuthenticated == true) { await LoadData(); PrepareCreate(); } } } 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 PrepareCreate() { selectedProfile = null; isEditMode = false; profileForm = new TaxProfileForm { ClientId = clients.FirstOrDefault()?.Id, TaxRiskLevel = "normal", NextFilingDueDate = DateTime.Today.AddMonths(1) }; } private void OnRowSelected(TaxProfile profile) { if (profile == null) return; selectedProfile = profile; isEditMode = true; profileForm = new TaxProfileForm { ClientId = profile.ClientId, BusinessType = profile.BusinessType ?? "", TaxRiskLevel = profile.TaxRiskLevel, NextFilingDueDate = profile.NextFilingDueDate, SpecialNotes = profile.SpecialNotes }; } private async Task SaveProfile() { if (form != null) { await form.Validate(); if (!form.IsValid) { Snackbar.Add("고객을 선택하세요.", Severity.Warning); return; } } try { if (isEditMode && selectedProfile != null) { await TaxProfileClient.UpdateAsync(selectedProfile.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); } } PrepareCreate(); 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); if (selectedProfile?.Id == id) { PrepareCreate(); } await LoadData(); } catch (Exception ex) { Snackbar.Add($"삭제 실패: {ex.Message}", Severity.Error); } } 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; } } }