004f99c2b4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
104 lines
3.2 KiB
C#
104 lines
3.2 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using MoneyMap.Models;
|
|
using MoneyMap.Services;
|
|
|
|
namespace MoneyMap.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
public class BudgetsController : ControllerBase
|
|
{
|
|
private readonly IBudgetService _budgetService;
|
|
|
|
public BudgetsController(IBudgetService budgetService) => _budgetService = budgetService;
|
|
|
|
[HttpGet("status")]
|
|
public async Task<IActionResult> GetStatus([FromQuery] string? asOfDate = null)
|
|
{
|
|
DateTime? date = null;
|
|
if (!string.IsNullOrWhiteSpace(asOfDate) && DateTime.TryParse(asOfDate, out var parsed))
|
|
date = parsed;
|
|
|
|
var statuses = await _budgetService.GetAllBudgetStatusesAsync(date);
|
|
|
|
var result = statuses.Select(s => new
|
|
{
|
|
s.Budget.Id,
|
|
Category = s.Budget.DisplayName,
|
|
s.Budget.Amount,
|
|
Period = s.Budget.Period.ToString(),
|
|
s.PeriodStart,
|
|
s.PeriodEnd,
|
|
s.Spent,
|
|
s.Remaining,
|
|
PercentUsed = Math.Round(s.PercentUsed, 1),
|
|
s.IsOverBudget
|
|
}).ToList();
|
|
|
|
return Ok(result);
|
|
}
|
|
|
|
[HttpPost]
|
|
public async Task<IActionResult> Create([FromBody] CreateBudgetRequest request)
|
|
{
|
|
if (!Enum.TryParse<BudgetPeriod>(request.Period, true, out var budgetPeriod))
|
|
return BadRequest(new { message = $"Invalid period '{request.Period}'. Must be Weekly, Monthly, or Yearly." });
|
|
|
|
if (!DateTime.TryParse(request.StartDate, out var startDate))
|
|
return BadRequest(new { message = "Invalid start date format" });
|
|
|
|
var budget = new Budget
|
|
{
|
|
Category = request.Category,
|
|
Amount = request.Amount,
|
|
Period = budgetPeriod,
|
|
StartDate = startDate,
|
|
IsActive = true
|
|
};
|
|
|
|
var result = await _budgetService.CreateBudgetAsync(budget);
|
|
|
|
return Ok(new { result.Success, result.Message, BudgetId = budget.Id });
|
|
}
|
|
|
|
[HttpPut("{id}")]
|
|
public async Task<IActionResult> Update(int id, [FromBody] UpdateBudgetRequest request)
|
|
{
|
|
var budget = await _budgetService.GetBudgetByIdAsync(id);
|
|
if (budget == null)
|
|
return NotFound(new { message = "Budget not found" });
|
|
|
|
if (request.Amount.HasValue)
|
|
budget.Amount = request.Amount.Value;
|
|
|
|
if (!string.IsNullOrWhiteSpace(request.Period))
|
|
{
|
|
if (!Enum.TryParse<BudgetPeriod>(request.Period, true, out var budgetPeriod))
|
|
return BadRequest(new { message = $"Invalid period '{request.Period}'. Must be Weekly, Monthly, or Yearly." });
|
|
budget.Period = budgetPeriod;
|
|
}
|
|
|
|
if (request.IsActive.HasValue)
|
|
budget.IsActive = request.IsActive.Value;
|
|
|
|
var result = await _budgetService.UpdateBudgetAsync(budget);
|
|
|
|
return Ok(new { result.Success, result.Message });
|
|
}
|
|
}
|
|
|
|
public class CreateBudgetRequest
|
|
{
|
|
public string? Category { get; set; }
|
|
public decimal Amount { get; set; }
|
|
public string Period { get; set; } = "";
|
|
public string StartDate { get; set; } = "";
|
|
}
|
|
|
|
public class UpdateBudgetRequest
|
|
{
|
|
public decimal? Amount { get; set; }
|
|
public string? Period { get; set; }
|
|
public bool? IsActive { get; set; }
|
|
}
|