@page "/admin/contracts" @using TaxBaik.Web.Services.AdminClients @inject IContractBrowserClient ContractClient @inject IClientBrowserClient ClientClient @inject ISnackbar Snackbar @inject IDialogService DialogService @attribute [Authorize] 계약 관리 CRM & 세무관리 계약 관리 고객 계약과 월 정기수익을 함께 관리합니다. @if (mrr > 0) { 월 정기수익: ₩@mrr.ToString("N0") } 새 계약 추가 @if (contracts is null) { } else if (contracts.Count == 0) { 계약이 없습니다. } else { @if (clientMap.TryGetValue(context.Item.ClientId, out var clientName)) { @clientName } @context.Item.StartDate.ToString("yyyy-MM-dd") @if (context.Item.EndDate.HasValue) { ~@context.Item.EndDate.Value.ToString("yyyy-MM-dd") } @{ var isActive = !context.Item.EndDate.HasValue || context.Item.EndDate.Value >= DateTime.Today; } @if (isActive) { 활성 } else { 만료 } } 새 계약 추가 @foreach (var client in clients) { @client.CompanyName } 취소 저장 @code { private List? contracts; private List clients = []; private Dictionary clientMap = new(); private decimal mrr = 0; private MudForm? form; private bool isDialogOpen; private ContractForm contractForm = new(); protected override async Task OnInitializedAsync() { await LoadData(); } private async Task LoadData() { try { contracts = await ContractClient.GetAllAsync(); var (clientItems, _) = await ClientClient.GetPagedAsync(); clients = clientItems.ToList(); clientMap = clients.ToDictionary(c => c.Id, c => c.CompanyName ?? ""); mrr = await ContractClient.GetMonthlyRecurringRevenueAsync(); } catch (Exception ex) { Snackbar.Add($"데이터 로드 실패: {ex.Message}", Severity.Error); } } private void OpenCreateDialog() { contractForm = new(); isDialogOpen = true; } private async Task SaveContract() { try { var newId = await ContractClient.CreateAsync( contractForm.ClientId, contractForm.ContractNumber, contractForm.ServiceType, contractForm.StartDate ?? DateTime.Now, contractForm.MonthlyFee); if (newId > 0) { Snackbar.Add("계약이 추가되었습니다.", Severity.Success); CloseDialog(); await LoadData(); } } catch (Exception ex) { Snackbar.Add($"저장 실패: {ex.Message}", Severity.Error); } } private async Task DeleteContract(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 ContractClient.DeleteAsync(id); Snackbar.Add("계약이 삭제되었습니다.", Severity.Success); await LoadData(); } catch (Exception ex) { Snackbar.Add($"삭제 실패: {ex.Message}", Severity.Error); } } private void CloseDialog() { isDialogOpen = false; contractForm = new(); } private class ContractForm { public int ClientId { get; set; } public string ContractNumber { get; set; } = ""; public string ServiceType { get; set; } = ""; public DateTime? StartDate { get; set; } public decimal? MonthlyFee { get; set; } } }