@page "/admin/tax-filing-schedules" @using TaxBaik.Web.Services.AdminClients @using TaxBaik.Domain.Entities @using TaxBaik.Web.Components.Admin.Shared @inject ITaxFilingScheduleBrowserClient TaxFilingClient @inject IClientBrowserClient ClientClient @inject ISnackbar Snackbar @inject IDialogService DialogService @attribute [Authorize] 신고 일정
CRM & 세무관리 신고 일정 고객별 마감일과 처리 상태를 한 화면에서 관리합니다.
새 일정 추가
@if (schedules is null) { } else { @if (schedules.Count == 0) { 신고 일정이 없습니다. } else { @if (clientMap.TryGetValue(context.Item.ClientId, out var clientName)) { @clientName } @{ var effectiveDueDate = BusinessDayCalculator.GetEffectiveDueDate(DateOnly.FromDateTime(context.Item.DueDate)); var daysLeft = BusinessDayCalculator.GetDday(DateOnly.FromDateTime(context.Item.DueDate)); var statusColor = daysLeft < 0 ? Color.Error : daysLeft <= 7 ? Color.Warning : Color.Success; } @effectiveDueDate.ToDateTime(TimeOnly.MinValue).ToString("yyyy-MM-dd") @if (daysLeft >= 0) { (D-@daysLeft) } else { (마감 @Math.Abs(daysLeft)일 경과) } @if (context.Item.Status == "completed") { 완료 } else { 대기 } @if (context.Item.Status != "completed") { } }
@(isEditMode ? "신고 일정 상세" : "새 신고 일정 추가") @if (isEditMode) { 새로 작성 }
@foreach (var client in clients) { @GetClientDisplayName(client) }
@if (isEditMode && selectedSchedule?.Status != "completed") { 완료 처리 } @if (isEditMode) { 삭제 } else { 저장 }
} @code { [CascadingParameter] private Task? AuthStateTask { get; set; } private List? schedules; private List clients = []; private Dictionary clientMap = new(); private MudForm? form; private bool isEditMode; private TaxFilingSchedule? selectedSchedule; private TaxFilingScheduleForm scheduleForm = 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(); PrepareCreate(); StateHasChanged(); } } } } private async Task LoadData() { try { schedules = await TaxFilingClient.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() { selectedSchedule = null; isEditMode = false; scheduleForm = new TaxFilingScheduleForm { FilingYear = DateTime.Now.Year, DueDate = DateTime.Today, ClientId = clients.FirstOrDefault()?.Id, FilingType = string.Empty }; } private void OnRowSelected(TaxFilingSchedule schedule) { if (schedule == null) return; selectedSchedule = schedule; isEditMode = true; scheduleForm = new TaxFilingScheduleForm { ClientId = schedule.ClientId, FilingType = schedule.FilingType, DueDate = schedule.DueDate, FilingYear = schedule.FilingYear }; } private async Task SaveSchedule() { if (form != null) { await form.Validate(); if (!form.IsValid) { Snackbar.Add("필수 항목을 입력해주세요.", Severity.Warning); return; } } try { if (scheduleForm.ClientId == null) return; var newId = await TaxFilingClient.CreateAsync( scheduleForm.ClientId.Value, scheduleForm.FilingType, scheduleForm.DueDate ?? DateTime.Today, scheduleForm.FilingYear); if (newId > 0) { Snackbar.Add("신고 일정이 추가되었습니다.", Severity.Success); PrepareCreate(); await LoadData(); } else { Snackbar.Add("등록에 실패했습니다.", Severity.Error); } } catch (Exception ex) { Snackbar.Add($"저장 실패: {ex.Message}", Severity.Error); } } private async Task CompleteSchedule(int id) { try { await TaxFilingClient.MarkCompletedAsync(id); Snackbar.Add("신고 일정이 완료 처리되었습니다.", Severity.Success); if (selectedSchedule?.Id == id) { PrepareCreate(); } await LoadData(); } catch (Exception ex) { Snackbar.Add($"처리 실패: {ex.Message}", Severity.Error); } } private async Task DeleteSchedule(int id) { var parameters = new DialogParameters { { "Title", "삭제 확인" }, { "Message", "이 신고 일정을 삭제하시겠습니까?" } }; var dialog = await DialogService.ShowAsync("", parameters); var result = await dialog.Result; if (result?.Canceled ?? true) return; try { await TaxFilingClient.DeleteAsync(id); Snackbar.Add("신고 일정이 삭제되었습니다.", Severity.Success); if (selectedSchedule?.Id == id) { PrepareCreate(); } await LoadData(); } catch (Exception ex) { Snackbar.Add($"삭제 실패: {ex.Message}", Severity.Error); } } private static string GetClientDisplayName(Client client) => !string.IsNullOrWhiteSpace(client.CompanyName) ? client.CompanyName : !string.IsNullOrWhiteSpace(client.Name) ? client.Name : $"Client #{client.Id}"; private class TaxFilingScheduleForm { public int? ClientId { get; set; } public string FilingType { get; set; } = ""; public DateTime? DueDate { get; set; } public int FilingYear { get; set; } = DateTime.Now.Year; } }